Friday, September 2, 2011

BT LE FindMe profile in Bluez

There is a post in Bluez mailing list "Current status on BLE development". It tells us current BT LE status in Bluez and also shows some git repositories with their development. I try to build their kernel and the latest bluez. I made some experiments and understood more about FindMe profile in Bluez.

* Unstable kernel with Interleaved Discovery, RSSI Threshold monitor,
LE scanning and remaining SM patches
[1] http://git.infradead.org/users/vcgomes/linux-2.6.git (branch
proximity-integration)

* BlueZ Userspace
[2] git://git.infradead.org/users/cktakahasi/bluez.git proximity-devel

Experiment I: prepare one LE device only(Key Fob/Reporter/GATT Server) and one dual mode LE/BR/EDR device (Monitor/GATT Client) in Ubuntu machine. Key Fob runs immediate alert service. Bluez register the monitor service and it can write Alert Level to reporter. If Alert Level is mild or high, the Key Fob would ring. Then user can find where is the Key Fob. Reference to Immediate Alert Service (UUID: 0x1802) page and Alert Level(UUID:0x2a06) page.

Reference from Bluetooth.org site:
The Immediate Alert service is instantiated as a Primary Service. There is only one instance of the Immediate Alert service on a device. There is only one instance of the Alert Level characteristic in an Immediate Alert service. This alert continues until one of following conditions occurs:
• An implementation specific timeout
• User interaction on this device
• A new alert level is written
• The physical link is disconnected

Examples:
If the written alert level is “No Alert”, no alerting is done on this device.
If the written alert level is “Mild Alert”, the device alerts.
If the written alert level is “High Alert”, the device alerts in the strongest possible way.

How to demo it:
1. set Key Fob to advertising mode
2. try LE scan from Ubuntu

erin@sundays:/project/upstream/bluez$ sudo hcitool -i hci0 lescan
LE Scan ...
C0:FF:EE:C0:AA:06
C0:FF:EE:C0:AA:06
C0:FF:EE:C0:AA:06
C0:FF:EE:C0:AA:06
C0:FF:EE:C0:AA:06

3. create LE connection

erin@sundays:/project/upstream/bluez$ sudo hcitool -i hci0 lecc C0:FF:EE:C0:AA:06
Connection handle 32

4. use gatttool to browse the service of LE device

erin@sundays:/project/upstream/bluez$ sudo gatttool -i hci0 -b C0:FF:EE:C0:AA:06 -m 48 --interactive
[ ][C0:FF:EE:C0:AA:06][LE]> connect
[CON][C0:FF:EE:C0:AA:06][LE]> primary
[CON][C0:FF:EE:C0:AA:06][LE]>
attr handle: 0x0001, end grp handle: 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x000e uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000f, end grp handle: 0x0011 uuid: 00001803-0000-1000-8000-00805f9b34fb
attr handle: 0x0012, end grp handle: 0x0014 uuid: 00001802-0000-1000-8000-00805f9b34fb
attr handle: 0x0015, end grp handle: 0x0017 uuid: 00001804-0000-1000-8000-00805f9b34fb
attr handle: 0x0018, end grp handle: 0x001e uuid: 0000ffb0-0000-1000-8000-00805f9b34fb
attr handle: 0x001f, end grp handle: 0x0031 uuid: 0000ffa0-0000-1000-8000-00805f9b34fb
attr handle: 0x0032, end grp handle: 0x0036 uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
[CON][C0:FF:EE:C0:AA:06][LE]> characteristics 0x0012 0x0014
[CON][C0:FF:EE:C0:AA:06][LE]>
handle: 0x0013, char properties: 0x08, char value handle: 0x0014, uuid: 00002a06-0000-1000-8000-00805f9b34fb
[CON][C0:FF:EE:C0:AA:06][LE]> char-desc 0x0012 0x00014
[CON][C0:FF:EE:C0:AA:06][LE]>
handle: 0x0012, uuid: 2800
handle: 0x0013, uuid: 2803
handle: 0x0014, uuid: 2a06
[CON][C0:FF:EE:C0:AA:06][LE]> char-read-uuid 2a06
[CON][C0:FF:EE:C0:AA:06][LE]>
handle: 0x0011 value: 00
[CON][C0:FF:EE:C0:AA:06][LE]> char-write-cmd 0x0011 02
[CON][C0:FF:EE:C0:AA:06][LE]> char-read-uuid 2a06
[CON][C0:FF:EE:C0:AA:06][LE]>
handle: 0x0011 value: 02
[CON][C0:FF:EE:C0:AA:06][LE]> disconnect

5. Key Fob would start to ring

Experiment II: prepare two BT BR/EDR devices. One is my Ubuntu laptop (daydreamer) and the other is my Ubuntu Desktop (Sundays). Daydreamer is a Key Fob (Client) and Sundays is a Monitor (Server).

1. Fake Immediate Alert profile and Link Loss profile in local data files.

erin@sundays:/project/vcgomes/linux-2.6$ cat /var/lib/bluetooth/00\:13\:EF\:F0\:C4\:46/profiles
78:DD:08:A3:A7:52 0000110a-0000-1000-8000-00805f9b34fb 0000110c-0000-1000-8000-00805f9b34fb 0000110e-0000-1000-8000-00805f9b34fb 00001112-0000-1000-8000-00805f9b34fb 0000111f-0000-1000-8000-00805f9b34fb 00001800-0000-1000-8000-00805f9b34fb 00001801-0000-1000-8000-00805f9b34fb 00001802-0000-1000-8000-00805f9b34fb 00001803-0000-1000-8000-00805f9b34fb
erin@sundays:/project/vcgomes/linux-2.6$ cat /var/lib/bluetooth/00\:13\:EF\:F0\:C4\:46/primary
78:DD:08:A3:A7:52 0011#0013#00001802-0000-1000-8000-00805f9b34fb 0009#000b#00001803-0000-1000-8000-00805f9b34fb

2. use dbus-send to change Alert Service value

erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/2617/hci1/dev_78_DD_08_A3_A7_52 org.bluez.Proximity.GetProperties
method return sender=:1.62 -> dest=:1.91 reply_serial=2
array [
dict entry(
string "LinkLossAlertLevel"
variant string "none"
)
dict entry(
string "ImmediateAlertLevel"
variant string "none"
)
]

erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/2617/hci1/dev_78_DD_08_A3_A7_52 org.bluez.Proximity.SetProperty string:ImmediateAlertLevel variant:string:high
method return sender=:1.62 -> dest=:1.92 reply_serial=2

erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/2617/hci1/dev_78_DD_08_A3_A7_52 org.bluez.Proximity.GetProperties
method return sender=:1.62 -> dest=:1.93 reply_serial=2
array [
dict entry(
string "LinkLossAlertLevel"
variant string "none"
)
dict entry(
string "ImmediateAlertLevel"
variant string "high"
)
]

3. use gatttool to check the Alert Level value

erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/2617/hci1/dev_78_DD_08_A3_A7_52 org.bluez.Proximity.SetProperty string:LinkLossAlertLevel variant:string:mild
method return sender=:1.62 -> dest=:1.96 reply_serial=2

erin@sundays:/project/upstream/bluez$ sudo gatttool -i hci0 -b 78:DD:08:A3:A7:52 -p 31 -m 48 --interactive
[ ][78:DD:08:A3:A7:52][BR]> connect
[CON][78:DD:08:A3:A7:52][BR]> char-read-uuid 2a06
[CON][78:DD:08:A3:A7:52][BR]>
handle: 0x000b value: 01
handle: 0x0013 value: 00

Tuesday, April 19, 2011

OBEX Message Access Profile introduction

Have you ever tried to push a SMS message from a laptop to an Android phone via Bluetooth? It's very similar to OPP (object push profile) and it is to use OBEX to exchange data too. I found some patches in Aurora about supporting MAP (message access profile) in Android two months ago. Finally, I got some time to play with it.

What is MAP? MAP defines a set of features and procedures to exchange messages between devices. It is especially tailored for the automotive Hands-Free use case where an onboard terminal device (typically a Car-Kit installed in the car) takes advantage of the messaging capability of a communication device (typically a mobile phone). This profile can however also be used for other use cases that require the exchange of messages between two devices.

I have no Car-Kit to verify this profile and I cannot find any platform to support it either. Therefore, I use python lightblue and write few lines to verify this function. I have one samsung smdkv210 platform and one ubuntu laptop. Below is the list about MAP profile from Aurora git repository. If you are using gingerbread, you could apply their patches easily. Also, it's just a simple list and we should review git log to retrieve more patches related to MAP profile.

native bluez
Bluetooth : Add MAP service records into SDP tool
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/bluetooth/bluez.git;a=commit;h=7f52e048879c74a35a212ed4a0ce2f14133e2806

android frameworks
frameworks/bluetooth: Changes for enabling Bluetooth MAP profile
https://www.codeaurora.org/gitweb/quic/la/?p=platform/frameworks/base.git;a=commit;h=a7d9bf26766e420be997d2858fc7b73b42868860

Bluetooth UI application
Bluetooth: Adding MAP Profile implementation
https://www.codeaurora.org/gitweb/quic/la/?p=platform/packages/apps/Bluetooth.git;a=commit;h=e900ed4897561fbb317a8c1488ac84c0fb051068

Email UI application
Email: Changes to trigger Email app to update its mailbox from Bluetooth MAP Profile
https://www.codeaurora.org/gitweb/quic/la/?p=platform/packages/apps/Email.git;a=commit;h=e11f384228e44cb8b718247436fc0501bb81673a

MMS UI application
Mms: Enable MMS app to push a MMS added to outbox by Bluetooth MAP profile
https://www.codeaurora.org/gitweb/quic/la/?p=platform/packages/apps/Mms.git;a=commit;h=703e2c2ae82f973954c539cd8e55470e4d6c3873

Add MAS service from init.rc file and then we can see MAP record from sdptool.

#cat /root/init.rc
service map /system/bin/sdptool add --channel=16 MAS
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

# sdptool browse local
Service Name: OBEX Message Access
Service RecHandle: 0x10008
Service Class ID List:
"" (0x1132)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 16
"OBEX" (0x0008)
Profile Descriptor List:
"" (0x1134)
Version: 0x0100


I use ipython to write my scripts to demo MAP function. I create an OBEX Client from my Ubuntu machine and use it to connect with Android device. It send a 'get' request to retrieve the first slot of SMS.


import lightblue
host="12:60:41:7F:03:11"
port=16
client = lightblue.obex.OBEXClient(host,port)
client.connect()
f=file('/home/erin/Desktop/temp','w+')
client.get({'type':"x-bt/message",'name':'1'},f)
f.seek(0)
f.read()
f.close()
client.disconnect()





Monday, December 27, 2010

GATT related dbus API

After trying gatttool, I am trying how to use this new attribute dbus api in bluez. I find there is an "attrib/example.c" and it would create some service records to demo GATT. When we create a device to bluez, it would detect the device type. If it's a LE device, it would run to "attrib_client_register", then register Primary and Characteristics services. We can use d-feet to see these interfaces. Also, bluez will write some data files to "/var/lib/bluetooth/". When we restart bluez, it can create these interfaces without discovering the remote device again.


Primary Service
We can know what kind of services this remote BT device has from 'UUIDs' value. For example, "0x1801" is GENERIC_ATTRIB_SVCLASS_ID and "0x1800" is GENERIC_ACCESS_PROFILE_ID. 'Services' value is the object path of all primary services.

erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/5444/hci0/dev_78_DD_08_A3_A7_52 org.bluez.Device.GetProperties


method return sender=:1.93 -> dest=:1.96 reply_serial=2
array [
dict entry(
string "Address"
variant string "78:DD:08:A3:A7:52"
)
dict entry(
string "Name"
variant string ""
)
dict entry(
string "Alias"
variant string "78-DD-08-A3-A7-52"
)
dict entry(
string "Paired"
variant boolean true
)
dict entry(
string "Trusted"
variant boolean false
)
dict entry(
string "Blocked"
variant boolean false
)
dict entry(
string "Connected"
variant boolean false
)
dict entry(
string "UUIDs"
variant array [
string "00001105-0000-1000-8000-00805f9b34fb"
string "00001106-0000-1000-8000-00805f9b34fb"
string "0000110a-0000-1000-8000-00805f9b34fb"
string "0000110c-0000-1000-8000-00805f9b34fb"
string "0000110e-0000-1000-8000-00805f9b34fb"
string "00001112-0000-1000-8000-00805f9b34fb"
string "0000111f-0000-1000-8000-00805f9b34fb"
string "00001800-0000-1000-8000-00805f9b34fb"
string "00001801-0000-1000-8000-00805f9b34fb"
string "0000a002-0000-1000-8000-00805f9b34fb"
string "0000a004-0000-1000-8000-00805f9b34fb"
string "4f0ac096-35d4-4911-9631-dea8dc74eefe"
]
)
dict entry(
string "Services"
variant array [
object path "/org/bluez/5444/hci0/dev_78_DD_08_A3_A7_52/service0001"
object path "/org/bluez/5444/hci0/dev_78_DD_08_A3_A7_52/service0010"
object path "/org/bluez/5444/hci0/dev_78_DD_08_A3_A7_52/service0100"
object path "/org/bluez/5444/hci0/dev_78_DD_08_A3_A7_52/service0200"
object path "/org/bluez/5444/hci0/dev_78_DD_08_A3_A7_52/service0680"
]
)
dict entry(
string "Adapter"
variant object path "/org/bluez/5444/hci0"
)
]


Characteristics Service
We can also discover what kind of characteristics service this BT device has. It would like use gatttool to run "--characteristics" and it would register related interfaces like below:

erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/5612/hci0/dev_78_DD_08_A3_A7_52/service0200 org.bluez.Characteristic.Discover
method return sender=:1.107 -> dest=:1.112 reply_serial=2


erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/5612/hci0/dev_78_DD_08_A3_A7_52/service0200 org.bluez.Characteristic.GetProperties


method return sender=:1.107 -> dest=:1.117 reply_serial=2
array [
dict entry(
string "Characteristics"
variant array [
object path "/org/bluez/5612/hci0/dev_78_DD_08_A3_A7_52/service0200/characteristic0204"
object path "/org/bluez/5612/hci0/dev_78_DD_08_A3_A7_52/service0200/characteristic0212"
]
)
]

Attribute Value - READ
From example.c, we know "0xA006" is TEMPERATURE_UUID. We can call below dbus method to retrieve its properties. This "Value" property is an array of bytes and it could have format, value and representation to describe the exact value meaning.


erin@sundays:~$ dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/5612/hci0/dev_78_DD_08_A3_A7_52/service0200/characteristic0204 org.bluez.Characteristic.GetProperties


method return sender=:1.107 -> dest=:1.118 reply_serial=2
array [
dict entry(
string "UUID"
variant string "0000a006-0000-1000-8000-00805f9b34fb"
)
dict entry(
string "Name"
variant string ""
)
dict entry(
string "Description"
variant string "Outside Temperature"
)
dict entry(
string "Value"
variant array of bytes [
8a 02
]
)
]


Bluez Data Files
GATT related files in /var/lib/bluetooth

erin@sundays:~$ cat /var/lib/bluetooth/00\:1B\:DC\:02\:86\:C5/primary
78:DD:08:A3:A7:52 0001#0006#00001800-0000-1000-8000-00805f9b34fb 0010#0012#00001801-0000-1000-8000-00805f9b34fb 0100#0111#0000a002-0000-1000-8000-00805f9b34fb 0200#0214#0000a004-0000-1000-8000-00805f9b34fb 0680#0685#4f0ac096-35d4-4911-9631-dea8dc74eefe

erin@sundays:~$ cat /var/lib/bluetooth/00\:1B\:DC\:02\:86\:C5/characteristic
78:DD:08:A3:A7:52#0001 0006#02#0006#00002a00-0000-1000-8000-00805f9b34fb 0006#02#0006#00002a00-0000-1000-8000-00805f9b34fb
78:DD:08:A3:A7:52#0010 0012#02#0012#0000a001-0000-1000-8000-00805f9b34fb
78:DD:08:A3:A7:52#0200 0204#02#0210#0000a006-0000-1000-8000-00805f9b34fb 0212#02#0214#0000a009-0000-1000-8000-00805f9b34fb

erin@sundays:~$ cat /var/lib/bluetooth/00\:1B\:DC\:02\:86\:C5/attributes
78:DD:08:A3:A7:52#0205 00002904-0000-1000-8000-00805f9b34fb#0EFE07A00108A0
78:DD:08:A3:A7:52#0206 00002901-0000-1000-8000-00805f9b34fb#4F7574736964652054656D706572617475726500
78:DD:08:A3:A7:52#0213 00002904-0000-1000-8000-00805f9b34fb#04000AA00BA008
78:DD:08:A3:A7:52#0214 00002901-0000-1000-8000-00805f9b34fb#4F7574736964652052656C61746976652048756D696400

erin@sundays:~$ cat /var/lib/bluetooth/00\:1B\:DC\:02\:86\:C5/profiles
78:DD:08:A3:A7:52 00001105-0000-1000-8000-00805f9b34fb 00001106-0000-1000-8000-00805f9b34fb 0000110a-0000-1000-8000-00805f9b34fb 0000110c-0000-1000-8000-00805f9b34fb 0000110e-0000-1000-8000-00805f9b34fb 00001112-0000-1000-8000-00805f9b34fb 0000111f-0000-1000-8000-00805f9b34fb 00001801-0000-1000-8000-00805f9b34fb


Attribute Value - WRITE
How to change a characteristic value? I really don't know how to send a value like "variant array of bytes [8a 02]". Then, I use ipython to send this dbus method, then I can rewrite its value.


In [1]: import dbus
In [2]: bus_name="org.bluez"
In [3]: obj_path="/org/bluez/5612/hci0/dev_78_DD_08_A3_A7_52/service0200/characteristic0204"
In [4]: bus = dbus.SystemBus()
In [5]: proxy = bus.get_object(bus_name,obj_path)
In [6]: char = dbus.Interface(proxy, dbus_interface="org.bluez.Characteristic")
In [7]: properties = char.GetProperties()
In [8]: print properties
dbus.Dictionary({dbus.String(u'Description'): dbus.String(u'Outside Temperature', variant_level=1), dbus.String(u'UUID'): dbus.String(u'0000a006-0000-1000-8000-00805f9b34fb', variant_level=1), dbus.String(u'Value'): dbus.Array([dbus.Byte(128), dbus.Byte(110)], signature=dbus.Signature('y'), variant_level=1), dbus.String(u'Name'): dbus.String(u'', variant_level=1)}, signature=dbus.Signature('sv'))
In [9]: result = char.SetProperty("Value", dbus.Array([dbus.Byte(77), dbus.Byte(22)]))
In [10]: properties = char.GetProperties()
In [11]: print properties
dbus.Dictionary({dbus.String(u'Description'): dbus.String(u'Outside Temperature', variant_level=1), dbus.String(u'UUID'): dbus.String(u'0000a006-0000-1000-8000-00805f9b34fb', variant_level=1), dbus.String(u'Value'): dbus.Array([dbus.Byte(77), dbus.Byte(22)], signature=dbus.Signature('y'), variant_level=1), dbus.String(u'Name'): dbus.String(u'', variant_level=1)}, signature=dbus.Signature('sv'))

Tuesday, December 21, 2010

gatttool in bluez over BR/EDR

Recently, I am studying Bluetooth 4.0 (Low Energy) core spec and checking the latest bluez code about LE stuff. Here is my working notes and how I use 'gatttool' to verify Generic Attribute Profile (GATT) features. We can check this feature over BR/EDR first, not use real LE device yet. My working machine is Ubuntu 10.10.

Set up Bluez part

retrieve latest bluez code, configure it with enable-attrib, and compile it
# git clone git://git.kernel.org/pub/scm/bluetooth/bluez.git
# cd bluez
# autoreconf -vifs
# ./configure --prefix=/usr --mandir=/usr/share/man \
--sysconfdir=/etc --localstatedir=/var --libexecdir=/lib --enable-attrib
# make && sudo make install

modify main.conf, enable LE and attribute-server

diff --git a/src/main.conf b/src/main.conf
index c03f135..121ee9b 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -58,9 +58,9 @@ DebugKeys = false

# Enable Low Energy support if the dongle supports. Default is false.
# Enable/Disable interleave discovery and attribute server over LE.
-EnableLE = false
+EnableLE = true

# Enable the GATT Attribute Server. Default is false, because it is only
# useful for testing. Attribute server is not enabled over LE if EnableLE
# is false.
-AttributeServer = false
+AttributeServer = true

start bluetooth daemon in foreground with debug information

# sudo /usr/sbin/bluetoothd -n -d

Play with gatttool

Since we configured Bluez with enable-attrib, we will start an attribute-server from running bluetooth daemon. It would add some attribute records for GATT service, and it's created from attrib/example.c file. Also, we will add a GAP service like below.


erin@sundays:~/project/bluez$ sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
Service Name: Generic Attribute Profile
Service Provider: BlueZ
Service RecHandle: 0x10000
Service Class ID List:
"Generic Attribute" (0x1801)
Protocol Descriptor List:
"L2CAP" (0x0100)
PSM: 31
"ATT" (0x1801)
uint16: 0x1
uint16: 0xffff
Profile Descriptor List:
"Generic Attribute" (0x1801)
Version: 0x0100

Below GATT features are from BT 4.0 core spec Volume 3 Part G.

Primary Service Discovery
This procedure is used by a client to discover primary services on a server. Once the primary services are discovered, additional information about the primary services can be accessed using other procedures, including characteristic discovery and relationship discovery to find other related primary and secondary services.

a. Discover all primary services ==> "Read By Group Type Request"
b. Discover primary service by service UUID ==> "Find By Type Value Request"



gatt_discover_primary(attrib, opt_start, opt_end, opt_uuid, primary_by_uuid_cb, attrib);

erin@sundays:~$ sudo gatttool -b 78:DD:08:A3:A7:52 --primary --psm=31 --mtu=48
attr handle = 0x0001, end grp handle = 0x0006, attr value (UUID) = 1800
attr handle = 0x0010, end grp handle = 0x0012, attr value (UUID) = 1801
attr handle = 0x0100, end grp handle = 0x0111, attr value (UUID) = a002
attr handle = 0x0200, end grp handle = 0x0214, attr value (UUID) = a004
attr handle = 0x0680, end grp handle = 0x0685, attr value (UUID) = 4f0ac096-35d4-4911-9631-dea8dc74eefe

erin@autumn:~/project/bluez$ gatttool -b 78:DD:08:A3:A7:52 --primary --uuid=1801
Starting handle: 0010 Ending handle: 0012

erin@autumn:~/project/bluez$ gatttool -b 78:DD:08:A3:A7:52 --primary --uuid=1800
Starting handle: 0001 Ending handle: 0006


Characteristic Discovery
This procedure is used by a client to discover service characteristics on a server. Once the characteristics are discovered additional information about the characteristics can be discovered or accessed using other procedures.

a. Discover all characteristics of a Service ==> "Read By Type Request"
b. Discover characteristics by UUID ==> "Read By Type Request"



gatt_discover_char(attrib, opt_start, opt_end, char_discovered_cb, char_data);
gatt_read_char_by_uuid(attrib, start, end, &uuid, func, user_data);

erin@sundays:~$ sudo gatttool -b 78:DD:08:A3:A7:52 --characteristics --psm=31 --mtu=48
handle = 0x0004, char properties = 0x02, char value handle = 0x0006, uuid = 2a00
handle = 0x0011, char properties = 0x02, char value handle = 0x0012, uuid = a001
handle = 0x0106, char properties = 0x02, char value handle = 0x0110, uuid = a003
handle = 0x0203, char properties = 0x02, char value handle = 0x0204, uuid = a006
handle = 0x0210, char properties = 0x02, char value handle = 0x0212, uuid = a009
handle = 0x0501, char properties = 0x02, char value handle = 0x0502, uuid = a00c
handle = 0x0503, char properties = 0x02, char value handle = 0x0504, uuid = a00d
handle = 0x0506, char properties = 0x02, char value handle = 0x0507, uuid = a00c
handle = 0x0508, char properties = 0x02, char value handle = 0x0509, uuid = a00d
handle = 0x0560, char properties = 0x02, char value handle = 0x0568, uuid = a00f
handle = 0x0682, char properties = 0x02, char value handle = 0x0683, uuid = 8088f218-902c-450b-b6c4-62891e8c25e9

erin@autumn:~/project/bluez$ gatttool -b 78:DD:08:A3:A7:52 --characteristics --start=0x0001 --end=0x0100
handle = 0x0004, char properties = 0x02, char value handle = 0x0006, uuid = 2a00
handle = 0x0011, char properties = 0x02, char value handle = 0x0012, uuid = a001


Characteristic Descriptor Discovery
This procedure is used by a client to discover characteristic descriptors of a characteristic. Once the characteristic descriptors are discovered additional information about the characteristic descriptors can be accessed using other procedures.

a. Discover All Characteristic Descriptors ==> "Find Information Request"



gatt_find_info(attrib, opt_start, opt_end, char_desc_cb, NULL);
erin@sundays:~$ sudo gatttool -b 78:DD:08:A3:A7:52 --char-desc --psm=31
handle = 0x0001, uuid = 2800
handle = 0x0004, uuid = 2803
handle = 0x0006, uuid = 2a00
handle = 0x0010, uuid = 2800
handle = 0x0011, uuid = 2803

erin@autumn:~/project/bluez$ gatttool -b 78:DD:08:A3:A7:52 --char-desc --start=0x0001 --end=0x0010
handle = 0x0001, uuid = 2800
handle = 0x0004, uuid = 2803
handle = 0x0006, uuid = 2a00
handle = 0x0010, uuid = 2800
erin@autumn:~/project/bluez$ gatttool -b 78:DD:08:A3:A7:52 --char-desc --start=0x0001 --end=0x0005
handle = 0x0001, uuid = 2800
handle = 0x0004, uuid = 2803


Characteristic Value Read
This procedure is used to read a Characteristic Value from a server.

a. Read characteristic value
b. Read using characteristic UUID
c. Read long characteristic values (not implement)
d. Read multiple characteristic values (not implement)



gatt_read_char(attrib, opt_handle, char_read_cb, attrib);
==> g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen, func, user_data, NULL);

gatt_read_char_by_uuid(attrib, opt_start, opt_end, opt_uuid, char_read_by_uuid_cb, char_data);
==> g_attrib_send(attrib, ATT_OP_READ_BY_TYPE_REQ, pdu, plen, func, user_data, NULL);

erin@sundays:~$ sudo gatttool -b 78:DD:08:A3:A7:52 --char-read --uuid=2800
handle: 0x0001 value: 00 18
handle: 0x0010 value: 01 18
handle: 0x0100 value: 02 a0
handle: 0x0200 value: 04 a0
handle: 0x0680 value: 4f 0a c0 96 35 d4 49 11 96 31 de a8 dc 74 ee fe

erin@sundays:~$ sudo gatttool -b 78:DD:08:A3:A7:52 --char-read --handle=0x0001
Characteristic value/descriptor: 00 18

erin@autumn:~/project/bluez$ gatttool -b 78:DD:08:A3:A7:52 --char-read --uuid=a00d
handle: 0x0504 value: 32 33 37 34 39 35 2d 33 32 38 32 2d 41
handle: 0x0509 value: 31 31 32 36 37 2d 32 33 32 37 41 30 30 32 33 39


Characteristic value write
This procedure is used to write a Characteristic Value to a server.

a. Write without response
b. Signed write without response (not check yet)
c. Write characteristic value
d. Write long charcharacteristic values (not check yet)
e. Reliable writes (not check yet)



erin@sundays:~$ gatttool -b 78:DD:08:A3:A7:52 --char-write --psm=31 --mtu=48 --handle=0x0001 --value=0x0011
erin@sundays:~$ gatttool -b 78:DD:08:A3:A7:52 --char-read --psm=31 --mtu=48 --handle=0x0001
Characteristic value/descriptor: 00 00 11

Sunday, October 24, 2010

Tips for Transmission in Android


use Transmission Web UI


1. set environment variable TRANSMISSION_WEB_HOME to "/etc/transmission/web"

diff --git a/external/transmission/libtransmission/platform.c b/external/transmission/libtransmission/platform.c
index d3493ae..e7d6ab8 100644
--- a/external/transmission/libtransmission/platform.c
+++ b/external/transmission/libtransmission/platform.c
@@ -27,6 +27,10 @@
#include
#endif

+#ifndef TRANSMISSION_WEB_HOME
+ #define TRANSMISSION_WEB_HOME "/etc/transmission/web"
+#endif
+
#include
#include
#include
@@ -615,7 +619,10 @@ tr_getWebClientDir( const tr_session * session UNUSED )
s = NULL;
}
}
-
+#elif defined( TRANSMISSION_WEB_HOME )
+ {
+ s = tr_strdup( TRANSMISSION_WEB_HOME );
+ }
#else /* everyone else, follow the XDG spec */



2. copy its Web UI to rootdir

diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index e91bad2..2f0ff12 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -5,6 +5,43 @@ include $(CLEAR_VARS)

copy_from := \
etc/dbus.conf \
+ etc/transmission/web/stylesheets/common.css \
+ etc/transmission/web/stylesheets/iphone.css \
+ etc/transmission/web/stylesheets/ie7.css \
+ etc/transmission/web/stylesheets/ie6.css \
+ etc/transmission/web/javascript/menu.js \
+ etc/transmission/web/javascript/common.js \
+ etc/transmission/web/javascript/torrent.js \
+ etc/transmission/web/javascript/transmission.remote.js \
+ etc/transmission/web/javascript/jquery \
+ etc/transmission/web/javascript/jquery/jquery.form.min.js \
+ etc/transmission/web/javascript/jquery/jquery.contextmenu.min.js \
+ etc/transmission/web/javascript/jquery/json.min.js \
+ etc/transmission/web/javascript/jquery/jquery.min.js \
+ etc/transmission/web/javascript/jquery/jquery.transmenu.min.js \
+ etc/transmission/web/javascript/dialog.js \
+ etc/transmission/web/javascript/transmission.js \
+ etc/transmission/web/index.html \
+ etc/transmission/web/images/favicon.ico \
+ etc/transmission/web/images/favicon.png \
+ etc/transmission/web/images/graphics/logo.png \
+ etc/transmission/web/images/graphics/filter_icon.png \
+ etc/transmission/web/images/graphics/chrome.png \
+ etc/transmission/web/images/graphics/iphone_chrome.png \
+ etc/transmission/web/images/graphics/transfer_arrows.png \
+ etc/transmission/web/images/graphics/filter_bar.png \
+ etc/transmission/web/images/progress/progress.png \
+ etc/transmission/web/images/buttons/cancel.png \
+ etc/transmission/web/images/buttons/info_activity.png \
+ etc/transmission/web/images/buttons/info_files.png \
+ etc/transmission/web/images/buttons/tab_backgrounds.png \
+ etc/transmission/web/images/buttons/torrent_buttons.png \
+ etc/transmission/web/images/buttons/toolbar_buttons.png \
+ etc/transmission/web/images/buttons/file_wanted_buttons.png \
+ etc/transmission/web/images/buttons/info_trackers.png \
+ etc/transmission/web/images/buttons/file_priority_buttons.png \
+ etc/transmission/web/images/buttons/info_general.png \
+ etc/transmission/web/images/webclip-icon.png \
etc/hosts


3. write transmission-daemon as a service in init.rc

diff --git a/rootdir/init.rc b/rootdir/init.rc
index 3011bf6..a3c45f8 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -361,6 +361,12 @@ service dbus /system/bin/dbus-daemon --system --nofork
user bluetooth
group bluetooth net_bt_admin

+service tr-daemon /system/bin/transmission-daemon -g /data/transmission -w /data/transmission/ -c /data/transmission/
+ user root
+ group net_admin system
+ disabled
+ oneshot
+
service bluetoothd /system/bin/bluetoothd -n
socket bluetooth stream 660 bluetooth bluetooth
socket dbus_bluetooth stream 660 bluetooth bluetooth


4. Some important arguments for transmission-daemon


-g --config-dir directory
Where to look for configuration files. When it stars to run, it would
write a settings.json file to this folder. It stores all config values.

-c directory
Directory to watch for new .torrent files to be added. If you push
torrent files to this directory, the daemon will load them into
Transmission automatically.

-w --download-dir
Where to store downloaded data.



5. add Transmission site "http://localhost:9091" to default Bookmark list in Browser

diff --git a/packages/apps/Browser/res/values/strings.xml b/packages/apps/Browser/res/values/strings.xml
index 18a2144..1824664 100644
--- a/packages/apps/Browser/res/values/strings.xml
+++ b/packages/apps/Browser/res/values/strings.xml
@@ -675,6 +675,8 @@
http://www.weather.com/
BBC
http://www.bbc.co.uk/
+ Transmission
+ http://localhost:9091/


Friday, September 10, 2010

use Transmission in Android

Recently, I am checking how to use BitTorrent function in Android. There are lots of BitTorrent tools in Internet. Based on my common user experiences, I was using BitComet in Windows machine, Transmission in Ubuntu laptop, Vuze in Mac mini, and rTorrent in Debian server. I also found there are some BitTorrent remote management applications in Android market, but it's for controlling remote torrents, not directly download files via BT.

After making a survey of these BitTorrent tools, I choose Transmission, since I think porting it in Android is with less effort and more simple. I didn't build related GTK or QT code for Transmission. I'd like to use it without its own GUI. It has 'transmission-daemon' and 'transmission-remote' command line tools. I can use both of them to use Transmission without a GUI. Furthermore, it comes with a WEB UI. It means I can control BitTorrent from a browser. Therefore, I don't need to write Java UI application for it.


# export TRANSMISSION_WEB_HOME=/etc/web/transmission
# transmission-daemon -f -g /sdcard/transmission -w /sdcard/transmission --incomplete-dir /sdcard/transmission
[11:48:07.715] Transmission 2.04 (11151) started (external/transmission/libtransmission/session.c:622)
[11:48:07.727] RPC Server Adding address to whitelist: 127.0.0.1 (external/transmission/libtransmission/rpc-server.c:767)
[11:48:07.727] RPC Server Serving RPC and Web requests on port 9091 (external/transmission/libtransmission/rpc-server.c:940)
[11:48:07.727] RPC Server Whitelist enabled (external/transmission/libtransmission/rpc-server.c:944)
[11:48:07.728] DHT Generating new id (external/transmission/libtransmission/tr-dht.c:378)
[11:48:07.728] Using settings from "/sdcard/transmission" (external/transmission/daemon/daemon.c:443)
[11:48:07.728] disable save setting here! (external/transmission/daemon/daemon.c:444)
[11:48:07.728] Loaded 2 torrents (external/transmission/libtransmission/session.c:1743)
[11:48:07.728] Port Forwarding (NAT-PMP) initnatpmp succeeded (0) (external/transmission/libtransmission/natpmp.c:67)
[11:48:07.729] Port Forwarding (NAT-PMP) sendpublicaddressrequest succeeded (2) (external/transmission/libtransmission/natpmp.c:67)

I verified it in Android emulator (froyo), coz it can use local machine network. I run Transmission-daemon from the terminal. Then, I open Android Web browser and type this URL http://localhost:9091. It would go to Transmission Web UI. I can control torrent from it. Like add a BT torrent, delete torrent, pause it, check current status. The Web UI looks nice and easy to use.

How about make it more straight? I would like to search BitTorrent from application UI, not from Web browser. Then I can save some time on typing. I find a very comprehensive BitTorrent tool Transdroid in Android market . It can control remote BitTorrent and it supports Transmission too. I use it to connect my local one. It has a search function and you can also set the BitTorrent searching engine from the menu. It makes thing easier, search something, pick up a torrent, download it, and see it. There is a help guide in their web site.


These screenshots are copied from my office machine. The network environment here is bad. I cannot see good downloading speed. But I verified few torrents at my home machine, the downloading speed was over 500 KB. Also, the download speed depends on the content you are downloading too. If you search some very hot or popular things, the download speed would be very high!

I created a project android-transmission in gitoriou. If you have interests, you could use my works there.

Monday, August 2, 2010

0xdroid release beagle-eclair-0x5, devkit8k-eclair-0x5 (with/without SGX)

0xlab team is glad to announce the fifth release of 0xdroid. 0xdroid is community-developed Android distribution by 0xlab, runs on omap3 based boards include beagleboard and devkit8000.

Version: beagle-eclair-0x5-sgx, beagle-eclair-0x5-no-sgx, devkit8k-eclair-0x5-sgx, devkit8k-eclair-0x5-no-sgx

Version: beagle-eclair-0x5
Date: July 30, 2010
Release Image:
beagle-eclair-0x5_no_sgx.zip
beagle-eclair-0x5_sgx.zip
devkit8k-eclair-0x5_no_sgx.zip
devkit8k-eclair-0x5_sgx.zip
MD5 sum:
beagle-eclair-0x5_no_sgx
beagle-eclair-0x5_sgx
devkit8k-eclair-0x5_no_sgx
devkit8k-eclair-0x5_sgx


Release Details
  • Eclair codebase
  • Feature: Major Linux kernel upgrade: from 2.6.29 to 2.6.32
  • Feature: Support TI's Android PowerVR SGX (hardware 2D/3D engine)
  • Feature: Support Android USB gadget: adb and mass-storage (issue #95)
  • Note: 0xdroid no longer support usbnet gadget driver. Use adb or USB Ethernet instead.
  • Feature: new Bluetooth Extensions -- HID (issue #102)
  • Feature: Make Launcher2 really usable (issue #76)
  • Feature: Make Gallery3D workable by fixing PixelFlinger regressions (issue #107)
  • Feature: Touchscreen Calibration shouldn't require reboot (issue #94, issue #99)
  • Feature: Robocat i2c port support (issue #134)
  • Feature: Improved libgralloc for non HW accelerated target (issue #108, issue #133)

For more detail, please reference our roadmap and issues tracking

Where to download images
You can grab the image from here and following the steps described on the wiki page to test the image.

This release comes with PowerVR SGX from Texas Instruments. If you try both two images with SGX and without SGX, you would tell how amazing it displays photos in Gallery 3D application. Like ususal, it also comes with a happy Installer and it would bring you an Android Eclair system in few seconds. If you are looking for more details about the integration, you could reference to this wiki page.

How to build from scratch

$ repo init -u git://gitorious.org/0xdroid/manifest.git -b beagle-eclair
$ echo "TARGET_PRODUCT := beagleboard" > buildspec.mk
$ echo "TARGET_PRODUCT := devkit8000" > buildspec.mk ( if build for devkit8000 )
$ echo "INSTALL_PREBUILT_DEMO_APKS := true" >> buildspec.mk ( optional for adding prebuilt demo apks )
$ cd .repo/manifests/
$ git checkout -b beagle-eclair-0x5-release beagle-eclair-0x5
$ repo sync
$ repo forall -c "git checkout -b beagle-eclair-0x5-release beagle-eclair-0x5"
$ make (or make -j4 if there are 4 cores)