MSI SDR device sample code does not compile - android

I am trying to interface with an MSI SDR dongle, using an android app
This device is a clone of the SDRPlay SDR device, and is compatible with it's software and drivers
I am trying to interface with this using an OTG cable and android phone
The android drivers for this can be downloaded from here https://www.sdrplay.com/downloads/
It is in the Android tab under the API/HW – V2.11 (15TH NOV 2017) link (https://www.sdrplay.com/anddl.php)
A possible sample code for this driver can be found here: https://www.sdrplay.com/docs/AndroidIntegrationNote.pdf
Before making the full android program it says the library (libmir_sdr_api.a) should be built into an .so library file using ndk-build
I currently have Android's hello-jni sample project from here: https://github.com/android/ndk-samples/tree/android-mk/hello-jni
I have replaced the jni folder using the Android.mk file, libmir_sdr_api.a, mir_sdr.h, initialization-jni.cpp, demod-jni.cpp and demod-jni.h files mentioned in section 3 of the AndroidIntegrationNote.pdf file I linked above
When I execute ndk-build from the hello-jni project folder, I get he following error:
Android NDK: Found platform level in ./default.properties. Setting APP_PLATFORM to android-25.
Android NDK: android-25 is an alias for android-24. Adjusting APP_PLATFORM to match.
[arm64-v8a] Gdbserver : [aarch64-linux-android] libs/arm64-v8a/gdbserver
[arm64-v8a] Gdbsetup : libs/arm64-v8a/gdb.setup
[x86_64] Gdbserver : [x86_64-linux-android] libs/x86_64/gdbserver
[x86_64] Gdbsetup : libs/x86_64/gdb.setup
[armeabi-v7a] Gdbserver : [arm-linux-androideabi] libs/armeabi-v7a/gdbserver
[armeabi-v7a] Gdbsetup : libs/armeabi-v7a/gdb.setup
[x86] Gdbserver : [i686-linux-android] libs/x86/gdbserver
[x86] Gdbsetup : libs/x86/gdb.setup
make: *** No rule to make target 'jni/initialisation-jni.cpp', needed by 'obj/local/arm64-v8a/objs-debug/mirics-jni/initialisation-jni.o'. Stop.
I am used to compiling NDK code suing Android Studio and cmake so I am not sure what is going on here. I have not been able to link the .a file through cmake either so I thought of giving the driver manufacturer's sample code a try, but it not working either. Is the Android.mk file in pdf file linked earlier incomplete, or am I not building it correctly? These are the contents of the Android.mk file:
# $(call my-dir) returns the local directory which is the jni directory
LOCAL_PATH := $(call my-dir)
# libmir_sdr_api.a – this section creates a version of the Mirics API to be used below
include $(CLEAR_VARS)
LOCAL_MODULE := mir_sdr_api-prebuilt
LOCAL_SRC_FILES := libmir_sdr_api.a
LOCAL_EXPORT_C_INCLUDES := $(call my-dir)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# mirics-jni – this section uses the jni C++ source code to build the dynamic library
LOCAL_MODULE := mirics-jni
LOCAL_SRC_FILES := initialisation-jni.cpp demod-jni.cpp
LOCAL_C_INCLUDES := $(call my-dir)
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib
LOCAL_STATIC_LIBRARIES := mir_sdr_api-prebuilt
include $(BUILD_SHARED_LIBRARY)

Regarding missing jni/initialisation-jni.cpp, you probably have the file jni/initialization-jni.cpp instead.
Also, unfortunately, the document is wrong. You can only use $(call my-dir) easily at the top of the file. Luckily, Android NDK adds the jni directory to includes path for you. Still, to be on the safe side, better write:
# $(call my-dir) returns the local directory which is the jni directory
LOCAL_PATH := $(call my-dir)
# libmir_sdr_api.a – this section creates a version of the Mirics API to be used below
include $(CLEAR_VARS)
LOCAL_MODULE := mir_sdr_api-prebuilt
LOCAL_SRC_FILES := libmir_sdr_api.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# mirics-jni – this section uses the jni C++ source code to build the dynamic library
LOCAL_MODULE := mirics-jni
LOCAL_SRC_FILES := initialization-jni.cpp demod-jni.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib
LOCAL_STATIC_LIBRARIES := mir_sdr_api-prebuilt
include $(BUILD_SHARED_LIBRARY)
Finally, pay attention to your build process. You only have one kind of the libmir_sdr_api.a static library, it's built for a 32-bit ARM CPU. Therefore you cannot build your libmirics-jni.so for other architectures. Add
APP_ABIS = armeabi-v7a
to your Application.mk file, or specify
abifilters = armeabi-v7a
in your build.gradle, if you build your library in Android Studio.

Related

Using NDK header when building vendor module with VNDK enabled

I have a native vendor module built with AOSP (android 9.0.0_r35).
This module uses android/input.h header. Note that this header is included in the android NDK.
When enabling the VNDK, building module fails with fatal error: 'android/input.h' file not found error.
This is caused by android build system (see compiler.go) who does not export the CommonGlobalIncludes when VNDK is enabled so frameworks/native/include (containing input.h) is not in include list.
I tried adding libandroid to LOCAL_SHARED_LIBRARIES without success.
The android doc mentioning header does not refers to NDK includes.
This file is supposed to stay stable so I think it is safe to use it from a vendor module.
Is there a module (LOCAL_SHARED_LIBRARIES or LOCAL_HEADER_LIBRARIES) to include to allow using NDK headers ?
Else, is it safe to add $(ANDROID_BUILD_TOP)/out/soong/ndk/sysroot/usr/include/ to include path ?
Test code :
Android.mk :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= testIncludeInput_vendor
LOCAL_PROPRIETARY_MODULE := true
LOCAL_SRC_FILES := test.cpp
LOCAL_SHARED_LIBRARIES := libandroid
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= testIncludeInput_system
LOCAL_SRC_FILES:= test.cpp
LOCAL_SHARED_LIBRARIES := libandroid
include $(BUILD_STATIC_LIBRARY)
test.cpp :
#include <android/input.h>

How do I build the arcore camera_utility shared library in NDK-BUILD?

I'm trying to build the 'arcore camera utility' library in NDK_BUILD, here: https://github.com/google-ar/arcore-unity-sdk/tree/master/Assets/GoogleARCore/Examples/ComputerVision/Plugins/src
Using this guide: https://yeephycho.github.io/2016/10/20/How-to-Use-NDK-to-Build-A-Shared-Android_Native-Library/ I was at least able to get it to compile in a libarcore_camera_utility.so file. Not only that but it was actually recognized by my app on the phone and instead of getting a DLL missing error I got the error: "EntryPointNotFoundException: Unable to find an entry point named 'TextureReader_create' in 'arcore_camera_utility'." which means it at least found the file, now.
The filesize of the .so is only 6k so it seems like I'm not compiling it correctly as the already working 32bit version that comes with the package is 100k, based on this question it seems like I'm leaving something out?: Entry point not found, Android .so file
My Android.mk file is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := arcore_camera_utility_shared
LOCAL_C_INCLUDES += \
LOCAL_SRC_FILES := camera_utility.cc gl_utility.cc texture_reader.cc
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := arcore_camera_utility
LOCAL_WHOLE_STATIC_LIBRARIES := arcore_camera_utility_shared
include $(BUILD_SHARED_LIBRARY)
And my Application.mk file contains:
APP_ABI := arm64-v8a
APP_PLATFORM := android-24
APP_STL := c++_static
APP_BUILD_SCRIPT := ./jni/Android.mk
Am I building it in such a way as to leave the code out?
To compile arcore_camera_utility for the arm 64bit target-
1.) Create a new directory called 'arcorelibrary', then a subdirectory called 'jni'
2.) Download this zip: https://github.com/google-ar/arcore-unity-sdk/blob/master/Assets/GoogleARCore/Examples/ComputerVision/Plugins/src/arcore_camera_utility.zip
3.) get the three .cc files and the three .h files and place them in the jni directory
4.) Create a file called 'Android.mk' and place it in the jni directory, with the following contents:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= arcore_camera_utility_static
LOCAL_SRC_FILES:= camera_utility.cc gl_utility.cc texture_reader.cc
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDLIBS := -llog -landroid -lEGL -lGLESv2 -lGLESv3
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := arcore_camera_utility
LOCAL_WHOLE_STATIC_LIBRARIES := arcore_camera_utility_static
include $(BUILD_SHARED_LIBRARY)
5.) Create a file called 'Application.mk' and place it in the jni directory, with the following contents:
APP_ABI := arm64-v8a
APP_PLATFORM := android-24
APP_STL := c++_static
APP_BUILD_SCRIPT := ./jni/Android.mk
6.) Download Android NDK and unzip somewhere (The version you need depends on which Unity version you're using) https://developer.android.com/ndk/downloads/older_releases.html
7.) Open a terminal or powershell, go to the root directory (arcorelibrary) of your project
8.) Create a path to where ever you unzipped Android NDK (Powershell example):
$env:Path += ";C:\[where-ever-you-unzipped]\android-ndk-r13b-windows-x86_64\android-ndk-r13b"
9.) Run:
ndk-build.cmd

Specify directory for external C++ library +NDK +Android studio

I'm new to this NDK build and I'm having trouble with running this Buildbox project in android studio.
After linking C++ to Gradle using ndk-build and syncing, it is giving this error.
Android NDK: C:\AndroidApps\app\app\src\main\jni\Android.mk: Cannot find module with tag 'box2D' in import path
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined?
Android NDK: The following directories were searched:
Android NDK:
process_begin: CreateProcess(NULL, "", ...) failed.
I can see reference for cocos2dx in the java and resources subfolders.
I'm not sure if I have to download box2D,core,cocos2dx library .
What changes do I have to make to the android.mk file so that the errors are gone?
Here is the android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := player_shared
LOCAL_MODULE_FILENAME := libplayer
LOCAL_SRC_FILES := main.cpp
LOCAL_WHOLE_STATIC_LIBRARIES := core_static cocos2dx_static box2d_static
GOOGLE_PLAY_STORE := true
include $(BUILD_SHARED_LIBRARY)
$(call import-add-path, $(LOCAL_PATH)/platform/third_party/android/prebuilt)
$(call import-module, box2D)
$(call import-module, core)
$(call import-module, cocos2dx)
NDK does not download imported modules for you. I am not sure if there are plans to add such feature (parallel to XCode pods) in the future.
You will find detailed description of import-module here, but basically you can set NDK_MODULE_PATH in your Application.mk file, with ; separators on Windows, but using straight / in paths instead of Windows native backsashes, e.g. C:/ext), and then
$(call import-module, box2D)
will be equivalent to
include C:/ext/box2D/Android.mk

use libcryto.so and libssl.so in an android project?

I'm beginer to Android NDK. I want to build a RSA example base on openssl libary.
First, I built libssl.so and libcrypto.so librairies with ndk-build in the guardianproject.
Next, I create a new sample project to integrate libary (libss.so & lybcryto.so). I follow the same in this post
My App directory
TrialApp
|
|-->Activity.java (includes System.LoadLibrary calls)
|
|-->jni
|-->TestJNI2.cpp
|
|-->Android.mk
|
|-->includes
| |
| |-->openssl (dir containing *.h files)
|
|-->precompiled
|-->libssl.so
|-->libcrypto.so
My android.mk:
LOCAL_PATH := $(call my-dir)
# Prebuilt libssl
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := precompiled/libssl.so
include $(PREBUILT_SHARED_LIBRARY)
# Prebuilt libcrypto
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := precompiled/libcrypto.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
c_includes := $(LOCAL_PATH)
cf_includes := includes/openssl
cf_includes := $(addprefix -Ijni/,$(cf_includes))
export_c_includes := $(c_includes)
LOCAL_MODULE := security
LOCAL_SRC_FILES := TestJNI2.cpp
LOCAL_CFLAGS += $(cf_includes)
LOCAL_EXPORT_C_INCLUDES := $(export_c_includes)
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libssl.so
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libcrypto.so
include $(BUILD_SHARED_LIBRARY)
TestJNI2.cpp
/* OpenSSL headers */
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
/* Initializing OpenSSL */
void init_openssl(void){
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
}
Then when i build with ndk-build always have problems like this
/data/workspace/TestJNI2/jni/TestJNI2.cpp:3:25: error: openssl/bio.h: No such file or directory
/data/workspace/TestJNI2/jni/TestJNI2.cpp:4:25: error: openssl/ssl.h: No such file or directory
/data/workspace/TestJNI2/jni/TestJNI2.cpp:5:25: error: openssl/err.h: No such file or directory
/data/workspace/TestJNI2/jni/TestJNI2.cpp: In function 'void init_openssl()':
/data/workspace/TestJNI2/jni/TestJNI2.cpp:10: error: 'SSL_load_error_strings' was not declared in this scope
/data/workspace/TestJNI2/jni/TestJNI2.cpp:11: error: 'ERR_load_BIO_strings' was not declared in this scope
/data/workspace/TestJNI2/jni/TestJNI2.cpp:12: error: 'OpenSSL_add_all_algorithms' was not declared in this scope
make: *** [/data/workspace/TestJNI2/obj/local/armeabi/objs/security/TestJNI2.o] Error 1
Can anyone help me? Or how to build an example RSA algorthim base on openssl lib?
You should build static libraries for libssl and libcrypto in your script. If you can't, rename these libraries (you can do this after build, while copying to your precompiled directory). The reason is that the system comes with its own (probably different) version of these shared libraries, and the loader will use /system/lib/libssl.so and /system/lib/libcrypto.so instead of your private copies.
Regarding the Android.mk file, I slightly cleaned it up for you (note that I did not change the names of prebuilt LOCAL_MODULEs, but changed the name of LOCAL_MODULE you finally build, because security is, well, too generic and could also happen to match a system library on some device):
LOCAL_PATH := $(call my-dir)
# Prebuilt libssl
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := precompiled/libPrivateSsl.so
include $(PREBUILT_SHARED_LIBRARY)
# Prebuilt libcrypto
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := precompiled/libPrivateCrypto.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := PrivateSecurity
LOCAL_C_INCLUDES := includes
LOCAL_SRC_FILES := TestJNI2.cpp
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := ssl crypto
include $(BUILD_SHARED_LIBRARY)
Don't forget that your Java should load the dependencies first:
{
System.loadLibrary("PrivateSsl");
System.loadLibrary("PrivateCrypto");
System.loadLibrary("PrivateSecurity");
}
I'm beginer to Android NDK. I want to build a RSA example base on openssl libary.
You can, but you have to be careful. Here's the reason Alex told you to use static libraries for libssl and libcrypto in your script.
The master Android process is zygote. Its like init in Linux. Zygote loads OpenSSL when its start, and it loads version 0.9.8. If you link against OpenSSL 1.0.1, then you will get mysterious runtime crashes. The crashes are due to the Android loader using the 0.9.8 version of the library (already mapped from Zygote), and not your version of OpenSSL.
You can use a shared object, but your shared object must be a wrapper around the static version of libssl and libcrypto.
If you are not using Android's build system, then you can find additional instructions for building purely from the command line at OpenSSL's wiki. The wiki page includes setting the envrionment and cross compiling. See FIPS Library and Android.
Another thing to watch out for: be sure to build with -mfloat-abi=softfp. The stock OpenSSL misses that when cross compiling. You need it to ensure floats are passed on the stack, and not through floating point registers. Otherwise, all your floats will mysteriously have 0.0f value (like the floats used to estimate entropy in RAND_add).

How to link a prebuilt shared Library to an Android NDK project?

Here I used this Android.mk file in jni/ folder.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Here we give our module name and source file(s)
LOCAL_MODULE := offlineDownload
LOCAL_SRC_FILES := offline_download.c
LOCAL_SHARED_LIBRARIES :=../lib/libpackext.so.1.0
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
And make one lib folder in project directory and put my prebuilt .so library and make one Android.mk file which contains following
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := packext
LOCAL_SRC_FILES := libpackext.so.1.0
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include
include $(PREBUILT_SHARED_LIBRARY)
And when i use ndk-build -B command than i got undefined reference to packageExtraction. Here I use my prebuilt library functions means I can't link my prebuilt shared library to my offlinedownload library.
So any body please help me to solved out this issue.
Here is a complete Android.mk file for using a 3rd party shared library.
The library (libffmpeg.so) is placed in the jni folder.
Its "LOCAL_EXPORT_C_INCLUDES" specifies where the header files are kept for the library.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := libffmpeg.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../ffmpeg/libs/arm-linux-androideabi4.7_1/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpegandroid
LOCAL_SRC_FILES := ffmpegandroid.c
LOCAL_SHARED_LIBRARIES := ffmpeg
include $(BUILD_SHARED_LIBRARY)
If you wanted to support multiple architectures then you could specify:
APP_ABI := armeabi armeabi-v7a x86 mips
in your jni/Application.mk and change the LOCAL_SRC_FILES to something like:
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libffmpeg.so
and place a libffmpeg.so at jni/armeabi/libffmpeg.so, jni/armeabi-v7a/libffmpeg.so etc ..
Android NDK official hello-libs CMake example
https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs
Just worked for me on Ubuntu 17.10 host, Android Studio 3, Android SDK 26, NDK 15.2. so I strongly recommend that you base your project on it.
The shared library is called libgperf, the key code parts are:
hello-libs/app/src/main/cpp/CMakeLists.txt:
// -L
add_library(lib_gperf SHARED IMPORTED)
set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION
${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so)
// -I
target_include_directories(hello-libs PRIVATE
${distribution_DIR}/gperf/include)
// -lgperf
target_link_libraries(hello-libs
lib_gperf)
on C++ code, use: #include <gperf.h>
header location: hello-libs/distribution/gperf/include/gperf.h
lib location: distribution/gperf/lib/arm64-v8a/libgperf.so
app/build.gradle:
android {
sourceSets {
main {
// let gradle pack the shared library into apk
jniLibs.srcDirs = ['../distribution/gperf/lib']
Then, if you look under /data/app on the device, libgperf.so will be there as well.
If you only support some architectures, see: Gradle Build NDK target only ARM
The example git tracks the prebuilt shared libraries, but it also contains the build system to actually build them as well: https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs
You have to do either one of the following:
Cut and paste everything except LOCAL_PATH := $(call my-dir) from your second Android.mk into your first.
Put the following in the end of your first Android.mk:
$(call import-module,packext)
Also make sure that you set your NDK_MODULE_PATH environment variable to a path where the Android.mk-file defining the module packext can be found.
You also have to change the LOCAL_SHARED_LIBRARIES in the same way mgiza said in the first answer. I suppose the packageExtraction that you got undefined reference to is in your prebuilt library so unless you have other linking problems this should solve the issue.
Have a look at the ndk documentation for prebuilts:
android-ndk/docs/PREBUILTS.html
You have to change
LOCAL_SHARED_LIBRARIES :=../lib/libpackext.so.1.0
to
LOCAL_SHARED_LIBRARIES := packext
Be sure that your folder containing the Android.mk for the packext module is named packext and can be found in in your NDK_MODULE_PATH.

Categories

Resources