Sunday, December 27, 2009

Android Bluetooth in Eclair


If you noticed the source code in Eclair branch, you will find few differences in Bluetooth function. There are three new git repositories for bluetooth. "bluez", "glib" and "hcidump", all of them are located in /external/bluetooth folder, not /external/bluez anymore.

bluez
android source: git://android.git.kernel.org/platform/external/bluetooth/bluez.git
Eclair is using bluez version 4.47 and the big difference would be bluez API. Since it has a lot of changes between bluez3 (android 1.6) and bluez4 (Android 2.0), we can tell from the documents in doc folder. Or we can use dbus-send to get the detailed information.



# dbus-send --system --type=method_call --print-reply --dest=org.bluez / org.bluez.Manager.DefaultAdapter
method return sender=:1.2 -> dest=:1.3
object path "/org/bluez/932/hci0"

# dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/932/hci0 org.freedesktop.DBus.Introspectable.Introspect


Also, bluetooth service name is changed in Eclair. It's "bluetoothd" now. Check init.rc in /system/core/rootdir.


service bluetoothd /system/bin/bluetoothd -d -n
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 bluetoothd drop uid to bluetooth with the right linux capabilities
group bluetooth net_bt_admin misc
disabled

glib
android source: git://android.git.kernel.org/platform/external/bluetooth/glib.git
When we build bluez library, it would build glib as a static library.
GLib provides the core application building blocks for libraries and applications written in C. It provides the core object system used in GNOME, the main loop implementation, and a large set of utility functions for strings and common data structures. If you are interested in how bluez use glib, you can trace bluez source code.

new Bluetooth API
http://developer.android.com/guide/topics/wireless/bluetooth.html
About Bluetooth, Android website has a very good document. It lists the functions and example code.


Bluetooth
* Turn on/off Bluetooth
* Device and service discovery
* Connect to a remote device using RFCOMM and send/receive data
* Advertise RFCOMM services and listen for incoming RFCOMM connection


Bluetooth Chat application
What I am curious? It's related to using RFCOMM and send/receive data. In the beginning, I am not quite understand and I thought it's OBEX. After running Bluetooth Chat application, I know what it means now. I installed 0xlab experimental eclair image in Beagle board and installed Bluetooth chat example from Android. I also run a python script in my ubuntu machine and it's from pybluez. Then, I can chat between Beagle board and my laptop via Bluetooth. When we start to run Bluetooth Chat application, it would create a RFCOMM socket and set it to listen mode. We can retrieve the information from sdptool. Then other BT devices can connect to Android using RFCOMM protocol and set channel to the same one.


# sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
Service Name: BluetoothChat
Service RecHandle: 0x10005
Service Class ID List:
UUID 128: fa87c0d0-afac-11de-8a39-0800200c9a66
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 30


From Collages

Friday, December 18, 2009

0xdroid beagle-donut-0x3 is released now!

So exciting is our brand new release called '0xdroid beagle donut-0x3' that we forgot all about the coming bad weather in Taipei (raining, humid, and chill). This is our third released image for Beagle board in Android and it's based on Donut branch. If you have a beagle board on hand, you may give it a try. We provide a 'Happy installer' tool and it could give you a 'no pain no tears' good experiences on installing Android. Here is a 2 minutes video in youtube based on real booting time! If you don't have any beagle board to see our work, you could take it a look from our released videos in youtube.


What kind of meat we have this time?

Easy access to Internet through USB OTG network routed via host
  • Ethernet support + USB OTG network with default static IP configurations ...
Performance improvements
  • Dalvik VM + JIT compiler for ARMv7 ...
  • ARM NEON optimizations for PixelFlinger ...
Theme Flexibility
  • Theme selector introduced ...
  • Flexible resolution support for Launcher ...
More and better peripheral support
  • External GSM modem for functional Android Telephony/RIL ...
  • Bluetooth OBEX OPush and FTP support ...
  • Motion sensor support ...
  • Camera capture / recording ...
Stability improvements with several issues fixed
  • Dalvik stability fix ...
  • Wifi signal strength with Linux Wireless Extension fix ...
  • Mouse stability fix ...
Here is our Roadmap about all these releases. If you have interest on particular item, you could get more information from our issue tracker. Furthermore, we welcome your feedback or any suggestion on 0xlab-devel mailing list!

Frankly speaking, my favorite feature in this released image is neither Bluetooth Obex nor GSM modem, what I like most is our theme launcher. It has a Christmas theme inside. This theme is our best wishes. Wish everyone have a Merry Christmas and a Happy New Year!



Tuesday, December 1, 2009

Provide Bluetooth FTP profile in Android

About providing Bluetooth FTP & OPP profile issue, I've merged all related source code to 0xdroid begle-donut branch. I verified these two services in both Beagle board and Android Dev phone. It looks good now.

When we turn BT on, we start 'obex-client' service in the background. It would register a record to SDP server in bluez and then other BT devices can find we provide this service. How it looks like? We provide channel 7 for FTP. Other BT device can browse our file system using rfcomm. They can pull data from us, modify file name, delete file, or push data to us. Below it's FTP record in SDP database:


Service Name: File Transfer server
Service RecHandle: 0x10003
Service Class ID List:
"OBEX File Transfer" (0x1106)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 7
"OBEX" (0x0008)
Profile Descriptor List:
"OBEX File Transfer" (0x1106)
Version: 0x0100





Let's explain it and trace the source code.
Eg. CreateSession method call in obex-client dbus API

How we connect obex-client with Bluetooth UI? [using JNI, aidl, and d-bus]
We register a FTP service from AndroidRuntime. We also create few methods and it's based on obex client API document. Below texts are related source code:

AndroidRuntime.cpp

REG_JNI(register_android_server_BluetoothFtpService),

android_server_BluetoothFtpService.cpp

int register_android_server_BluetoothFtpService(JNIEnv *env)
{
jclass clazz = env->FindClass("android/server/BluetoothFtpService");

method_onCreateSessionComplete = env->GetMethodID( clazz, "onCreateSessionComplete", "(Ljava/lang/String;Ljava/lang/String;Z)V" );
method_onChangeFolderComplete = env->GetMethodID( clazz, "onChangeFolderComplete", "(Ljava/lang/String;Ljava/lang/String;Z)V" );

return AndroidRuntime::registerNativeMethods(env,
"android/server/BluetoothFtpService", sMethods, NELEM(sMethods));
}


Below text is the sequence from UI to native code and then back to UI.

RemoteFileManagerActivity.java (Pick up one device from remote tab in Bluetooth UI)

public boolean onOptionsItemSelected(MenuItem item) {
// Intent intent;
switch (item.getItemId()) {
case MENU_SELECT_SERVER:
if (mFTPClient.isConnectionActive()) {
Toast.makeText(this, R.string.error_ftp_connect_timeout, Toast.LENGTH_LONG).show();
} else {
/* Connect to Server */
handleServerSelect();
}

public void handleServerSelect() {
mDirectoryButtons.removeAllViews();
currentDirectory = "/";
if (mContext.isBluetoothEnabled()) {
Intent intent = new Intent(getApplicationContext(), BluetoothDevicePicker.class);
intent.setAction(BluetoothAppIntent.ACTION_SELECT_BLUETOOTH_DEVICE);
intent.putExtra(BluetoothAppIntent.PROFILE, BluetoothAppIntent.PROFILE_FTP);
intent.setData(Uri.parse("file://" + currentDirectory));
try {
startActivityForResult(intent, SUBACTIVITY_PICK_BT_DEVICE);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "No Activity for : " + BluetoothAppIntent.ACTION_SELECT_BLUETOOTH_DEVICE, e);
}
}
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

switch (requestCode) {
case SUBACTIVITY_PICK_BT_DEVICE:
if (resultCode == RESULT_OK && data != null) {
/* Obtain the Server name and Address */
String serverAddress = data.getStringExtra(BluetoothDevicePicker.ADDRESS);
String serverName = data.getStringExtra(BluetoothDevicePicker.NAME);
if (mFTPClient != null) {
mFTPClient.setAddress(serverAddress);
mFTPClient.setName(serverName);
mServerConnectButtonLayout.setVisibility(View.GONE);
if(mFTPClient.createSession() != true) {
String szStr = getResources().getString(R.string.ftp_connect_failed, mFTPClient.getName());
Toast.makeText(this, szStr, Toast.LENGTH_LONG).show();
updateServerStatus();
} else {
String szStr = getResources().getString(R.string.ftp_connect_device, mFTPClient.getName());
showBusy(mFTPClient.getName(), szStr);
}
}
}
break;
}
} /* onActivityResult */

BluetoothFtpService.java (handle from Android Frameworks)

public synchronized boolean createSession(String address, IBluetoothFtpCallback callback) {
/*
* Need to register callback before calling native code
* (which could potentially call callback)
*/
BluetoothObexDatabase.SessionDbItem dbItem =
mSessionDb.new SessionDbItem(address,null,callback);
mSessionDb.insert(dbItem);

boolean ret = createSessionNative(address);

if (!ret) {
mSessionDb.deleteByAddress(address);
}

return ret;
}

android_server_BluetoothFtpService.cpp (use JNI and send a dbus method call to obex-client)
 
static jboolean createSessionNative(JNIEnv* env, jobject object, jstring address )
{
DBusMessage *msg = dbus_message_new_method_call(OBEXD_DBUS_CLIENT_SVC,
OBEXD_DBUS_CLIENT_PATH,
OBEXD_DBUS_CLIENT_IFC,
OBEXD_DBUS_CLIENT_CREATE);

pending = (dbus_async_call_t *) malloc(sizeof(dbus_async_call_t));
if (pending)
{
DBusPendingCall *call;
char *context_address = (char *) calloc(BTADDR_SIZE,
sizeof(char));
strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
pending->env = env;
pending->user_cb = onCreateSessionComplete;
pending->user = context_address;
pending->nat = nat;
dbus_bool_t reply = dbus_connection_send_with_reply(nat->conn,
msg,
&call,
10*1000);

/external/obexd/client/main.c (handle from obex-client)

static DBusMessage *create_session(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
if (session_create(source, dest, target, create_callback, data) == 0)
return NULL;

/external/obexd/client/session.c (use rfcomm to connect with specific channel )

int session_create(const char *source,
const char *destination, const char *target,
session_callback_t function, void *user_data)
{
if (session->channel > 0) {
err = rfcomm_connect(&session->src, &session->dst,
session->channel, rfcomm_callback, callback);

android_server_BluetoothFtpService.cpp (we get the callback!)
 
static void onCreateSessionComplete(DBusMessage *msg, void *user, void *nat_cb)
{
char* c_address = (char *)user;
JNIEnv *env = NULL;
nat->vm->GetEnv((void**)&env, nat->envVer);
jstring address = env->NewStringUTF(c_address);

env->CallVoidMethod(nat->me,
method_onCreateSessionComplete,
obj_path,
address,
is_error);

BluetoothFTPClient.java (handle from Bluetooth UI)

public void onCreateSessionComplete(boolean isError) {
Message msg = Message.obtain();
msg.what = TYPE_CREATE_SESSION_COMPLETE;
Bundle b = new Bundle();
b.putBoolean("isError", isError);
msg.obj = b;
mHandler.sendMessage(msg);
}


RemoteFileManagerActivity.java (device is connected, going to refresh panel to display Remote file system)

public void onCreateSessionComplete(boolean isError) {
mSessionCreated = !isError;
hideBusy();
if (mFTPClient != null) {
if (isError == false) {
mContext.onServerConnected();
goHomeDir();
} else {
String szStr = getResources().getString(R.string.ftp_connect_failed, mFTPClient.getName());
Toast.makeText(this, szStr, Toast.LENGTH_LONG).show();
}
}
updateServerStatus();
refreshDirectoryPanel();
}

Tuesday, November 24, 2009

Radio Layer Interface in Android

There is a Radio Layer Interface in Android and it is about telephony service. Like my previous article, I was working on using an external GSM modem in Beagle board. Currently, I am using it to verify telephony service and I can trace the whole log between framework (Telephony service) and ril-daemon. It is the real GSM network and then I can trace the traffic between modem and GSM base station.

Here is some RIL information from Android Platform Development Kit.




RIL Initialization


Android initializes the telephony stack and the Vendor RIL at startup as described in the sequence below:

RIL daemon reads rild.lib path and rild.libargs system properties to determine the Vendor RIL library to use and any initialization arguments to provide to the Vendor RIL
- these arguments are from /system/build.prop
eg.
rild.libpath=/system/lib/libreference-ril.so
rild.libargs=-d /dev/pts/0

RIL daemon loads the Vendor RIL library and calls RIL_Init to initialize the RIL and obtain a reference to RIL functions
- open modem device
- connect with telephony service (Android Frameworks)

RIL daemon calls RIL_register on the Android telephony stack, providing a reference to the Vendor RIL functions
- start listen socket (SOCKET_NAME_RIL = rild)
- set ril event to listenCallback function



Below text is from radio log and we can see the sequence:

I/RIL ( 954): Opening tty device /dev/pts/0
D/AT ( 954): entering mainLoop()
I/RILJ ( 820): Connected to 'rild' socket
I/RILC ( 954): libril: new connection
D/RILC ( 954): [UNSL]< UNSOL_RESPONSE_RADIO_STATE_CHANGED {RADIO_UNAVAILABLE}
D/RILJ ( 820): Radio OFF @ init
D/RILJ ( 820): [UNSL]< UNSOL_RESPONSE_RADIO_STATE_CHANGED RADIO_UNAVAILABLE
I/RILC ( 954): RIL Daemon version: android reference-ril 1.0
D/AT ( 954): AT< AT-Command Interpreter ready
D/RILC ( 954): [UNSL]< UNSOL_RESPONSE_RADIO_STATE_CHANGED {RADIO_OFF}
D/AT ( 954): AT> ATE0Q0V1
D/AT ( 954): ATE0Q0V1
D/RILB ( 820): Notifying: radio available

RIL Interaction

There are two forms of communication that the RIL handles:


Solicited commands: Solicited commands originated by RIL lib, such as DIAL and HANGUP.

The vendor RIL must provide the functions described in the table below to handle solicited commands. The RIL solicited command request types are defined in ril.h with the RIL_REQUEST_ prefix. Check the header file for details.

eg. ask GSM network signal strength

Send a request from framework (telephony service) to GSM modem (ril-daemon)

D/GSM ( 791): EVENT_POLL_SIGNAL_STRENGTH
D/RILJ ( 791): [0048]> SIGNAL_STRENGTH
D/RILJ ( 791): send rr to ril-daemon...
D/RILJ ( 791): [0048]> SIGNAL_STRENGTH
D/RILJ ( 791): EVENT_SEND 001
V/RILJ ( 791): writing packet: 8 bytes
D/RILC ( 943): [0048]> SIGNAL_STRENGTH
D/RIL ( 943): onRequest: SIGNAL_STRENGTH
D/AT ( 943): AT> AT+CSQ
D/AT ( 943): AT+CSQ
D/AT ( 943): +CSQ: 20,99
D/AT ( 943): OK
D/AT ( 943): AT< +CSQ: 20,99
D/AT ( 943): AT< OK
D/RILC ( 943): [0048]< SIGNAL_STRENGTH {[ 20 99]}
V/RILJ ( 791): Read packet: 40 bytes
D/RILJ ( 791): [0048]< SIGNAL_STRENGTH {20, 99, 0, 0, 0, 0, 0}
D/GSM ( 791): EVENT_GET_SIGNAL_STRENGTH
D/GSM ( 791): [PhoneNotifier] notifySignalStrength
D/GSM ( 791): GSMPhone getSignalStrength


Unsolicited responses: Unsolicited responses that originate from the baseband, such as CALL_STATE_CHANGED and NEW_SMS.

eg. Receive an incoming call (from ril-daemon to telephony service)

D/AT ( 943): RING
D/AT ( 943): AT< RING
D/RILC ( 943): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED
V/RILJ ( 791): Read packet: 8 bytes
D/RILJ ( 791): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED
D/GSM ( 791): [GsmCallTracker] checkNoOperationsPending: pendingOperations=0
D/RILJ ( 791): [0283]> GET_CURRENT_CALLS
D/RILJ ( 791): send rr to ril-daemon...
D/RILJ ( 791): [0283]> GET_CURRENT_CALLS
D/RILJ ( 791): EVENT_SEND 001
V/RILJ ( 791): writing packet: 8 bytes
D/RILC ( 943): [0283]> GET_CURRENT_CALLS
D/RIL ( 943): onRequest: GET_CURRENT_CALLS
D/AT ( 943): AT> AT+CLCC
D/AT ( 943): AT+CLCC
D/AT ( 943): +CLCC: 1,1,4,0,0,"0952123687",129,"808
D/AT ( 943): 42C771F"
D/AT ( 943): OK
D/AT ( 943): AT< +CLCC: 1,1,4,0,0,"0952123687",129,"80842C771F"
D/AT ( 943): AT< OK
D/RILC ( 943): [0283]< GET_CURRENT_CALLS {[id=1,INCOMING,toa=129,norm,mt,als=0,voc,noevp,0952082687,cli=0,name='(null)',0}
V/RILJ ( 791): Read packet: 88 bytes
D/RILJ ( 791): InCall VoicePrivacy is disabled
D/RILJ ( 791): [0283]< GET_CURRENT_CALLS [id=1,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,0]


PS. tag information
RIL: /hardware/ril/reference-ril/refereince-ril.c
AT: /hardware/ril/reference-ril/atchannel.c
RILD: /hardware/ril/rild/rild.c
RILC: /hardware/ril/libril/ril.cpp
RILJ: /frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java
GSM: /frameworks/base/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java

Thursday, November 19, 2009

Pick up the phone in Beagle board

I just uploaded two videos about using NEO as external GSM modem in Beagle board. We were trying to make both MT and MO phone call in Beagle board. Since we'd like to hear something during the phone call, I set it to SPEAKER mode in Android Dev phone. Therefore, we can hear what we speak in NEO and also hear some annoyed ECHO sound. Sorry for this....



Friday, November 6, 2009

External GSM modem in Beagle board

My friend Tick just migrated 0xdroid to beagle-donut branch and then I go back to work on external GSM modem issue in Beagle board. This time I tried to connect two devices from my working Ubuntu machine via two USB cables. It becomes very easy to debug and trace the behaviour between GSM modem and Beagle board. I set up an ethernet bridge in Ubuntu machine (192.168.0.200) and two USB networks. One is to connect with NEO phone (192.168.0.202) and the other is to connect with Beagle board (192.168.0.201). All of these three devices can see each other. Therefore, I can use ssh or adb shell to control them.





GSM modem is a device "/dev/ttySAC0" in NEO GTA02 phone and I use netcat to make it be listened in port 4270. This modem becomes 192.168.0.202:4270 now. How to make Android to see it? I use a pty small program from OpenedHand. It's like a pseudo terminal and it can reads and writes to the socket. Running it can make GSM modem become a device "/dev/pts/0" in Android. After starting ril-daemon service, it would connect to GSM modem. Then, everything is like usual. We can camp to GSM network and can dial out a phone call.
I am going to close this issue and then file other issues about ril problems later.

Saturday, October 31, 2009

Download Bluetooth OBEX UI from CyanogenMod

I am very glad CyanogenMod use Bluetooth OBEX support in their new released ROM image "version 4.2.3.1". If you'd like to try this feature, you could flash with their Android image. Also, you can use CM updater to keep tracing with their works!

Monday, October 26, 2009

how to have OBEX function in Android?

Few months ago, I was working on porting openobex, obexpushd and obexftp in Android. They are using commands and I don't have any UI application to use. It's not that convenient for common users. My friend jserv sent me a link in September, then I found there is a Bluetooth UI application about OPUSH/FTP profiles from Aurora forum. Therefore, I started to work on it.

At first, we should prepare Android building environment and I am using Donut branch now. My target is Android Dev phone. I can build the images for this device and flash with my images successfully. If you are familiar with Android building environment, you can use my works as below:

(1) Android frameworks
base: http://android.git.kernel.org/?p=platform/frameworks/base.git;a=shortlog;h=refs/heads/donut
my work: http://androidobex.googlecode.com/files/0001-apply-Bluetooth-FTP-OPP-patch-from-aurora.patch

(2) Blueooth UI application patch from Aurora forum
base: https://www.codeaurora.org/gitweb/quic/la/?p=platform/packages/apps/Bluetooth.git;a=shortlog;h=refs/heads/donut_glazed
my work: http://androidobex.googlecode.com/files/0001-Modify-OBEX-received-file-path-to-sdcard-and-set-de.patch

(3) init.rc script patch
base: http://android.git.kernel.org/?p=platform/system/core.git;a=shortlog;h=refs/heads/donut
my work: http://androidobex.googlecode.com/files/0001-Add-obexd-and-obex-client-service.patch

(4) bluedroid patch
base: http://android.git.kernel.org/?p=platform/system/bluetooth.git;a=shortlog;h=refs/heads/donut
my work: http://androidobex.googlecode.com/files/0001-add-obexd-obex-client-service-start-and-stop.patch

(5) obexd (i use obexd-0.10 version)
http://gitorious.org/android-obex/obexd

(6) glib (i use glib-2.13.0 version)
http://gitorious.org/android-obex/glib

(7) bluez patch
base: http://android.git.kernel.org/?p=platform/external/bluez.git;a=shortlog;h=refs/heads/donut
from aurora: https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/bluez.git;a=commit;h=c2fdca9be6ac9625c229728d83c9ca3b26b64bba

(8) openobex (i use openobex version 1.5)
http://gitorious.org/android-obex/openobex

Sunday, October 25, 2009

Android Bluetooth UI application from Aurora

Finally, I can use a friendly UI application in Android and it allows to use Bluetooth OPUSH/FTP profiles. I was working on porting obexd and merged some patches from Aurora forum to Donut tree. Here is a discussion in 0xlab-devel mailing list about OBEX integration in 0xdroid.

How is this Bluetooth UI application and what I can do? let's check some screen shots! Some examples between my nokia N73 phone and Android Dev phone.

Connect to other Bluetooth devices from G1
* scan nearby devices from Remote tab
* pair with it
* connect to it



Pull file from other Bluetooth device from G1
* explore file manager from Remote tab
* download an image file
* open it from Local tab



Push file from G1 to other Bluetooth device
* open Local tab
* choose a file
* send it out



Receive a vcard from other Bluetooth device to G1
* bluetooth authorize dialog
* accept a *.vcf file?
* press OK, it would store to Contact
* open Contact




Receive a mp3 file from other Bluetooth device to G1
* bluetooth authorize dialog
* accept a *.mp3 file?
* press OK, it would store to sdcard
* open Music


Sunday, September 13, 2009

Android Bluetooth Introduction

Check out this SlideShare Presentation :)

Tuesday, September 8, 2009

Android ROM images from community

When I got the Android Dev phone, I download the official Android images from HTC site. Sometimes I build some packages myself, then upload them to ADP. Yesterday, I started to try Android images from community. I am so surprised that I can see so many different and versatile images. Their images are even based on the newest Android code. jserv gave me a link that someone is using my work "android obex" in their Android images about two weeks ago, but I didn't figure it out. I was trying to find out how HTC HERO users can get root access and how I can flash Android images from community. I tried to flash about 5 different images and played all day long. Too interesting to quit...:D

Here is a very detailed table chart and it shows kinds of Android images. I can pick one based on its status, like kernel version, WiFi or BT status, what input method, or application status....etc.

The first image I tried is from CyanogenMod. I downloaded this image file and push it to /sdcard in ADP. We can enter into 'Recovery' mode to update this image.

I also found there is 'cyanogen-updater' application in Android Market. I can install it in ADP and then I can update with their newest image version. It can download ROM image and update it in Recovery mode automatically. After rebooting it, I found it has bluez utils and my obex stuff inside. It means users needn't download hidd, hcitool, or those binary files, and they needn't build those stuff themselves either. I think that is better for normal and common users. Some of my friends, they don't even know what Android phone is, but they know how to use Facebook, how to use Internet. If they buy an Android phone someday, they can use this application to flash image without pain or tears. How cool it is!

Furthermore, I found Chinese Input mothod in another Android image. It's my first time to try this HTC Chinese input method. I used handwriting method to write words and it's pretty good to use. It can recognize all my writings. I thought I would need a cell phone with qwerty keyboard, but now I think that I can use touch input as well. XD

Sunday, September 6, 2009

Android emulator + external GSM modem

Recently, I am working on this issue 'Use GTA02 GSM Passthrough mode as external Android GSM modem' and the goal is to use Beagle board as a platform. Since we are still using cupcake in beagle board, I choose to use Android emulator with latest donut in the beginning. When we have donut image in beagle board, i will switch it on that time.

In Android emulator, it would use a qemud socket as GSM modem and it can simulate GSM network. Like camp to GSM base station (Android 3G :P), receive incoming call, dial out a phone call, has a simulated SIM Card, send SMS messages....etc. In my previous article about tracing RIL, I tried to run two emulators and made a phone call to each other. It's pretty fun, coz it can simulate real GSM network.

But it's still a fake one, not real GSM network, it doesn't camp to the nearby network like your mobile does. Therefore..... I changed few lines and made Android emulator to run an external GSM modem. Here is my experiment!



rild: allow it to use other GSM device in qemu

diff --git a/rild/rild.c b/rild/rild.c
index 14a6ea9..bd91314 100644
--- a/rild/rild.c
+++ b/rild/rild.c
@@ -161,7 +161,7 @@ int main(int argc, char **argv)
}
close(fd);

- if (strstr(buffer, "android.qemud=") != NULL)
+ if (strstr(buffer, "android.qemud=") == NULL)
{
/* the qemud daemon is launched after rild, so
* give it some time to create its GSM socket


Modify rild lib argument and change device name

diff --git a/target/board/generic/system.prop b/target/board/generic/system.prop
index f2424c9..1b84596 100644
--- a/target/board/generic/system.prop
+++ b/target/board/generic/system.prop
@@ -3,4 +3,4 @@
#

rild.libpath=/system/lib/libreference-ril.so
-rild.libargs=-d /dev/ttyS0
+rild.libargs=-d /dev/ttyS2


GTA02 NEO phone

erin@daydreamer:~$ sudo ifconfig usb0 192.168.0.200
erin@daydreamer:~$ ssh root@192.168.0.202
root@om-gta02:~# echo 1 > /sys/devices/platform/neo1973-pm-gsm.0/power_on
root@om-gta02:~# echo ate1 | ./tickminicom
root@om-gta02:~# nc -l -p 4270 < /dev/ttySAC0 > /dev/ttySAC0 &

PS. tickminicom is here

Running pty in host machine

# ./pty 192.168.0.202 4270

PS.1 where is pty? how do I know it? it's from Thomas! I was co-working with him about gsmd and dialer UI in 2007.

Running emulator with serial port option

erin@daydreamer:~/android/mydroid_emu/out$ ./host/linux-x86/bin/emulator -system ./target/product/generic/system.img -sysdir ./target/product/generic/system -data ./target/product/generic/userdata.img -kernel ../prebuilt/android-arm/kernel/kernel-qemu -ramdisk ./target/product/generic/ramdisk.img -qemu -serial /dev/pts/2


Cannot receive any incoming call
I was stuck on this case and it would send hangup command to any incoming calls without any notification UI. I found this issue is a known one and we can set 'Settings.Secure.DEVICE_PROVISIONED' to 1. Then no problem now.

What it can do now?
* Camp to GSM network
* Dial out a phone call
* Receive an incoming call
* Send SMS
* Receive SMS

Wednesday, September 2, 2009

Connect Bluetooth Keyboard in Android Dev Phone

I have an Apple Wireless Keyboard and how do I connect it with G1 or any Android phones? I am using Android Dev Phone for my example, so I already have its root permission. If you are using other Android phone, not ADP, you have to get root permission first!! BTW, my working machine is Ubuntu 9.04!

Download related bluetooth utilities here or build it yourself!

$ wget http://androidobex.googlecode.com/files/hciconfig
$ wget http://androidobex.googlecode.com/files/hcitool
$ wget http://androidobex.googlecode.com/files/hidd


Change mount and folder permission in Android Dev Phone

$ su
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
# chmod 777 /system/xbin


Upload related bluetooth utilities to Android Dev phone

$ adb push hidd /system/xbin
$ adb push hcitool /system/xbin
$ adb push hciconfig /system/xbin


Turn Bluetooth ON from Setting UI and click 'Scan for devices'



Press 'Apple Wireless Keyboard' and it would appear Pair request



Type '0000' or '1111' as pin code and it would appear 'Paired but not connected'




Let's type some bluez utilities commands to make it work!

# hciconfig
hci0: Type: UART
BD Address: 00:22:A5:B8:AD:65 ACL MTU: 1021:4 SCO MTU: 180:4
UP RUNNING PSCAN
RX bytes:8672 acl:98 sco:0 events:285 errors:0
TX bytes:3336 acl:102 sco:0 commands:89 errors:0

# hcitool dev
Devices:
hci0 00:22:A5:B8:AD:65

# hcitool scan
Scanning ...
00:1D:4F:A7:9A:49 Apple Wireless Keyboard
00:22:43:C6:5B:B9 daydreamer-0
00:18:C5:42:18:78 Erin-Nokia N73

# hidd --connect 00:1D:4F:A7:9A:49

# hcitool con
Connections:
< ACL 00:1D:4F:A7:9A:49 handle 1 state 1 lm MASTER



DONE! I can connect to Bluetooth Keyboard in Android. It's more convenient when I type email, message, or chat with friends now!

Monday, August 24, 2009

0xlab in COSCUP 2009

What is COSCUP? (Conference for Open Source Coders, Users and Promoters) It's a big event for Open Source group in Taiwan. It has become an annual festival for open source community members around Taiwan. This year it hold on August 15-16 in NTU. 0xlab has the great pleasure to become the sponsor and we are so happy to contribute 4 talks and one lightning show! :D

Unfortunately, I only found three talks in YouTube and missed two talks (olv and walkingice). We will try to provide their pretty slides online later. If you have interests about our talks, you may check these videos in YouTube. haha, our team member jserv is quite famous in Taiwan FOSS community. His talk in COSCUP 2009 is the most funny and most popular one. It's not easy to make people laugh on hard topic like 'Linux Virtualization Goes Mobile'. XD

let's discuss more with 0xlab!



I am very glad that 0xlab created two mailing lists for community. We would like to see more people here. If you could drop us a line or few notes about our works, or express your idea about Android, it would be terrific! I am going to close my comment board in this tiny blog, since we have a better one. :P

Currently we have two mailing lists in Google groups website. 0xlab-discuss is for general discussion and 0xlab-devel is for development related topics. Please come to visit us!!

There are some different methods to join it.

Visit online: you can read all posts in Google group website.
http://groups.google.com/group/0xlab-devel?hl=en
http://groups.google.com/group/0xlab-discuss?hl=en

Subscribe it: you can join our groups and read groups from your email. Also, you can post message to the group from your email too!

Available feeds: The feeds allow you to read new topics or new messages from this group with any feed reading software. For example, Bloglines, Google Reader, or Firefox RSS....

PS. you will need to create a google account to use Google Groups!

Tuesday, August 18, 2009

oh...my God! Happy Installer!


Our team member jserv provides a very convenient 'Installer' tool and it's for beagle board + Android. What I need is one SD card and download three image files from 0xlab site. Just spend me two minutes and then I can play Android on beagle board.





1. Download images from 0xlab website

- wget http://downloads.0xlab.org/installer/beagle-cupcake-0x1/uImage.bin (installer itself)
- wget http://downloads.0xlab.org/release/beagle-cupcake-0x1/0xkernel-beagle.bin (kernel image)
- wget http://downloads.0xlab.org/release/beagle-cupcake-0x1/android-beagle.ubi (android image)

2. Prepare a SD card

- Format the first partition over than 100MB with VFAT on a SD card. (howto format)
- Copy those three image files into the first partition of SD/MMC card

3. Boot it with beagle board

- Plug the SD card in beagleboard SD slot and restart the beagleboard
- Wait for UI installer over
- Erase NAND flash with those three images
- Done

4. Reboot beagle board without SD card

- start to run Android system
- Enjoy!

PS. we provide daily build images as well. You may rename the image file and copy it to SD card.

PS1. here is a 2 minutes video in youtube based on real booting time!

Tuesday, August 4, 2009

[video] Listen FM radio in Android

Listen FM radio in Android


I started to work on beagle board from July and it's a low power OMAP3 based platform. My friend Tick is hacking it with Android recently. Therefore, it's very easy for me to pick up Android stuff in beagle board based on his work.

Since i am working on beagle board with Android, I need to use a lot of cable lines around it. Eg. HDMI cable, USB hub, USB keyboard, USB mice, speaker, mini USB cable and a bluetooth board. Those lines occupy my desk and my mind! Actually, I am checking Broadcom 4325 solution, it combines Bluetooth, Wi-Fi and FM radio functionality on a single-chip design. Yup! It means we can listen to FM Radio in Android. That is the one to keep me busy in July. :D

Here is a simple FM Radio application. It allows me to adjust FM frequency, preset few radio stations, mute/unmute, and auto scan....etc. I will make a video about FM radio later. The best scenario is browsing internet with WiFi, listen mp3 from a bluetooth speaker, and also listen FM radio from screen speaker by this tiny combo chip. And, it works!

PS. FM 99.7 is a classical radio station in Taiwan and it's my favorite one!