aboutsummaryrefslogtreecommitdiffstats
path: root/java/jni/helper_base.hpp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-04-20 07:21:35 +0200
committerSven Gothel <[email protected]>2020-04-20 07:21:35 +0200
commit6fdcdb13db5e13f11c44f0f9bba088252d9ffa18 (patch)
tree8c9c321dd2064eb53438544f0faba91306629c8c /java/jni/helper_base.hpp
parent6505f49b63db200d817817d1d01a14005a3d732c (diff)
Initial working Java binding for the direct_bt C++ module
Example ScannerTinyB01 demonstrates efficient scanning devices using the new BluetoothDeviceDiscoveryListener interface. The C++ HCIObject extends JavaUplink, which handles the java object references via 'std::shared_ptr<JavaAnonObj>', where JavaAnonObj relies on later polymorph specialization. JavaAnonObj gets derived in the java/jni of direct_bt, where the JNI header + libraries are available. +++ The java inplementing NativeDownlink implementations store the nativeInstance to the C++ instances as well as handle their java references within the native instances. The C++ JavaUplink and Java NativeDownlink interfaces are complete the cross referencing java <-> native. +++ Native libraries are now split into pairs: - tinyb + javatinyb - direct_bt + javadirect_bt TODO: BluetoothFactory must chose the proper bundle! +++ The Java Adapter received a BluetoothDeviceDiscoveryListener hook, matching C++ Adapter's HCIDeviceDiscoveryListener. Since the Java Adapter implements its own discovery thread, using the BluetoothDeviceDiscoveryListener is more efficient then polling over a list of Devices fetched. ++++ TODO: Align Java and C++ class names, foremost in the C++ direct_bt space. TODO: Bind the whole C++ GATT functionality More testing.
Diffstat (limited to 'java/jni/helper_base.hpp')
-rw-r--r--java/jni/helper_base.hpp68
1 files changed, 67 insertions, 1 deletions
diff --git a/java/jni/helper_base.hpp b/java/jni/helper_base.hpp
index 153faa9b..4cbda995 100644
--- a/java/jni/helper_base.hpp
+++ b/java/jni/helper_base.hpp
@@ -26,10 +26,15 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#pragma once
+#ifndef HELPER_BASE_HPP_
+#define HELPER_BASE_HPP_
#include <vector>
#include <memory>
+#include <functional>
+#include <jni.h>
+
+#include "BasicTypes.hpp"
jfieldID getInstanceField(JNIEnv *env, jobject obj);
@@ -41,10 +46,20 @@ jfieldID search_field(JNIEnv *env, jclass clazz, const char *field_name,
const char *type, bool is_static);
bool from_jboolean_to_bool(jboolean val);
std::string from_jstring_to_string(JNIEnv *env, jstring str);
+jstring from_string_to_jstring(JNIEnv *env, const std::string & str);
jobject get_bluetooth_type(JNIEnv *env, const char *field_name);
jobject get_new_arraylist(JNIEnv *env, unsigned int size, jmethodID *add);
template <typename T>
+T *castInstance(jlong instance)
+{
+ T *t = reinterpret_cast<T *>(instance);
+ if (t == nullptr)
+ throw std::runtime_error("Trying to cast null object");
+ return t;
+}
+
+template <typename T>
T *getInstance(JNIEnv *env, jobject obj)
{
jlong instance = env->GetLongField(obj, getInstanceField(env, obj));
@@ -111,7 +126,58 @@ jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::unique_ptr<T>>&
return result;
}
+template <typename T>
+jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::shared_ptr<T>>& array,
+ const char *ctor_prototype, std::function<jobject(JNIEnv*, jclass, jmethodID, T*)> ctor)
+{
+ unsigned int array_size = array.size();
+
+ jmethodID arraylist_add;
+ jobject result = get_new_arraylist(env, array_size, &arraylist_add);
+
+ if (array_size == 0)
+ {
+ return result;
+ }
+
+ jclass clazz = search_class(env, T::java_class().c_str());
+ jmethodID clazz_ctor = search_method(env, clazz, "<init>", ctor_prototype, false);
+
+ for (unsigned int i = 0; i < array_size; ++i)
+ {
+ T *elem = array.at(i).get();
+ jobject object = ctor(env, clazz, clazz_ctor, elem);
+ if (!object)
+ {
+ throw std::runtime_error("cannot create instance of class\n");
+ }
+ env->CallBooleanMethod(result, arraylist_add, object);
+ }
+ return result;
+}
+
void raise_java_exception(JNIEnv *env, std::exception &e);
void raise_java_runtime_exception(JNIEnv *env, std::runtime_error &e);
+void raise_java_runtime_exception(JNIEnv *env, direct_bt::RuntimeException &e);
void raise_java_oom_exception(JNIEnv *env, std::bad_alloc &e);
void raise_java_invalid_arg_exception(JNIEnv *env, std::invalid_argument &e);
+void raise_java_bluetooth_exception(JNIEnv *env, direct_bt::BluetoothException &e);
+
+void exception_check_raise_and_throw(JNIEnv *env, const char* file, int line);
+
+#define CATCH_EXCEPTION_AND_RAISE_JAVA(env, e) \
+ catch (std::bad_alloc &e) { \
+ raise_java_oom_exception(env, e); \
+} catch (direct_bt::BluetoothException &e) { \
+ raise_java_bluetooth_exception(env, e); \
+} catch (direct_bt::RuntimeException &e) { \
+ raise_java_runtime_exception(env, e); \
+} catch (std::runtime_error &e) { \
+ raise_java_runtime_exception(env, e); \
+} catch (std::invalid_argument &e) { \
+ raise_java_invalid_arg_exception(env, e); \
+} catch (std::exception &e) { \
+ raise_java_exception(env, e); \
+}
+
+#endif /* HELPER_BASE_HPP_ */