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

Sunday, June 21, 2009

OBEX introduction


What is OBEX?
OBEX (abbreviation of OBject EXchange, also termed IrOBEX) is a communications protocol that facilitates the exchange of binary objects between devices. It is maintained by the Infrared Data Association but has also been adopted by the Bluetooth Special Interest Group and the SyncML wing of the Open Mobile Alliance (OMA). OBEX is very similar in design and function to HTTP. It's a client-server type. One device is a server and it waits for any connections. The other device is a client and it requests to send a file to the server.

How to use OBEX via bluetooth in Android?
There are some popular open source projects and they have implemented OBEX protocol. I choose openobex, obexpushd, obexftp applications, and I made some changes to allow them to run in Android.

* build
  1. download the original source
  2. write related Android.mk files
  3. fix undeclared problems or modify to use glib functions....etc
  4. upload the source code to gitorious site (http://gitorious.org/android-obex)
* install
adb push obexpushd /system/xbin/obexpushd
adb push obexftp /system/bin/obexftp
adb push obex_test /system/bin/obex_test

Examples:
A. Run an OBEX data server in Android, use 'adb shell' to Android Dev phone terminal

> su (use root account)
# cd /sdcard (change dir to sdcard and launch obex data server here)
# obexpushd (it will store incoming files to /sdcard dir and run in backgournd)
or
# obexpushd -n -d (it will store incoming file to /sdcard dir and not run in backgound, display debug message)

When it launchs an OBEX data server in Android, it would broadcast "OBEX Object Push" service from SDP server. If you use other BT devices to search OBEX service, it can discover Android Dev phone. Once you make a paired connection, you can send files to Android Dev phone via bluetooth. It will automatically store files to sdcard.

B. Make Android Dev phone as a client, use 'adb shell' to Android Dev phone terminal

This is an example, I send a mp3 file from Android phone to my NOKIA N73 mobile phone.

> su (use root account)
# hcitool scan (scan all near by bluetooth device)
Scanning ...
00:18:C5:42:18:78 Erin-Nokia N73
# sdptool search FTP (search near by BT device with FTP service)
Inquiring ...
Searching for FTP on 00:18:C5:42:18:78 ...
Service Name: OBEX File Transfer
Service RecHandle: 0x1000e
Service Class ID List:
"OBEX File Transfer" (0x1106)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 11
"OBEX" (0x0008)
Language Base Attr List:
code_ISO639: 0x454e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"OBEX File Transfer" (0x1106)
Version: 0x0100

# cd /sdcard
# obexftp -b 00:18:C5:42:18:78 -B 11 --list (list folder information)
Browsing 00:18:C5:42:18:78 ...
Channel: 11
Connecting..\done
Receiving "(null)"...|

]>



done
Disconnecting../done

# obexftp -b 00:18:C5:42:18:78 -B 11 -cE: -p 01.Breakaway.mp3 (send a MP3 song to NOKIA phone)
Browsing 00:18:C5:42:18:78 ...
Channel: 11
Connecting..\done
Sending "E:"...|done
Sending "01.Breakaway.mp3".../done
Disconnecting..-done

# obex_test -b 00:18:C5:42:18:78 11 (send obex text file to NOKIA phone)
Using Bluetooth RFCOMM transport
OBEX Interactive test client/server.
> c (create connection)
Made some progress...
Server request finished!
server_done() Command (00) has now finished
Timeout waiting for data. Aborting
> p (push a file)
PUT file (local, remote)> /sdcard/obex
test (write a subject name)
name=/sdcard/obex, size=3423
Going to send 3423 bytes
Made some progress...
Made some progress...
Made some progress...
Made some progress...
Server request finished!
server_done() Command (02) has now finished
Timeout waiting for data. Aborting
> q (leave it)

PS. all related source code is here.

Monday, June 15, 2009

Bluetooth OBEX file sharing in Android

I'd like to use OBEX in Android Dev phone, but there is no any available bluetooth application yet. Therefore, I made some changes from 'openobex' and 'obexpushd', then I can run these applications in Android. According to Android Bluetooth architecture, we can see ‘RFCOMM’ in kernel bluez. RFCOMM is a simple set of transport protocols, made on top of the L2CAP protocol, providing emulated RS-232 serial ports (up to sixty simultaneous connections to a bluetooth device at a time). In the protocol stack, RFCOMM is bound to L2CAP. In Bluetooth, OBEX is used for many profiles that require simple data exchange, e.g. object push, file transfer, basic imaging, basic printing, phonebook access etc. In the protocol stack, OBEX is bound to RFCOMM. It means if I can use RFCOMM connections between two BT devices correctly, I should be able to use OBEX between them.

Here is my experiment!

I prepared two bluetooth devices, one is my ubuntu laptop and the other one is Android Dev Phone. I installed bluez version 4.32 in Ubuntu and bluez version 3.36 in Android. OBEX is like the client-server networking. The sending file one is a client and the receiving one is a server. For example, if I want to receive a file via bluetooth in Android Dev phone, I can run an OBEX data server and it would start to listen a channel for any incoming connections. If I want to send a file via bluetooth in Android Dev phone, I can use obex_test or obexftp to push data to another BT device.



Receiving file in Android Dev phone

> obexpushd -n -d

this command would start an OBEX data server with debug message, not detach from terminal, and the default channel is 9. Be aware of the file permission problem in Android! I run this command in /sdcard folder, and then it can store the incoming files in this folder with write permission.

Sending file from Android Dev phone

> obex_test -b OTHER_BT_ADDR CHANNEL

this command will build the connection betwen Android Dev phone and the other BT device. OTHER_BT_ADDRESS is the other BT device address and CHANNEL is its OBEX channel number.

Done! Listening to the music!




PS. source code is in google code temporally and I will move to gitorious site soon.

Wednesday, June 3, 2009

QR code scanner in Android


We were talking about making our 0xlab business card this afternoon. How can make it be different? use particular title, like code generator, cleaner, terminator, or CEO something? ha, some people want to put finger print to provide their public key. I also want to put something interesting, then I think of 'QR code'.

I downloaded a 'QR code scanner'(reader) from Android Market and made a QR code image from this 'QR door website' (QR code generator). We can make few kinds of QR code image. Like contact information, URL, email address, RSS feed, Geo location, plain text, phone number....etc.

How we apply for these QR code type?

Contact information: it would be a name card. When we scan it by a cell phone, we can store it to Address book directly.


URL: when we scan it, we can open the link from web browser.


Geo location: we can provide Geo information for restaurants or sightseeing places. When we scan it, it can be added in the map. It would be extremely convenient for people cannot remember the address or people are easy to get lost.



Phone number: when we scan it, we can dial to this number directly.


SMS: when we scan it, we can launch SMS application to send a message.