Skip to content
This repository was archived by the owner on Jan 4, 2023. It is now read-only.

Commit 6e580f4

Browse files
committed
java: Add notifications for ManufacturerData, ServiceData and ServicesResolved
Signed-off-by: Petre Eftime <[email protected]>
1 parent 52a0b06 commit 6e580f4

File tree

2 files changed

+233
-0
lines changed

2 files changed

+233
-0
lines changed

java/BluetoothDevice.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,42 @@ public BluetoothGattService find(String UUID) {
275275
*/
276276
public native Map<Short, byte[]> getManufacturerData();
277277

278+
/**
279+
* Enables notifications for the manufacturer data property and calls run function of the
280+
* BluetoothNotification object.
281+
* @param callback A BluetoothNotification<Map<Short, byte[]> > object. Its run function will be called
282+
* when a notification is issued. The run function will deliver the new value of the manufacturer data
283+
* property.
284+
*/
285+
public native void enableManufacturerDataNotifications(BluetoothNotification<Map<Short, byte[]> > callback);
286+
/**
287+
* Disables notifications of the manufacturer data property and unregisters the callback
288+
* object passed through the corresponding enable method.
289+
*/
290+
public native void disableManufacturerDataNotifications();
291+
292+
278293
/** Returns a map containing service advertisement data.
279294
* An entry has a UUID string key and an array of bytes.
280295
* @return service advertisement data.
281296
*/
282297
public native Map<String, byte[]> getServiceData();
283298

299+
/**
300+
* Enables notifications for the service data property and calls run function of the
301+
* BluetoothNotification object.
302+
* @param callback A BluetoothNotification<Map<String, byte[]> > object. Its run function will be called
303+
* when a notification is issued. The run function will deliver the new value of the service data
304+
* property.
305+
*/
306+
public native void enableServiceDataNotifications(BluetoothNotification<Map<String, byte[]> > callback);
307+
/**
308+
* Disables notifications of the service data property and unregisters the callback
309+
* object passed through the corresponding enable method.
310+
*/
311+
public native void disableServiceDataNotifications();
312+
313+
284314
/** Returns the transmission power level (0 means unknown).
285315
* @return the transmission power level (0 means unknown).
286316
*/
@@ -291,10 +321,25 @@ public BluetoothGattService find(String UUID) {
291321
*/
292322
public native boolean getServicesResolved ();
293323

324+
/**
325+
* Enables notifications for the services resolved property and calls run function of the
326+
* BluetoothNotification object.
327+
* @param callback A BluetoothNotification<Boolean> object. Its run function will be called
328+
* when a notification is issued. The run function will deliver the new value of the services resolved
329+
* property.
330+
*/
331+
public native void enableServicesResolvedNotifications(BluetoothNotification<Boolean> callback);
332+
/**
333+
* Disables notifications of the services resolved property and unregisters the callback
334+
* object passed through the corresponding enable method.
335+
*/
336+
public native void disableServicesResolvedNotifications();
337+
294338
private native void delete();
295339

296340
private BluetoothDevice(long instance)
297341
{
298342
super(instance);
299343
}
344+
300345
}

java/jni/BluetoothDevice.cxx

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,75 @@ jobject Java_tinyb_BluetoothDevice_getManufacturerData(JNIEnv *env, jobject obj)
910910
return nullptr;
911911
}
912912

913+
void Java_tinyb_BluetoothDevice_enableManufacturerDataNotifications(JNIEnv *env, jobject obj, jobject callback)
914+
{
915+
try {
916+
BluetoothDevice *obj_device =
917+
getInstance<BluetoothDevice>(env, obj);
918+
std::shared_ptr<JNIGlobalRef> callback_ptr(new JNIGlobalRef(callback));
919+
obj_device->enable_manufacturer_data_notifications([ callback_ptr ] (std::map<uint16_t, std::vector<uint8_t>> v)
920+
{
921+
jclass notification = search_class(*jni_env, **callback_ptr);
922+
jmethodID method = search_method(*jni_env, notification, "run", "(Ljava/lang/Object;)V", false);
923+
924+
jclass map_cls = search_class(*jni_env, "java/util/HashMap");
925+
jmethodID map_ctor = search_method(*jni_env, map_cls, "<init>",
926+
"(I)V", false);
927+
jmethodID map_put = search_method(*jni_env, map_cls, "put",
928+
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
929+
false);
930+
931+
jclass short_cls = search_class(*jni_env, "java/lang/Short");
932+
jmethodID short_ctor = search_method(*jni_env, short_cls, "<init>",
933+
"(S)V", false);
934+
935+
jobject result = jni_env->NewObject(map_cls, map_ctor, v.size());
936+
937+
for (auto it: v) {
938+
jbyteArray arr = jni_env->NewByteArray(it.second.size());
939+
jni_env->SetByteArrayRegion(arr, 0, it.second.size(), (const jbyte *)it.second.data());
940+
jobject key = jni_env->NewObject(short_cls, short_ctor, it.first);
941+
jni_env->CallObjectMethod(result, map_put, key, arr);
942+
943+
jni_env->DeleteLocalRef(arr);
944+
jni_env->DeleteLocalRef(key);
945+
}
946+
947+
jni_env->CallVoidMethod(**callback_ptr, method, result);
948+
949+
});
950+
} catch (std::bad_alloc &e) {
951+
raise_java_oom_exception(env, e);
952+
} catch (BluetoothException &e) {
953+
raise_java_bluetooth_exception(env, e);
954+
} catch (std::runtime_error &e) {
955+
raise_java_runtime_exception(env, e);
956+
} catch (std::invalid_argument &e) {
957+
raise_java_invalid_arg_exception(env, e);
958+
} catch (std::exception &e) {
959+
raise_java_exception(env, e);
960+
}
961+
}
962+
963+
void Java_tinyb_BluetoothDevice_disableManufacturerDataNotifications(JNIEnv *env, jobject obj)
964+
{
965+
try {
966+
BluetoothDevice *obj_device =
967+
getInstance<BluetoothDevice>(env, obj);
968+
obj_device->disable_service_data_notifications();
969+
} catch (std::bad_alloc &e) {
970+
raise_java_oom_exception(env, e);
971+
} catch (BluetoothException &e) {
972+
raise_java_bluetooth_exception(env, e);
973+
} catch (std::runtime_error &e) {
974+
raise_java_runtime_exception(env, e);
975+
} catch (std::invalid_argument &e) {
976+
raise_java_invalid_arg_exception(env, e);
977+
} catch (std::exception &e) {
978+
raise_java_exception(env, e);
979+
}
980+
}
981+
913982
jobject Java_tinyb_BluetoothDevice_getServiceData(JNIEnv *env, jobject obj)
914983
{
915984
try {
@@ -955,6 +1024,73 @@ jobject Java_tinyb_BluetoothDevice_getServiceData(JNIEnv *env, jobject obj)
9551024
return nullptr;
9561025
}
9571026

1027+
void Java_tinyb_BluetoothDevice_enableServiceDataNotifications(JNIEnv *env, jobject obj, jobject callback)
1028+
{
1029+
try {
1030+
BluetoothDevice *obj_device =
1031+
getInstance<BluetoothDevice>(env, obj);
1032+
std::shared_ptr<JNIGlobalRef> callback_ptr(new JNIGlobalRef(callback));
1033+
obj_device->enable_service_data_notifications([ callback_ptr ] (std::map<std::string, std::vector<uint8_t>> v)
1034+
{
1035+
jclass notification = search_class(*jni_env, **callback_ptr);
1036+
jmethodID method = search_method(*jni_env, notification, "run", "(Ljava/lang/Object;)V", false);
1037+
1038+
jclass map_cls = search_class(*jni_env, "java/util/HashMap");
1039+
jmethodID map_ctor = search_method(*jni_env, map_cls, "<init>",
1040+
"(I)V", false);
1041+
jmethodID map_put = search_method(*jni_env, map_cls, "put",
1042+
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
1043+
false);
1044+
1045+
jobject result = jni_env->NewObject(map_cls, map_ctor, v.size());
1046+
1047+
for (auto it: v) {
1048+
jbyteArray arr = jni_env->NewByteArray(it.second.size());
1049+
jni_env->SetByteArrayRegion(arr, 0, it.second.size(), (const jbyte *)it.second.data());
1050+
jobject key = jni_env->NewStringUTF(it.first.c_str());
1051+
jni_env->CallObjectMethod(result, map_put, key, arr);
1052+
1053+
jni_env->DeleteLocalRef(arr);
1054+
jni_env->DeleteLocalRef(key);
1055+
}
1056+
1057+
jni_env->CallVoidMethod(**callback_ptr, method, result);
1058+
1059+
});
1060+
} catch (std::bad_alloc &e) {
1061+
raise_java_oom_exception(env, e);
1062+
} catch (BluetoothException &e) {
1063+
raise_java_bluetooth_exception(env, e);
1064+
} catch (std::runtime_error &e) {
1065+
raise_java_runtime_exception(env, e);
1066+
} catch (std::invalid_argument &e) {
1067+
raise_java_invalid_arg_exception(env, e);
1068+
} catch (std::exception &e) {
1069+
raise_java_exception(env, e);
1070+
}
1071+
}
1072+
1073+
void Java_tinyb_BluetoothDevice_disableServiceDataNotifications(JNIEnv *env, jobject obj)
1074+
{
1075+
try {
1076+
BluetoothDevice *obj_device =
1077+
getInstance<BluetoothDevice>(env, obj);
1078+
obj_device->disable_service_data_notifications();
1079+
} catch (std::bad_alloc &e) {
1080+
raise_java_oom_exception(env, e);
1081+
} catch (BluetoothException &e) {
1082+
raise_java_bluetooth_exception(env, e);
1083+
} catch (std::runtime_error &e) {
1084+
raise_java_runtime_exception(env, e);
1085+
} catch (std::invalid_argument &e) {
1086+
raise_java_invalid_arg_exception(env, e);
1087+
} catch (std::exception &e) {
1088+
raise_java_exception(env, e);
1089+
}
1090+
}
1091+
1092+
1093+
9581094
jshort Java_tinyb_BluetoothDevice_getTXPower(JNIEnv *env, jobject obj)
9591095
{
9601096
try {
@@ -995,6 +1131,58 @@ jboolean Java_tinyb_BluetoothDevice_getServicesResolved(JNIEnv *env, jobject obj
9951131
return JNI_FALSE;
9961132
}
9971133

1134+
void Java_tinyb_BluetoothDevice_enableServicesResolvedNotifications(JNIEnv *env, jobject obj, jobject callback)
1135+
{
1136+
try {
1137+
BluetoothDevice *obj_device =
1138+
getInstance<BluetoothDevice>(env, obj);
1139+
std::shared_ptr<JNIGlobalRef> callback_ptr(new JNIGlobalRef(callback));
1140+
obj_device->enable_services_resolved_notifications([ callback_ptr ] (bool v)
1141+
{
1142+
jclass notification = search_class(*jni_env, **callback_ptr);
1143+
jmethodID method = search_method(*jni_env, notification, "run", "(Ljava/lang/Object;)V", false);
1144+
jclass boolean_cls = search_class(*jni_env, "java/lang/Boolean");
1145+
jmethodID constructor = search_method(*jni_env, boolean_cls, "<init>", "(Z)V", false);
1146+
1147+
jobject result = jni_env->NewObject(boolean_cls, constructor, v ? JNI_TRUE : JNI_FALSE);
1148+
1149+
jni_env->CallVoidMethod(**callback_ptr, method, result);
1150+
1151+
});
1152+
} catch (std::bad_alloc &e) {
1153+
raise_java_oom_exception(env, e);
1154+
} catch (BluetoothException &e) {
1155+
raise_java_bluetooth_exception(env, e);
1156+
} catch (std::runtime_error &e) {
1157+
raise_java_runtime_exception(env, e);
1158+
} catch (std::invalid_argument &e) {
1159+
raise_java_invalid_arg_exception(env, e);
1160+
} catch (std::exception &e) {
1161+
raise_java_exception(env, e);
1162+
}
1163+
}
1164+
1165+
void Java_tinyb_BluetoothDevice_disableServicesResolvedNotifications(JNIEnv *env, jobject obj)
1166+
{
1167+
try {
1168+
BluetoothDevice *obj_device =
1169+
getInstance<BluetoothDevice>(env, obj);
1170+
obj_device->disable_services_resolved_notifications();
1171+
} catch (std::bad_alloc &e) {
1172+
raise_java_oom_exception(env, e);
1173+
} catch (BluetoothException &e) {
1174+
raise_java_bluetooth_exception(env, e);
1175+
} catch (std::runtime_error &e) {
1176+
raise_java_runtime_exception(env, e);
1177+
} catch (std::invalid_argument &e) {
1178+
raise_java_invalid_arg_exception(env, e);
1179+
} catch (std::exception &e) {
1180+
raise_java_exception(env, e);
1181+
}
1182+
}
1183+
1184+
1185+
9981186
void Java_tinyb_BluetoothDevice_delete(JNIEnv *env, jobject obj)
9991187
{
10001188
try {

0 commit comments

Comments
 (0)