Summary
Omiscid is an open source middleware for designing services for local area networks. It has been developped for intelligent environments but can be used in various contexts. It features a graphical user interface for service monitoring. You can find Omiscid through the Omiscid website.
This page is about using Omiscid on Android to interconnect services running on a phone with other services (e.g. running in the environment, on a PC). Omiscid used ZeroConf as its discovery mecanism and the Java implementation also uses JAXB. These two elements are the main difficulties for running Omiscid on Android.
So, what works? A service on the phone can find and connect to a service on a computer. The phone service can send messages to and receive messages from it.
And ... what does not works? JAXB compiles but still does not run: exceptions are thrown even if they are non fatal for some Omiscid use cases (control port is not working). The computers are not seeing the services on the phone, I don't know why.
Let's do it
Setting
I tested with a laptop and a phone, both connected to the same wifi network. Everything in Java.
I pushed the projects to github: https://github.com/twitwi/AndromiscidDemo. I used the android SDK and tested with a Nexus One.
On the Laptop
Services are using avahi on the laptop. I designed a service to run on the computer. It is a Netbeans project that uses Omiscid with nothing special. It is in the ServiceOnComputer subfolder and should be runnable with ant run.
On the Phone
At the same time, I tried to use Netbeans to create the android project. You can find the project in the DemoWithNetbeans subfolder. Here, I list the important things that I did for the project to work.
Setting Permissions
Android clearly identifies permissions given to an application. Here we need two permissions: android.permission.INTERNET and android.permission.CHANGE_WIFI_MULTICAST_STATE. The first is for wifi communications, the second is required for ZeroConf (dnssd) to be operational. See DemoWithNetbeans/AndroidManifest.xml for the complet manifest.
Making ZeroConf works: enabling multicast processing
To improve battery life, processing of multicast packets is disabled by default on Android. We can and must reenable this for the service discovery to work. This is done programmatically by acquiring a lock in our activity. At the same time, we tell Omiscid to try directly the pure java implementation of ZeroConf (jmds). See the java code for the full class, but here are the related pieces:
class ... { android.net.wifi.WifiManager.MulticastLock lock; ... private void setUp() { // to be called by onCreate // Omiscid should try directly jmds, not avahi, not mdns DNSSDFactory.DefaultFactory.factoryToTryFirst = "jmdns"; DNSSDFactory.DefaultFactory.verboseMode = true; DNSSDFactory.DefaultFactory.verboseModeMore = true; android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) getSystemService(android.content.Context.WIFI_SERVICE); lock = wifi.createMulticastLock("HeeereDnssdLock"); lock.setReferenceCounted(true); lock.acquire(); ... } protected void onDestroy() { if (lock != null) lock.release(); ... }
Bundling JAXB and other libraries
For android, libraries needs to be compiled (like plain code) using a tool called dex. We have to add the following libraries to our project (these are JAXB + the subpart of Omiscid that omits avahi and mdns):
- activation.jar, jaxb-api.jar, jaxb-impl.jar, jsr173_1.0_api.jar
- omiscid-1.6.1.jar, JiveDNS-1.1-lightened.jar
JAXB has the particularity of being a core library (it is usually integrate in the java runtime environment, and it has classes in the "java..." package). Because of this I needed to tell "dex" to accept to compile JAXB. At the same time I fixed a problem with the Netbeans build script to include the above libraries. This has been done by patching the ant script DemoWithNetbeans/nbproject/build-impl.xml to add parameters to the "dex" call:
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-dex"> <exec executable="${dx}" failonerror="true"> <arg value="--dex"/> ... <arg value="--core-library"/> <!-- ADDED --> <arg path="${build.classes.dir}"/> <arg path="bundled-libs"/> <!-- ADDED -->
Building and Deploying
Once everything is properly done, I compile with ant. It happen to fail once because omiscid got compiled twice, just in case, I did rm -rf build/classes/fr ; ant. Then I deploy through USB with $SDK/platform-tools/adb install -r dist/DemoWithNetbeans.apk and monitor it with $SDK/platform-tools/adb logcat.
I hope I did not forget too many things and that we can go further than the current state.
Any feedback or remarks? Contact me at click-me ;-p @nospam.com.