Utilize Avahi Libraries in Android for mDNS Discovering
2015-12-15 04:09
721 查看
零.
Continue my
previous avahi article, here, i would port the same example code to Android platform.
Download and unravel
Android NDK
for me, the untarred NDK root locates in ~/Android/AndroidNDK/android-ndk-r10e
And install the android tools in the linux system. (yum for fedora, apt-get for ubunu/debian)
I strongly suggest you DO NOT install the others android-tool, header and libraries via apt-get/yum.
If you need those, just download from Android website and decompress them.
一.
Download and untar the avahi libraries, in here I use version 0.6.31.
Download 2 patches and place them in the untarred avahi folder:
avahi.org/raw-attachment/ticket/354/0001-Add-Android-support.patch
avahi.org/raw-attachment/ticket/354/0002-Add-uninstalled.pc.in-files.patch
apply the patches.
You would encounter a warning here, just ignore it. it is for there is no .git folder inside the avahi folder.
For the old configuration tools does not support androideabi, you need to upgrade the config.guess and config.sub from
here. it is, to overwrite these 2 files inside the avahi root folder.
二.
The struct in6_pktinfo has been added in Android 4.0(2011/10). When the avahi 0.6.31 was released (2012/2), the BioniC (the position of glibC for Android) libraries on most populace's Android phone was not implemented the whole IVP6. Therefore, the structure
ha been declare inside avahi. In present(2015/12), I thought there is no one set build-target version before 4.0. It is requisite to modify code to remove the obsolete lines in avahi-core/socket.c , about line 67:
The in6_pktinfo has been declared in NDKfolder/platforms/android-version/arch/usr/include/linux/ipv6.h, to comment out it to
avoid compilation error.
Optional:
if your application would be integrated web-browser and avahi disovering functions, you should modify the code avahi-core/netlink.c, about line 160:
It is, the add.nl_pid value would not be conflicted with browser's. More detail of this change is in
here.
三.
The Avahi configure arguments for me be:
NOTE :
Zero:
I disable most functions of Avahi. Because those are useless for the goal of discovering mDNS service and dependent on dbus, gtk, qt and so forth libraries. To building those depended libraries are difficult for Android.
One:
The path, /home/gaiger/Android/AndroidNDK/android-ndk-r10e/platforms/android-14/arch-arm/usr, is where the Android system libraries locates, those are being part of Android NDK.
/home/gaiger/Android/AndroidNDK/android-ndk-r10e : where AndroidNDK root locates.
platforms/android-14/arch-arm : I chose to android 4.0 with arm-architecture as my target system.
it is very natural to add include path (-Iusr_path/include) and linking path(-Iusr_path/lib) as arguments in cross-compilation.
TWO:
-mcpu=arm926ej-s -mfloat-abi=softfp : To avoid crash in some (mostly those are not existed ) cheap Android device CPU without hardware floating computing. Besides, Avahi do not involve in heavy floating point computing, So adapt pure soft-float computing
would not lead mDNS discovering sluggish.
arm926ej-s means, assuming the CPU does not support hardware floating but supports Jazelle ( for java VM).
More detail of CPU architecture, you could refer to
this article.
THREE :
--with-distro=debian : for me , I use ubuntu. If you use fedora/CentOS, you use set it as fedora.
FOUR:
--disable-stack-protector : there is no libssp (stack smash protector) in current BioniC defaultly. To advert configuring error, one should disable this function. The detail about libssp is in
here.
四.
After configuring done, it is very instinctive to press make and make install.
To this step, the avahi libraries for Android has been built, in the
avahi_root/built
五.
Create a folder and a sub-folder in avahi root: sandyboxcode/jni
Copy the code sandbox-discover-standalone.c of
my last article in folder sandyboxcode/jni.
And Create two files, Application.mk and Android.mk in the same folder ( sandyboxcode/jni).
The content of file Application.mk be:
The Android.mk file be:
Then to the sandbox folder, type :
Now you have gotten binary of sandbox-discover-standalone for Android, under the folder libs/armeabi .
六.
Push the built binary to a android device,
which might need to be rooted to execute a binary in shell.
For me, I use the development board
tiny210 on Android 4.0, which was rooted natively.
check if the device connected to working computer indeed:
push the binary to the android :
execute it in the shell:
It is successful totally.
Known insufficiency :
if you encounter Segmentation fault when you execute the binary in Android,
you should correct the code in sandbox-discover-standalone.c,
of function ServiceResolverCallback:
It could avoid the crashing: the function if_indextoname of bionic libraries is not as stable as libc.
Extra:
It is passible to write a stand Makefile for Android ndk build :
i assure the Makefile be in sandyboxcode/Makefile (NOT inside the jni folder),
for the sandbox-discover-sandalone.c be :
Note : the shared libraries liblog.so be linking directly!.
Continue my
previous avahi article, here, i would port the same example code to Android platform.
Download and unravel
Android NDK
for me, the untarred NDK root locates in ~/Android/AndroidNDK/android-ndk-r10e
And install the android tools in the linux system. (yum for fedora, apt-get for ubunu/debian)
sudo apt-get install gcc-arm-linux-androideabi
sudo apt-get install android-tools-adb
I strongly suggest you DO NOT install the others android-tool, header and libraries via apt-get/yum.
If you need those, just download from Android website and decompress them.
一.
Download and untar the avahi libraries, in here I use version 0.6.31.
Download 2 patches and place them in the untarred avahi folder:
avahi.org/raw-attachment/ticket/354/0001-Add-Android-support.patch
avahi.org/raw-attachment/ticket/354/0002-Add-uninstalled.pc.in-files.patch
apply the patches.
patch -p1 0001-Add-Android-support.patch
You would encounter a warning here, just ignore it. it is for there is no .git folder inside the avahi folder.
patch -p1 0002-Add-uninstalled.pc.in-files.patch
For the old configuration tools does not support androideabi, you need to upgrade the config.guess and config.sub from
here. it is, to overwrite these 2 files inside the avahi root folder.
二.
The struct in6_pktinfo has been added in Android 4.0(2011/10). When the avahi 0.6.31 was released (2012/2), the BioniC (the position of glibC for Android) libraries on most populace's Android phone was not implemented the whole IVP6. Therefore, the structure
ha been declare inside avahi. In present(2015/12), I thought there is no one set build-target version before 4.0. It is requisite to modify code to remove the obsolete lines in avahi-core/socket.c , about line 67:
#endif #if(0) #ifdef __BIONIC__ struct in6_pktinfo { struct in6_addr ipi6_addr; int ipi6_ifindex; }; #endif #endif static void mdns_mcast_group_ipv4(struct sockaddr_in *ret_sa) {
The in6_pktinfo has been declared in NDKfolder/platforms/android-version/arch/usr/include/linux/ipv6.h, to comment out it to
avoid compilation error.
Optional:
if your application would be integrated web-browser and avahi disovering functions, you should modify the code avahi-core/netlink.c, about line 160:
memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_groups = groups; #if(1) addr.nl_pid = 0; #else addr.nl_pid = getpid(); #endif if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
It is, the add.nl_pid value would not be conflicted with browser's. More detail of this change is in
here.
三.
The Avahi configure arguments for me be:
./configure --prefix=$PWD/built --disable-dbus --disable-mono --disable-monodoc --disable-qt4 --disable-qt3 --disable-glib --disable-gobject --disable-gtk --disable-gtk3 --disable-gdbm --disable-dbm --disable-python --disable-pygtk -disable-libdaemon --disable-nls --disable-xmltoman --with-xml=none --disable-core-docs --disable-doxygen-doc CPPFLAGS="-I/home/gaiger/Android/AndroidNDK/android-ndk-r10e/platforms/android-14/arch-arm/usr/include -mcpu=arm926ej-s -mfloat-abi=soft" LDFLAGS=-L/home/gaiger/Android/AndroidNDK/android-ndk-r10e/platforms/android-14/arch-arm/usr/lib --host=arm-linux-androideabi --disable-stack-protector --with-distro=debian
NOTE :
Zero:
I disable most functions of Avahi. Because those are useless for the goal of discovering mDNS service and dependent on dbus, gtk, qt and so forth libraries. To building those depended libraries are difficult for Android.
One:
The path, /home/gaiger/Android/AndroidNDK/android-ndk-r10e/platforms/android-14/arch-arm/usr, is where the Android system libraries locates, those are being part of Android NDK.
/home/gaiger/Android/AndroidNDK/android-ndk-r10e : where AndroidNDK root locates.
platforms/android-14/arch-arm : I chose to android 4.0 with arm-architecture as my target system.
it is very natural to add include path (-Iusr_path/include) and linking path(-Iusr_path/lib) as arguments in cross-compilation.
TWO:
-mcpu=arm926ej-s -mfloat-abi=softfp : To avoid crash in some (mostly those are not existed ) cheap Android device CPU without hardware floating computing. Besides, Avahi do not involve in heavy floating point computing, So adapt pure soft-float computing
would not lead mDNS discovering sluggish.
arm926ej-s means, assuming the CPU does not support hardware floating but supports Jazelle ( for java VM).
More detail of CPU architecture, you could refer to
this article.
THREE :
--with-distro=debian : for me , I use ubuntu. If you use fedora/CentOS, you use set it as fedora.
FOUR:
--disable-stack-protector : there is no libssp (stack smash protector) in current BioniC defaultly. To advert configuring error, one should disable this function. The detail about libssp is in
here.
四.
After configuring done, it is very instinctive to press make and make install.
To this step, the avahi libraries for Android has been built, in the
avahi_root/built
五.
Create a folder and a sub-folder in avahi root: sandyboxcode/jni
Copy the code sandbox-discover-standalone.c of
my last article in folder sandyboxcode/jni.
And Create two files, Application.mk and Android.mk in the same folder ( sandyboxcode/jni).
The content of file Application.mk be:
#APP_ABI := armeabi-v7a APP_ABI := armeabi
The Android.mk file be:
LOCAL_PATH := $(my-dir) ifneq ($(DYNAMIC_LINK),true) DYNAMIC_LINK = false include $(CLEAR_VARS) LOCAL_MODULE := libavahi-core LOCAL_SRC_FILES := ../../built/lib/libavahi-core.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := libavahi-common LOCAL_SRC_FILES := ../../built/lib/libavahi-common.a include $(PREBUILT_STATIC_LIBRARY) else include $(CLEAR_VARS) LOCAL_MODULE := libavahi-core LOCAL_SRC_FILES := ../../built/lib/libavahi-core.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := libavahi-common LOCAL_SRC_FILES := ../../built/lib/libavahi-common.so include $(PREBUILT_SHARED_LIBRARY) endif #if $DYNAMIC_LINK .neq. true include $(CLEAR_VARS) LOCAL_MODULE := sandbox-discover-standalone LOCAL_SRC_FILES := sandbox-discover-standalone.c LOCAL_CFLAGS := -O2 -mcpu=arm926ej-s -mfloat-abi=softfp LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../built/include ifeq ($(DYNAMIC_LINK),false) LOCAL_STATIC_LIBRARIES := libavahi-core libavahi-common else LOCAL_SHARED_LIBRARIES += libavahi-common libavahi-core endif #if $(DYNAMIC_LINK) eq false LOCAL_LDLIBS += -llog include $(BUILD_EXECUTABLE)
Then to the sandbox folder, type :
$your_ndk_path/ndk-build -B V=1
Now you have gotten binary of sandbox-discover-standalone for Android, under the folder libs/armeabi .
六.
Push the built binary to a android device,
which might need to be rooted to execute a binary in shell.
For me, I use the development board
tiny210 on Android 4.0, which was rooted natively.
check if the device connected to working computer indeed:
$ adb devices List of devices attached 0123456789ABCDEF device
push the binary to the android :
$ adb push libs/armeabi/sandbox-discover-standalone sandbox-discover-standalone 2291 KB/s (202300 bytes in 0.086s)
execute it in the shell:
$ adb shell / # chmod 777 sandbox-discover-standalone / # ./sandbox-discover-standalone 1 services have been found Service Type: _http._tcp Service Name: GAIGER NETEYE CS2230 Domain Name: local Interface: eth0 IPv4 Address: 192.168.13.107/NETEYECS2230-001A97018882.local:80 TEXT Data: NULL discover cast 1002 msec
It is successful totally.
Known insufficiency :
if you encounter Segmentation fault when you execute the binary in Android,
you should correct the code in sandbox-discover-standalone.c,
of function ServiceResolverCallback:
pServiceInfo->pServiceName = strndup(pServiceName, MAX_STR_LEN); pServiceInfo->pDomainName = strndup(pDomain, MAX_STR_LEN); #ifndef __ANDROID__ pServiceInfo->pInterface = strndup(if_indextoname(interface, (char*)pServiceName), MAX_STR_LEN); #endif pServiceInfo->pProtocolNumber = strndup(avahi_proto_to_string(protocol), MAX_STR_LEN);
It could avoid the crashing: the function if_indextoname of bionic libraries is not as stable as libc.
Extra:
It is passible to write a stand Makefile for Android ndk build :
i assure the Makefile be in sandyboxcode/Makefile (NOT inside the jni folder),
for the sandbox-discover-sandalone.c be :
CC := arm-linux-androideabi-gcc CXX := arm-linux-androideabi-g++ INC := -I~/Android/AndroidNDK/android-ndk-r10e/platforms/android-14/arch-arm/usr/include INC += -I../built/include -Ijni AVAHI_LIB_PATH := ../built/lib LIB := ~/Android/AndroidNDK/android-ndk-r10e/platforms/android-14/arch-arm/usr/lib/liblog.so LIB += $(AVAHI_LIB_PATH)/libavahi-core.a LIB += $(AVAHI_LIB_PATH)/libavahi-common.a CFLAGS := -g all : $(CC) $(CFLAGS) $(INC) jni/sandbox-discover-standalone.c $(LIB) -o sandbox-discover-standalone clean : rm sandbox-discover-standalone -rf
Note : the shared libraries liblog.so be linking directly!.
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories