Quantcast
Channel: xda-developers - Android Software and Hacking General [Developers Only]
Viewing all articles
Browse latest Browse all 3614

[GUIDE] How to port Bluez to Android 4.4!

$
0
0
Introduction
When the bluetooth stack changed to Bluedroid in Android 4.2, it was a nightmare to some of the old devices like my GT-P6800. I didn't have any experience in Bluetooth before so I did what I know. I spent weeks to revert the 4.2 platform to Bluez. Even though I succeeded, it probably not doable for 4.3 and later.
Last Nov. bluez.org announced support for Andriod. It gave us hope again! The principle is straight forward - Implement the functions defined in "hardware/libhardware/include/hardware/bluetooth.h". That's what I thought but I didn't have enough knowledge nor confidence to try...:o
After studying for a while, I started porting bluez to Android 4.4 last Christmas. It was frustrated and helpless. Although the lastest Android 4.4 example for Mako and Flo are out, they don't help much. A bunch of prebuilt kernel objects surely doesn't help! Porting for those devices already having bluedroid support is meaningless to most of us too... :(
Building the bluez hal and daemon are straight forward but how to make it really work is another story. After a few painful and frustrated weekends, I finally managed to pull everything together. I can start/stop and pairing bluetooth devices in the platform now. And here I'm, sharing my experiences. I think there might be better way and I welcome any corrections.
My p6800 has CSR bluetooth chip which has no bluedroid support. I think the same approach would work for other chips too. Cheers! :highfive:

** All paths assume your rom source dircetory to be the current directory **

1. Downlaod and Build
Bluez.org already has its own tutorial. I just summerize and list my suggestions.

1.1 local manifest
I learned my lesson and would avoid touching the "manifest.xml".
Add the following lines to your ".repo/local_manifests/local_menifest.xml"
Code:

  <remote name="gcode" fetch="https://code.google.com/p/"/>
  <remote name="korg" fetch="git://git.kernel.org/pub/scm/bluetooth/"/>
  <remove-project name="android_external_bluetooth_bluedroid"/>
  <project remote="korg" path="external/bluetooth/bluez" name="bluez" group="pdk" revision="master"/>
  <project remote="korg" path="external/bluetooth/sbc" name="sbc" group="pdk" revision="master"/>
  <project remote="gcode" path="external/bluetooth/glib" name="aosp-bluez.glib" group="pdk" revision="master"/>

After repo sync, bluez will replace bluedroid.

1.2 patching bionic
The patches for bionic are simple. Mainly by adding two flags and the function epoll_create1().
Bionic may vary from ROMs. It is wiser to patch the bionic of your ROM manually. You may follow the changes of the two commits below:
https://code.google.com/p/aosp-bluez...latform-bionic
https://code.google.com/p/aosp-bluez...latform-bionic

1.3 neccessary tools
There are tools in "external/bluetooth/bluez/tools". You may need some of those tools for setup or testing.
This is the "Android.mk" I added to "external/bluetooth/bluez/tools". You may cheery pick the required tools for your device.
Code:

#
# Bluetooth tools for setup and debug
#                        daniel_hk
LOCAL_PATH := external/bluetooth

# Retrieve BlueZ version from configure.ac file
BLUEZ_VERSION := $(shell grep ^AC_INIT $(LOCAL_PATH)/bluez/configure.ac | cpp -P -D'AC_INIT(_,v)=v')

# Specify pathmap for glib
#pathmap_INCL += glib:external/bluetooth/glib

# Specify common compiler flags
BLUEZ_COMMON_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\" \
        -DSTORAGEDIR=$(ANDROID_STORAGEDIR) \

# Disable warnings enabled by Android but not enabled in autotools build
BLUEZ_COMMON_CFLAGS += -Wno-pointer-arith -Wno-missing-field-initializers

# @ daniel, extra tools for CSR
# hciconfig
#
ifneq ($(BOARD_HAVE_BLUETOOTH_CUSTOM_HCITOOL), true)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
        bluez/lib/hci.c \
        bluez/lib/bluetooth.c \
        bluez/tools/csr.c \
        bluez/tools/csr_h4.c \
        bluez/tools/hciconfig.c

LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)

LOCAL_C_INCLUDES:=\
        $(LOCAL_PATH)/bluez \
        $(LOCAL_PATH)/bluez/tools \
        $(LOCAL_PATH)/bluez/lib \
        $(LOCAL_PATH)/bluez/src \
        $(LOCAL_PATH)/bluez/src/shared \

LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:=hciconfig

include $(BUILD_EXECUTABLE)

#
# hcitool
#
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
        bluez/lib/hci.c \
        bluez/lib/bluetooth.c \
        bluez/tools/hcitool.c \
        bluez/src/oui.c

LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)

LOCAL_C_INCLUDES:=\
        $(LOCAL_PATH)/bluez \
        $(LOCAL_PATH)/bluez/lib \
        $(LOCAL_PATH)/bluez/src \
        $(LOCAL_PATH)/bluez/src/shared \

LOCAL_C_INCLUDES += \
        $(call include-path-for, glib) \
        $(call include-path-for, glib)/glib \

LOCAL_SHARED_LIBRARIES := \
        libglib \

LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:=hcitool

include $(BUILD_EXECUTABLE)

#
# hciattach
#
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
        bluez/lib/hci.c \
        bluez/lib/bluetooth.c \
        bluez/tools/hciattach.c \
        bluez/tools/hciattach_ath3k.c \
        bluez/tools/hciattach_intel.c \
        bluez/tools/hciattach_qualcomm.c \
        bluez/tools/hciattach_st.c \
        bluez/tools/hciattach_ti.c \
        bluez/tools/hciattach_tialt.c \

LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
LOCAL_CFLAGS += \
        -D__BSD_VISIBLE=1 \
        -DCONFIGDIR=\"/etc/bluetooth\" \
        -DNEED_PPOLL

LOCAL_C_INCLUDES:=\
        $(LOCAL_PATH)/bluez \
        $(LOCAL_PATH)/bluez/lib \
        $(LOCAL_PATH)/bluez/tools \
        $(LOCAL_PATH)/bluez/src \
        $(LOCAL_PATH)/bluez/src/shared \

LOCAL_MODULE:=hciattach

include $(BUILD_EXECUTABLE)
endif

ifeq ($(BOARD_HAVE_BLUETOOTH_CSR),true)

#
# bccmd
#
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
        bluez/lib/hci.c \
        bluez/lib/bluetooth.c \
        bluez/tools/bccmd.c \
        bluez/tools/csr.c \
        bluez/tools/csr_3wire.c \
        bluez/tools/csr_bcsp.c \
        bluez/tools/csr_hci.c \
        bluez/tools/csr_h4.c \
        bluez/tools/csr_usb.c \
        bluez/tools/ubcsp.c

LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)

LOCAL_C_INCLUDES:=\
        $(LOCAL_PATH)/bluez \
        $(LOCAL_PATH)/bluez/lib \
        $(LOCAL_PATH)/bluez/tools \
        $(LOCAL_PATH)/bluez/src \
        $(LOCAL_PATH)/bluez/src/shared \

LOCAL_MODULE:=bccmd

include $(BUILD_EXECUTABLE)

#
# sdptool
#
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
        bluez/lib/hci.c \
        bluez/lib/bluetooth.c \
        bluez/tools/sdptool.c \
        bluez/src/sdp-xml.c

LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)

LOCAL_C_INCLUDES:=\
        $(LOCAL_PATH)/bluez \
        $(LOCAL_PATH)/bluez/lib \
        $(LOCAL_PATH)/bluez/tools \
        $(LOCAL_PATH)/bluez/src \
        $(LOCAL_PATH)/bluez/src/shared \

LOCAL_C_INCLUDES += \
        $(call include-path-for, glib) \
        $(call include-path-for, glib)/glib \

LOCAL_SHARED_LIBRARIES := \
        libglib \

LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:=sdptool

include $(BUILD_EXECUTABLE)
endif

1.4 patches for CyanogenMod 11
In CyanogenMod 11, the function "pin_request_cb" has one more argument. The following file need some patches:
in the file "external/bluetooth/bluez/android/hal-bluetooth.c"
Code:

** in function: handle_pin_request
        bt_hal_cbacks->pin_request_cb(addr, name, ev->class_of_dev, 0);        // @ daniel, added 0 for cm11

** in function: pin_request_cb
static void pin_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
                                                uint32_t cod, uint8_t secure)        // @ daniel, added secure from cm11
{
        /* Store for command completion */
        bt_bdaddr_t2str(remote_bd_addr, last_remote_addr);
        pin_request_addr = *remote_bd_addr;

        haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x secure=%02x\n", __func__,
                                        last_remote_addr, bd_name->name, cod, secure);        // @ daniel, added
        terminal_prompt_for("Enter pin: ", pin_request_answer);
}

2. kerenl patch
In the "README" inside "external/bluetooth/bluez/android", there is the line:
Quote:

Minimal required version of management interface is 1.3. This corresponds to Linux 3.9 but latest available version is recommended.
If you have tried porting bluez and fail, check the logcat. You might probably found the error "Failed to access management interface". This is the key making bluez to work! Sadly, most of the existing Android kernels are before ver. 3.9! The latest kernel we have might be ver. 3.4.x and the kernel for my p6800 is ver. 3.0.x! As the above line stated, Bluez5 requires the kernel to have management interface 1.3 or above. That means we have to backport the bluetooth subsystem from at least ver. 3.9. I backport my kernel with the latest (3.13-1) found in linux-foundation.org: http://drvbp1.linux-foundation.org/~...tml/backports/
It was a tough and painful job! There are lots of changes. I finally got a bootable backport kernel in 2 days!
I packed my patches in Attachment 2566338. This patch is for my 3.0.x kernel which might be different from other 3.0.x kernels. Don't have time to tidy up but it works for me. Although I've done the hard part:eek:, it still requires extra patience to get yours done. Prepare yourself...

2.1 Backport 3.13-1 to your kernel
  • Direct replacements.
    Replace the following folders in the zip with the one in your kernel source:
    drivers/bluetooth
    net/bluetooth
    include/net/bluetooth
  • Direct replacement might not work!
    Check include/linux in the zip
    For each file,
    add the required part (which I delimited with comments @ daniel and //@ ) to the corresponding file in your kernel source.
    If file not exist,
    copy the files to your kernel source
  • Check your defconfig. As README suggested, defconfig should have:
    CONFIG_BT
    CONFIG_BT_RFCOMM
    CONFIG_BT_RFCOMM_TTY
    CONFIG_BT_BNEP
    CONFIG_BT_BNEP_MC_FILTER
    CONFIG_BT_BNEP_PROTO_FILTER
    CONFIG_BRIDGE
    CONFIG_UHID
    # and for CSR chips
    CONFIG_BT_HCIUART=y
    CONFIG_BT_HCIUART_H4=y
    CONFIG_BT_HCIUART_BCSP=y
You probably need to compile the kernel many times to get it work. I worte a build script Attachment 2566366 to compile the kernel only.
Copy build-k to your ROM source directory and type:
Code:

./build-k <your device>
2.2 Backport-hid-generic to your kernel
There is another patch in the Mako-kern example:
https://code.google.com/p/aosp-bluez...-lge-mako-kern
Don't know if it is required for your kernel but adding this patch seems doesn't hurt.

If you do it right, you may find "Bluetooth management interface 1.4" in your logcat. Congratulation! Bluetoothd can connect to your kernel now!

3. initialization and setup
Take a look at your devices tree's TARGET_CUSTOM_BLUEDROID definition. If you have a file assigned, it supposed to replace the file "bluetooth.c" in the "system/bluetooth" project. In Android 4.4, this project is no longer exist/needed. Before Android 4.2, this project provide the functions "bt_enable()" and "bt_disable()" which are called in the frameworks. These functions will tell you how to "power on", "power off" and init your device's Bluetooth chip.
For CSR:
  • set /sys/class/rfkill/rfkill0/state to 1 ("power on")
  • start the service "bccmd" which will setup the chip and upload a PSConfig to the chip
  • start the service "hciattach" which init the port hci0 with parameters
  • start the service "bluetoothd" which is the bluez stack
The services are defined in init.rc or init.${ro.hardware}.rc.

3.1 Test your device and the tools
Disable the "import init.bluetooth.rc" line if you have added it before.
Example for CSR chips. Follow the steps in bt_enable. In a terminal or via adb:
Code:

$ su                                -- root user is required
# echo "1" > /sys/class/rfkill/rfkill0/state
# bccmd -t bcsp -d /dev/ttySAC0 -b 115200 psload -r /system/etc/PSConfig_8811.psr
  Loading 0x212c ... done
  Loading 0x212d ... done
        ...
  Loading PSKEY_CLOCK_REQUEST_ENABLE ... done
  Loading PSKEY_UART_HOST_WAKE ... done
# hciattach -p /dev/ttySAC0 bcsp 3000000 flow
  Device setup complete
# hciconfig hci0 up
# hcitool scan                        -- turn on a device's bluetooth for testing
        Nexus 4                        -- found the device means bluetooth is working now

3.2 Init sequence
In Bluez5, the HAL (bluetooth.default.so) driver will be loaded at boot and the daemon (bluetoothd) will be started inside too. Take a look at the function "bool hal_ipc_init(void)" in "external/bluetooth/bluez/android/hal-ipc.c". You may find how the HAL is init which is different from pre-4.2 Androids.
In order to get the daemon (bluetoothd) to work, we have to init the chip before that.
I worte a shell script init.bt.sh to init the chip/port:
Code:

#!/system/bin/sh
# modified by daniel_hk

LOG_TAG="CSR8811-HCI"
BTUART_PORT=/dev/ttySAC0
BTSTATE=/sys/class/rfkill/rfkill0/state
PSCONFIG=/system/etc/PSConfig_8811.psr

logi ()
{
  /system/bin/log -t $LOG_TAG -p i ": $@"
}

loge ()
{
  /system/bin/log -t $LOG_TAG -p e ": $@"
}

failed ()
{
  loge "$1: exit code $2"
  exit $2
}

#Enable power of csr chip
echo "1" > $BTSTATE

# PS Config with bccmd
logwrapper /system/bin/bccmd -t bcsp -d $BTUART_PORT -b 115200 psload -r $PSCONFIG
case $? in
  0) logi "bccmd init port....done";;
  *) failed "port: $BTUART_PORT - bccmd failed" $?;
    exit $?;;
esac

# attach HCI
logwrapper /system/bin/hciattach -p $BTUART_PORT bcsp 3000000 flow
case $? in
  0) logi "hci attached to : $BTUART_PORT";;
  *) failed "port: $BTUART_PORT - hciattach failed" $?;
    exit $?;;
esac

exit 0

It takes time for bccmd and hciattach to complete. Putting them in seperate services requires delay in between. I think it is better to run them as application one after one.

A new rc file init.${ro.hardware}.bt.rc is created and need to be imported in your init.${ro.hardware}.rc
Code:

on boot
    start bt_init

on property:init.svc.bluetoothd=running
    start hci0_up

on property:init.svc.bluetoothd=stopped
    start hci0_down

service bt_init /system/bin/logwrapper /system/bin/sh /system/etc/init.bt.sh
    class main
    user root
    group bluetooth net_bt_admin system
    disabled
    oneshot

service hci0_up /system/bin/logwrapper /system/xbin/hciconfig hci0 up
    class main
    group bluetooth
    disabled
    oneshot

service hci0_down /system/bin/logwrapper /system/xbin/hciconfig hci0 down
    class main
    group bluetooth net_bt_admin system
    disabled
    oneshot

import init.bluetooth.rc

Since HAL (bluetooth.default.so) is started quite early, I start the service bt_init at boot. I have tried a few places, daemon might timed out before bt_init finish. It also seems no need to repeat the init process everytime.
When bluetoothd is running (system/core/init will set the property init.svc.bluetoothd=running), set hci0 up with hciconfig. And when the service bluetoothd is stopped, set hci0 down with hciconfig. There might be a better way. Please indulge me if something better coming up.

You may turn ON/OFF bluetooth in settings now. Pairing and file transfer is working too.

4. Further porting
Take a look at the function get_profile_interface() in the file external/bluetooth/bluez/android/hal-bluetooth.c. Some interfaces which frameworks requested are missing.
eg.
Bluetooth Handsfree interface
Bluetooth Health Interface
Bluetooth GATT Interface
Don't know if bluez.org will fill them later. I have to study the source before knowing if they are required.
Update: The Handsfree service is included in the latest bluez update! Cheers!

As I mentioned before, I'm new to bluetooth. Further reading is required for me to fix other services. I also don't have enough time now. I have to process the stuck works after the Chinese New Year holiday. :cyclops: Hoping I can continue by the end of Feb. In the mean time, I hope someone have better knowledge may help fix other services.

For those devices don't have bluedroid support, we have a chance to carry on now! :D

Attached Thumbnails
Click image for larger version

Name:	Screenshot_2014-02-07-12-55-39.png
Views:	N/A
Size:	57.3 KB
ID:	2566469  
Attached Files
File Type: zip kernel-3.0.x-backport-3.13-1.zip - [Click for QR Code] (460.3 KB)
File Type: zip build-k.zip - [Click for QR Code] (1.1 KB)

Viewing all articles
Browse latest Browse all 3614

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>