Saturday, March 5, 2011

Dalvik ByteCode Injection

phew! been a really long time since the last post. I sort of stopped working on the VoIP idea.

What's new is dalvik bytecode injection. I managed to inject instructions in memory for an Android app.

http://groups.google.com/group/android-platform/browse_thread/thread/21549d6f3228eb50

According to Andy McFadden (the guy who wrote much of the VM), I am most probably the first person to do this. Encouraged, I am starting a project to have a comprehensive injection library for Dalvik.

This is the Issue tracker of Android that is currently active with the discussion
http://code.google.com/p/android/issues/detail?id=6322

Cheers,
Earlence

Friday, October 16, 2009

My Latest Work

Well, I've been really caught up with my day job. So I've had no time to continue my Android VoIP experimentation, but I will try to complete a working prototype the moment I get a little slack from my job. So till the next post...

Thursday, July 23, 2009

Writing applications using the Android NDK

I did not find any easy to read tutorials on how to exactly build an Android app with some native code component. Its true that the NDK package comes with some docs, but for Android beginners, this may not be an exciting prospect. However, I still maintain that the docs in the package are a must-read.

The following app simply prints out a small string returned from a C function on the LogView.

1. Create a Normal Android app. Lets call it 'native1'.
2. The main source file should look like this.


package com.earl.native1;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class native1 extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Log.i("--EARL--", new NativeLib().getHelloWorld());
}
}

class NativeLib
{
public native String getHelloWorld();

static {
System.loadLibrary("helloworld");
}

}



3. If you are using Eclipse, the class files built will be in the 'bin' directory.
4. Navigate to it and run 'javah' on the class file that contains the native method.

javah -jni com.earl.native1.NativeLib

5. After this, you will get one header file. This file contains the JNIEXPORTs generated from the java source.
6. Copy this file and paste it in a folder in the 'sources' dir of the Android NDK. I'm calling the folder 'earl'.
7. Now, create the C implementation file - earl.c It should look like this.


#include "com_earl_native1_NativeLib.h"

JNIEXPORT jstring JNICALL Java_com_earl_native1_NativeLib_getHelloWorld
(JNIEnv * env, jobject obj)
{
return (*env)->NewStringUTF(env, "Greetings from Earlence !");
}



8. Now you have to create the Android.mk file. This file describes your native code module to the build system. This file is created in the same dir as the source file.



# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := helloworld
LOCAL_SRC_FILES := earl.c

include $(BUILD_SHARED_LIBRARY)




9. Now, navigate to the 'apps' dir in the NDK home and create a folder of your choice. This will hold the Android Application you built using Eclipse earlier. I am calling it earl_jni. In this folder, create another one and call it 'projects'. In this, copy your ENTIRE eclipse project 'native1'. Then, navigate one level up to earl_jni and create the Application.mk file.



APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := helloworld



10. Now, navigate to the NDK home and run the make command.

$ make APP=earl_jni

11. You should see this output if everything works correctly.


Android NDK: Building for application 'earl_jni'
Compile thumb : helloworld <= sources/earl/earl.c
SharedLibrary :
libhelloworld.so
Install : libhelloworld.so => apps/earl_jni/project/libs/armeabi


12. Now, a folder called 'libs' will be created in apps/earl_jni/projects. This contains the .so file i.e the native library. Copy this into the eclipse project root. Compile and run. You should see something like on the LogView


I/ActivityManager( 564): Starting activity: Intent { action=android.intent.acti
on.MAIN categories={android.intent.category.LAUNCHER} flags=0x10200000 comp={com
.earl.native1/com.earl.native1.native1} }
I/--EARL--( 699): Greetings from Earlence !
I/ActivityManager( 564): Displayed activity com.earl.native1/.native1: 704 ms


Congratulations!!! You have just built your first JNI app for Android.





Installing Android NDK on Windows XP/Vista

What you need:

  • A Windows XP/Vista computer (yeah, u absolutely need it :)).
  • cygwin (make sure that make and gcc utilities are installed).
  • Android SDK 1.5
Steps to install:

  • Download the NDK from the Android developer site and unpack it to a disk location. I'm calling this NDK_HOME.
  • Startup cygwin and navigate to NDK_HOME.
  • Enter this command
  • export ANDROID_NDK_ROOT=NDK_HOME (note, use forward slashes '/' instead of the usual windows backslash. Remember that you are using a Linux emulation tool!).
  • Run this setup command.
  • bash build/host-setup.sh
  • You should get a "Host Setup Complete" message if everything went properly.
You're done.

Tuesday, July 21, 2009

NAT Traversal for Android

STUN (Simple Traversal of User Datagram Protocol through Network Address Translators) is a protocol that helps in the traversal of NATs/Firewalls. STUN works with full cone NAT, restricted cone NAT, and port restricted cone NAT. It does not work with Symmetric NATs. Traversal Using Relay NAT(TURN) maybe used in these cases. Another method for traversal is ICE (Interactive Connectivity Establishment). Here, I am focusing on NAT traversal for Android phones using STUN

  • jStun
  • stun4j
These are two STUN libraries available for the Java language. A jStun port is available from HSC. I've tested this on the Android Emulator. It returns an IP address and port mapping.

stun4j is another STUN library. This I tried directly on the Android emulator with no porting. It works directly with no code changes. I have compared results from both the libraries. Results are the same!!!


Monday, July 20, 2009

Real Time Audio Streaming for Android - Some Developments

OK, so I've made some progress on this project.

  • I have figured out how the Audio Streaming APIs work on the 1.5 SDK.
  • I have obtained a G 711 speech codec in Java which runs on Android. This was taken from the 'sipdroid' VoIP client.
  • I have been able to stream a pre-recorded PCM voice file to the emulator via UDP and play it using AudioTrack.
  • I have figured out how to use the jLibRtp RTP stack in a Java program. There is a port of the same stack by HSC for Android. So I guess it should work there also, but, I must still test it out.
So, it looks like most of the pieces of the puzzle are in place. However, while using AudioRecord and UDP on the emulator, I have encountered the following problems.

  1. On the emulator, I instantiate AudioRecord with a sampling rate of 8000Hz and an encoding of 16BIT PCM. This works fine. However, when I try to run the same code on a device, the AudioRecord object does not get created. Looks like I will have to experiment with different sampling rates and buffer sizes. Strange, huh?
  2. To test the sending and receiving of PCM data, I built a small Java applet that streamed the PCM data to the emulator. I setup proper port redirections. I am able to receive the data in the emulator, but, when I try to send data OUT from the emulator, nothing happens.
Looks like once these problems are sorted out, we are good to go!!!


Thursday, June 11, 2009

Real Time Voice Streaming for Google Android - Part 2 [Technical Details]

To stream voice, fundamentally, we need the following components.
  • A method to obtain PCM audio from the Mic and store it in an in-memory buffer.
  • A protocol suitable for transfer of real time data - RTP in other words.
  • Some kind of signaling protocol to negotiate the call. (Eg: SIP, XMPP/Jingle).
  • A codec to optimize the data transfer format. (Eg: Speex).
As far as the Google Android platform is considered, until recently (Android SDK 1.1 and lower) did not have the first capability. Android 1.5 still does not have an RTP stack, but I have ported a small but functional Open Source RTP stack to the platform. As for signalling, SIP and XMPP/Jingle, I feel have too much overhead. Since both peers will be utilizing my client, a stripped down negotiation protocol would be more efficient. This is where XMPP comes in. As you may know, XMPP is XML based and is widely used. Hence, we can build a small but fast call negotiation protocol over XMPP, given that the parties are logged in via their Jabber accounts.
One may think that this won't inter-operate with existing infrastructures. This is true. To have that capability would translate into unnecessary complexity at this stage. Integration with existing systems is future work as of now. :-)



Another point is that trasmitting raw PCM over the internet is not a very efficient design choice. For this, we need some kind of Codec that will provide us with compression, decompression etc. the Speex codec is Open source and available in Java as jSpeex. It is simple to use.




I will be approaching this project in the following manner.

1. Write PURE java code and test my ideas and algorithms on a Java applet.
2. Port it to the Android platform.