The focus of this JIRA is for providing a method to build the Proton-C library and get it running in the Android environment. I have forked the Qpid-Proton repository and made a branch called AndroidProton that is based off of 0.6. I have put together a little folder called proton-a which sits inside the former 0.6 branch. Proton-a is the foundation for Proton on Android. It contains a readme with instructions on how to build targeting Android, the necessary files, and an example Android Project utilizing the Proton-C library. I would like my changes to get pulled into the 0.6 branch as an added feature.
Issues porting Proton-C to Android
The first issue of getting Proton-C working on Android was the lack of openssl and uuid support. I fixed this by using open source implementations I found online. My openssl for Android implementation was acquired off an old github repository
My uuid for Android implementation was acquired from AOSP
Building the C libraries for Android
I built these libraries using the ndk-build system that comes with the Android ndk. My folder comes with a README that links to the Android ndk if one does not already have it. The README folder also has step-by-step instructions for someone to build the library their selves. As I said, this involves calling ndk-build 3 times. The user will build the openssl, then the uuid, then the Proton-C libraries. The user can create their own java bindings for calling the c library from Android by building the desktop Qpid-Proton-0.6 with java swig bindings. Or they can use the jars that come with my folder.
Every occurrence of getprotobyname("tcp")->p_proto had to be replaced with IPPROTO_TCP in the source file proton-c/src/posix/driver.c This fix checks if the source is being compiled with the NDK compiler to ensure that it doesn't break the desktop build. The pre-processor definition for Android is
functional bug fix
The swig language binding jars produced with Qpid-Proton-0.6 build system were causing a segfault whenever receiving a message that had the messageId set to a generated uuid from the desktop Qpid-Proton-0.6 client. The error is in JNIMessage.java in qpid-proton-0.6/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/messsage/jni. at the convert method whenever type is a uuid.
The fix I used involved removing the use of pn_bytes_to_array in favor of getting a pn_uuid_t from value (which is a pn_atom_t_u) and then getting the byte array directly from the pn_uuid_t with the pn_uuid_t.getBytes() method call.
Example Android project
In the AndroidProtonBuild folder, a sample Android Proton project is included that uses Proton-C. This project contains a file called UsingSwig.java which exposes simple methods like send(). This sample project has a send and receive button to check if the function is working with your target messaging endpoint. The address to send and receive from must be specified in the UsingSwig.java source file.
tip for native development on android
If you want to check for compilation by the NDK build system use
If you want to use eclipse and print to LogCat from C code, include the following lines at the top of the source file:
#define LOG_TAG "my-log-tag"
#define LOGD(...) _android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS_)
#define LOGE(...) _android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS_)
These lines allow you to call LOGD([stringToPrint]); Which basically serves as a printf, but to LogCat. It even allows formatting such as
LOGD("number of cars: %d", number_of_cars);
You can include these lines in any of the C source files you want to call LOGD from.