Search code examples
androidandroid-ndkjava-native-interface

MSI SDR device sample code does not compile


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)  

Solution

  • 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.