Thursday, June 25, 2009

Android bluetooth introduction part I


Here is a very detailed image from Android website and it tells us the whole architecture about bluetooth in Android. I tried to understand how bluetooth works in Android Dev phone and what BT services we can use.

I. related source code

* bluez 3.36 (both userspace & kernel)
- /mydroid/externel/bluez
- /mydroid/kernel/drivers/bluetooth
- /mydroid/kernel/net/bluetooth

* framework (java & c++)
- /mydroid/frameworks/base/core/jni/android_bluetooth_*.cpp (connect with hcid via dbus)
- /mydroid/frameworks/base/core/java/android/bluetooth/*.java
- /mydroid/frameworks/base/services/java/com/android/server/ (SystemServer)

* UI application (java)
- /mydroid/packages/apps/Phone/src/com/android/phone/ (Phone App)
- /mydroid/packages/apps/Settings/src/com/android/settings/bluetooth/ (Settings App)


II. Init bluetooth

* init script from /root/init.rc
  1. create this directory '/data/misc/hcid' to store paired BT device information
  2. launch dbus-daemon (deal connections between hcid and system server)
  3. create hcid (Bluetooth Host Controller Interface Daemon) service, but disabled at first
  4. create hfag service, it's for bluetooth Hands-Free Profile, but disabled at first, and only 'one shot' (it means not restart this service when it exits). Also it would register a SDP service and channel is 10.
  5. create hsag service, it's for bluetooth Headset Profile, but disabled at first, and only 'one shot' (it means not restart this service when it exits). Also it would register a SDP service and channel is 11.
  6. create dun service, it's for bluetooth Dial-up Networking Profile, but disabled at first, and only 'one shot' (it means not restart this service when it exits). Also it would register a SDP service and channel is 2.


# create basic filesystem structure
mkdir /data/misc/hcid 0770 bluetooth bluetooth

service dbus /system/bin/dbus-daemon --system --nofork
socket dbus stream 660 bluetooth bluetooth
user bluetooth
group bluetooth net_bt_admin

service hcid /system/bin/hcid -s -n -f /etc/bluez/hcid.conf
socket bluetooth stream 660 bluetooth bluetooth
socket dbus_bluetooth stream 660 bluetooth bluetooth
# init.rc does not yet support applying capabilities, so run as root and
# let hcid drop uid to bluetooth with the right linux capabilities
group bluetooth net_bt_admin misc
disabled

service hfag /system/bin/sdptool add --channel=10 HFAG
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

service dun /system/bin/sdptool add --channel=2 DUN
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

service hsag /system/bin/sdptool add --channel=11 HSAG
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

* init script from /root/init.trout.rc
  1. this script file is from /vendor/htc/dream folder and it's particular for this device.
  2. create hciattach (attach serial devices via UART HCI to BlueZ stack) service, but disabled at first.
  3. specify UART speed is 115200, serial device is /dev/ttyHS0, id/type is texas.


service hciattach /system/bin/hciattach \
-n -s 115200 /dev/ttyHS0 texas 4000000 flow
user bluetooth
group bluetooth net_bt_admin
disabled

* system server: it would decide whether it should turn bluetooth ON or OFF from settings value. If the value is ON, then it would start hciattach and hcid service. That is why the init scripts set them disabled at first. We can decide BT power from UI application.


III. Connect with other BT devices

  • bluez: it provides 'hcid' daemon and it's responsible for all related bluetooth services
  • dbus-daemon: the bridge between hcid and system server
  • D-Bus is a simple inter-process communication (IPC) system for software applications to communicate with one another.
  • debug utility: d-feet (a dbus UI debugger ), dbus-monitor (debug probe to print message bus messages), dbus-send (Send a message to a message bus)
  • bluez dbus API document: /mydroid/external/bluez/utils/hcid/dbus-api.txt
  • one example as below


* Scan nearby BT devices in Android


In system server, it would send a method 'DiscoverDevices' to bluez via dbus-daemon. This method starts the device discovery procedure. This includes an inquiry procedure and remote device name resolving. On start up this process will generate a DiscoveryStarted signal and then return DeviceFound singals. If the procedure has been finished an DiscoveryCompleted signal will be sent.



/mydroid/frameworks/base/core/jni/android_server_BluetoothDeviceService.cpp

/* Compose the command */
msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, nat->adapter, DBUS_CLASS_NAME, "DiscoverDevices");
/* Send the command. */
reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);

log from ddms

06-18 14:42:14.567: INFO/BluetoothEventLoop.cpp(67): DiscoveryStarted signal received
06-18 14:42:14.584: VERBOSE/BluetoothEventRedirector(361): Received android.bluetooth.intent.action.DISCOVERY_STARTED
06-18 14:42:14.834: VERBOSE/BluetoothEventRedirector(361): Received android.bluetooth.intent.action.REMOTE_DEVICE_FOUND
06-18 14:42:35.034: INFO/BluetoothEventLoop.cpp(67): DiscoveryCompleted signal received

12 comments:

  1. Thank you so much for your great articles about bluetooth on android... I'm currently researching it too but only scratched the surface yet. Your stuff is very useful for me, thanks :)

    ReplyDelete
  2. Thanks! I am very glad that someone would think it's useful. :)

    ReplyDelete
  3. Hi, do you have experience to certificate BQB

    ReplyDelete
  4. I need to implement hidd on android ny pointers for the same. By now my understanding about bluetooth implementation is :
    only A2dp is fully implemented in framework layer.
    SPP's apis available but still not integrated with services and implemented in UI.

    ReplyDelete
  5. if you just wanna use hidd to connect with bt mice or keyboard, you may use 'hidd' from native bluez. Here is a useful notes as below. You could use that patch and rebuild native bluez in Android building system. Then upload hidd to your Android device.

    http://groups.google.com/group/android-platform/browse_thread/thread/73eed70fb229d7ae

    ReplyDelete
  6. Hi Erin, I'm looking to use my Apple wireless keyboard with my new HTC Hero and found your nice articles. But I'm confused as to what steps I need to take and in what order.

    Is there already support for what I need in Cupcake but it isn't switched on/exposed or do I need to compile my own bluez and install?

    I'd like to get it working in the least invasive way possible (unless it's significantly easier doing it some other way, since I really don't know what I'm doing). I've managed to get root access at least.

    I'm on Ubuntu 9.04 btw.

    Cheers,
    Magnus

    ReplyDelete
  7. Hi Magnus,

    How is HTC Hero? I only saw its photos and videos from Internet, not touched any new one yet. :P

    mmh...you have to get the root permission first, then you can upload related file to Android phone.
    you probably could read this very useful notes here. http://groups.google.com/group/android-platform/browse_thread/thread/73eed70fb229d7ae

    it tells us how to build hidd from Android source tree and run hidd command to connect with BT keyboard. I followed those steps and then i can use Apple wireless keyboard with my Android Dev phone.

    mmh...i also met one problem with my Apple keyboard, coz i cannot use it in bluetooth discovery mode. Therefore, i cannot see it from Android phone. How i solved it? i removed the battery a while and put it back. (it can clear previous pairing information) Long pressed power button and it entered into discovery mode again.

    i hope you can use your Apple keyboard soon! :)

    Happy hacking,
    Erin

    ReplyDelete
  8. The Hero is really great, I certainly don't understand why people are whining about it being slow. But maybe it is compared to iPhone (which I haven't tried).

    The notes you pointed to seems nice but since I have no experience developing on Android there are a few things that aren't obvious to me.

    How do I locate the bluetooth lib on my phone?

    Step 1 (building): The Android.mk, is it supposed to be stored on the phone?

    Step 2 (building): The fastboot command, does it mean that I'm overwriting everything on the phone or just the bluetooth bits?

    And what is the RC29 note about, is it in case you want to go back to the original software?

    ReplyDelete
  9. if you have no experience on Android yet, I wouldn't recommend you use fastboot to flash the whole image. It would overwrite the whole system, not only bluez stuff.

    if you'd like to build bluez lib, you will need to set up Android building system. You may follow this page, it shows you how to setup. http://source.android.com/download

    HTC provides some tools and official images in their website. We can use it and roll back our android phone, if we screw up the phone.
    http://www.htc.com/www/support/android/adp.html

    About your questions:
    Step 1 (building): The Android.mk, is it supposed to be stored on the phone?

    No, we store this file in $MYDROID/external/bluez/util/hidd folder. ($MYDROID is Android source tree folder)
    We need to use this file to compile hidd binary file and then upload hidd to Android phone.

    Also, i am not sure about RC29 note and i only upload bluez stuff to my Android phone. fastboot is to flash the whole system image, but we can use 'adb push' to upload files to phone.

    ReplyDelete
  10. Okay, confused yet again (sorry for being such a bother):

    The Android.mk, I put it in the $MYDROID/external/bluez/utils/hidd folder just like you said, but couldn't figure out how to build only the bluez parts, so I built the entire tree.

    How do I build only bluez?

    ReplyDelete
  11. Did you download the whole android source using repo sync? if you did, then make sure two things.

    1. cd $MYDROID, then type 'make'. it would take a while and depends on your machine. I took about two hours to finish it. If it's done, it would say like as below:
    Target system fs image: out/target/product/generic/obj/PACKAGING/systemimage_unopt_intermediates/system.img
    Install system fs image: out/target/product/generic/system.img
    Target ram disk: out/target/product/generic/ramdisk.img
    Target userdata fs image: out/target/product/generic/userdata.img
    Installed file list: out/target/product/generic/installed-files.txt

    2. then start to build bluez hidd
    $ cd $MYDROID/external/bluez
    $ . ../../build/envsetup.sh
    $ touch `find -name "*.c"`
    $ cd utils/hidd
    $ mm

    If it's done, it would say like as below:
    target Non-prelinked: hidd (out/target/product/generic/symbols/system/bin/hidd)
    target Strip: hidd (out/target/product/generic/obj/EXECUTABLES/hidd_intermediates/hidd)
    Install: out/target/product/generic/system/xbin/hidd
    make: Leaving directory `/home/erin/mydroid'

    DONE! you can upload $MYDROID/out/target/product/generic/system/xbin/hidd this binary file to "/system/xbin" in your Android phone.

    $ adb push $MYDROID/out/target/product/generic/system/xbin/hidd /system/xbin

    PS. sorry! i am going to close my comment board, but i will reply emails from 0xlab-discuss mailing list. If you have any question, welcome to join our groups. :)

    http://groups.google.com/group/0xlab-discuss?hl=en

    ReplyDelete

Note: Only a member of this blog may post a comment.