diff --git a/simpleble/src/backends/android/PeripheralBase.cpp b/simpleble/src/backends/android/PeripheralBase.cpp index b01a89bb..e2b32624 100644 --- a/simpleble/src/backends/android/PeripheralBase.cpp +++ b/simpleble/src/backends/android/PeripheralBase.cpp @@ -9,8 +9,6 @@ #include "CommonUtils.h" #include "LoggingInternal.h" -#include - using namespace SimpleBLE; using namespace std::chrono_literals; @@ -21,7 +19,7 @@ PeripheralBase::PeripheralBase(Android::ScanResult scan_result) : _device(scan_r _gatt.discoverServices(); } else { // TODO: Whatever cleanup is necessary when disconnected. - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", "Disconnected from device"); + SIMPLEBLE_LOG_INFO("Disconnected from device"); SAFE_CALLBACK_CALL(callback_on_disconnected_); } }); @@ -100,8 +98,7 @@ std::vector PeripheralBase::advertised_services() { return std::vector< std::map PeripheralBase::manufacturer_data() { return std::map(); } ByteArray PeripheralBase::read(BluetoothUUID const& service, BluetoothUUID const& characteristic) { - auto msg = "Reading characteristic " + characteristic; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Reading characteristic " + characteristic); auto characteristic_obj = _fetch_characteristic(service, characteristic); @@ -116,8 +113,7 @@ ByteArray PeripheralBase::read(BluetoothUUID const& service, BluetoothUUID const void PeripheralBase::write_request(BluetoothUUID const& service, BluetoothUUID const& characteristic, ByteArray const& data) { - auto msg = "Writing request to characteristic " + characteristic; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Writing request to characteristic " + characteristic); auto characteristic_obj = _fetch_characteristic(service, characteristic); @@ -133,8 +129,7 @@ void PeripheralBase::write_request(BluetoothUUID const& service, BluetoothUUID c void PeripheralBase::write_command(BluetoothUUID const& service, BluetoothUUID const& characteristic, ByteArray const& data) { - auto msg = "Writing command to characteristic " + characteristic; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Writing command to characteristic " + characteristic); auto characteristic_obj = _fetch_characteristic(service, characteristic); @@ -150,8 +145,7 @@ void PeripheralBase::write_command(BluetoothUUID const& service, BluetoothUUID c void PeripheralBase::notify(BluetoothUUID const& service, BluetoothUUID const& characteristic, std::function callback) { - auto msg = "Subscribing to characteristic " + characteristic; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Subscribing to characteristic " + characteristic); auto characteristic_obj = _fetch_characteristic(service, characteristic); auto descriptor_obj = _fetch_descriptor(service, characteristic, @@ -177,8 +171,7 @@ void PeripheralBase::notify(BluetoothUUID const& service, BluetoothUUID const& c void PeripheralBase::indicate(BluetoothUUID const& service, BluetoothUUID const& characteristic, std::function callback) { - auto msg = "Subscribing to characteristic " + characteristic; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Subscribing to characteristic " + characteristic); auto characteristic_obj = _fetch_characteristic(service, characteristic); auto descriptor_obj = _fetch_descriptor(service, characteristic, @@ -203,8 +196,7 @@ void PeripheralBase::indicate(BluetoothUUID const& service, BluetoothUUID const& } void PeripheralBase::unsubscribe(BluetoothUUID const& service, BluetoothUUID const& characteristic) { - auto msg = "Unsubscribing from characteristic " + characteristic; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Unsubscribing from characteristic " + characteristic); auto characteristic_obj = _fetch_characteristic(service, characteristic); auto descriptor_obj = _fetch_descriptor(service, characteristic, @@ -226,8 +218,7 @@ void PeripheralBase::unsubscribe(BluetoothUUID const& service, BluetoothUUID con ByteArray PeripheralBase::read(BluetoothUUID const& service, BluetoothUUID const& characteristic, BluetoothUUID const& descriptor) { - auto msg = "Reading descriptor " + descriptor; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Reading descriptor " + descriptor); auto descriptor_obj = _fetch_descriptor(service, characteristic, descriptor); @@ -242,8 +233,7 @@ ByteArray PeripheralBase::read(BluetoothUUID const& service, BluetoothUUID const void PeripheralBase::write(BluetoothUUID const& service, BluetoothUUID const& characteristic, BluetoothUUID const& descriptor, ByteArray const& data) { - auto msg = "Writing descriptor " + descriptor; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO("Writing descriptor " + descriptor); auto descriptor_obj = _fetch_descriptor(service, characteristic, descriptor); diff --git a/simpleble/src/backends/android/android/BluetoothDevice.cpp b/simpleble/src/backends/android/android/BluetoothDevice.cpp index d29d2cae..17571e5e 100644 --- a/simpleble/src/backends/android/android/BluetoothDevice.cpp +++ b/simpleble/src/backends/android/android/BluetoothDevice.cpp @@ -34,11 +34,22 @@ BluetoothDevice::BluetoothDevice(JNI::Object obj) : _obj(obj) { initialize(); }; -std::string BluetoothDevice::getAddress() { return _obj.call_string_method(_method_getAddress); } +void BluetoothDevice::check_initialized() const { + if (!_obj) throw std::runtime_error("BluetoothDevice is not initialized"); +} + +std::string BluetoothDevice::getAddress() { + check_initialized(); + return _obj.call_string_method(_method_getAddress); +} -std::string BluetoothDevice::getName() { return _obj.call_string_method(_method_getName); } +std::string BluetoothDevice::getName() { + check_initialized(); + return _obj.call_string_method(_method_getName); +} BluetoothGatt BluetoothDevice::connectGatt(bool autoConnect, Bridge::BluetoothGattCallback& callback) { + check_initialized(); return BluetoothGatt(_obj.call_object_method(_method_connectGatt, nullptr, autoConnect, callback.get())); } diff --git a/simpleble/src/backends/android/android/BluetoothDevice.h b/simpleble/src/backends/android/android/BluetoothDevice.h index b38fc6c0..0a97186c 100644 --- a/simpleble/src/backends/android/android/BluetoothDevice.h +++ b/simpleble/src/backends/android/android/BluetoothDevice.h @@ -24,7 +24,7 @@ class BluetoothDevice { static jmethodID _method_connectGatt; static void initialize(); - + void check_initialized() const; JNI::Object _obj; }; diff --git a/simpleble/src/backends/android/android/BluetoothGatt.cpp b/simpleble/src/backends/android/android/BluetoothGatt.cpp index 2fefc5c7..7d821e1d 100644 --- a/simpleble/src/backends/android/android/BluetoothGatt.cpp +++ b/simpleble/src/backends/android/android/BluetoothGatt.cpp @@ -69,32 +69,37 @@ BluetoothGatt::BluetoothGatt() { initialize(); } BluetoothGatt::BluetoothGatt(JNI::Object obj) : BluetoothGatt() { _obj = obj; } + +void BluetoothGatt::check_initialized() const { + if (!_obj) throw std::runtime_error("BluetoothGatt is not initialized"); +} + void BluetoothGatt::close() { - if (!_obj) return; + check_initialized(); _obj.call_void_method(_method_close); } bool BluetoothGatt::connect() { - if (!_obj) return false; + check_initialized(); return _obj.call_boolean_method(_method_connect); } void BluetoothGatt::disconnect() { - if (!_obj) return; + check_initialized(); _obj.call_void_method(_method_disconnect); } bool BluetoothGatt::discoverServices() { - if (!_obj) return false; + check_initialized(); return _obj.call_boolean_method(_method_discoverServices); } std::vector BluetoothGatt::getServices() { - if (!_obj) return std::vector(); + check_initialized(); JNI::Object services = _obj.call_object_method("getServices", "()Ljava/util/List;"); if (!services) return std::vector(); @@ -113,31 +118,31 @@ std::vector BluetoothGatt::getServices() { } bool BluetoothGatt::readCharacteristic(BluetoothGattCharacteristic characteristic) { - if (!_obj) return false; + check_initialized(); return _obj.call_boolean_method(_method_readCharacteristic, characteristic.getObject().get()); } bool BluetoothGatt::readDescriptor(BluetoothGattDescriptor descriptor) { - if (!_obj) return false; + check_initialized(); return _obj.call_boolean_method(_method_readDescriptor, descriptor.getObject().get()); } bool BluetoothGatt::setCharacteristicNotification(BluetoothGattCharacteristic characteristic, bool enable) { - if (!_obj) return false; + check_initialized(); return _obj.call_boolean_method(_method_setCharacteristicNotification, characteristic.getObject().get(), enable); } bool BluetoothGatt::writeCharacteristic(BluetoothGattCharacteristic characteristic) { - if (!_obj) return false; + check_initialized(); return _obj.call_boolean_method(_method_writeCharacteristic, characteristic.getObject().get()); } bool BluetoothGatt::writeDescriptor(BluetoothGattDescriptor descriptor) { - if (!_obj) return false; + check_initialized(); return _obj.call_boolean_method(_method_writeDescriptor, descriptor.getObject().get()); } diff --git a/simpleble/src/backends/android/android/BluetoothGatt.h b/simpleble/src/backends/android/android/BluetoothGatt.h index 5fbeabc8..c4a99545 100644 --- a/simpleble/src/backends/android/android/BluetoothGatt.h +++ b/simpleble/src/backends/android/android/BluetoothGatt.h @@ -56,7 +56,7 @@ class BluetoothGatt { static jmethodID _method_writeDescriptor; static void initialize(); - + void check_initialized() const; JNI::Object _obj; }; diff --git a/simpleble/src/backends/android/android/BluetoothGattCharacteristic.cpp b/simpleble/src/backends/android/android/BluetoothGattCharacteristic.cpp index 697e1515..23c7d880 100644 --- a/simpleble/src/backends/android/android/BluetoothGattCharacteristic.cpp +++ b/simpleble/src/backends/android/android/BluetoothGattCharacteristic.cpp @@ -76,6 +76,10 @@ void BluetoothGattCharacteristic::initialize() { } } +void BluetoothGattCharacteristic::check_initialized() const { + if (!_obj) throw std::runtime_error("BluetoothGattCharacteristic is not initialized"); +} + BluetoothGattCharacteristic::BluetoothGattCharacteristic() { initialize(); } BluetoothGattCharacteristic::BluetoothGattCharacteristic(JNI::Object obj) : BluetoothGattCharacteristic() { @@ -93,10 +97,10 @@ BluetoothGattCharacteristic::BluetoothGattCharacteristic(JNI::Object obj) : Blue // } // std::vector BluetoothGattCharacteristic::getDescriptors() { - if (!_obj) return std::vector(); + check_initialized(); JNI::Object descriptors = _obj.call_object_method(_method_getDescriptors); - if (!descriptors) return std::vector(); + if (!descriptors) throw std::runtime_error("Failed to get descriptors"); std::vector result; JNI::Object iterator = descriptors.call_object_method("iterator", "()Ljava/util/Iterator;"); @@ -110,28 +114,43 @@ std::vector BluetoothGattCharacteristic::getDescriptors return result; } -int BluetoothGattCharacteristic::getInstanceId() { return _obj.call_int_method(_method_getInstanceId); } +int BluetoothGattCharacteristic::getInstanceId() { + check_initialized(); + return _obj.call_int_method(_method_getInstanceId); +} -int BluetoothGattCharacteristic::getPermissions() { return _obj.call_int_method(_method_getPermissions); } +int BluetoothGattCharacteristic::getPermissions() { + check_initialized(); + return _obj.call_int_method(_method_getPermissions); +} -int BluetoothGattCharacteristic::getProperties() { return _obj.call_int_method(_method_getProperties); } +int BluetoothGattCharacteristic::getProperties() { + check_initialized(); + return _obj.call_int_method(_method_getProperties); +} std::string BluetoothGattCharacteristic::getUuid() { - if (!_obj) return ""; + check_initialized(); JNI::Object uuidObj = _obj.call_object_method(_method_getUuid); - if (!uuidObj) return ""; + if (!uuidObj) throw std::runtime_error("Failed to get UUID"); return UUID(uuidObj).toString(); } -int BluetoothGattCharacteristic::getWriteType() { return _obj.call_int_method(_method_getWriteType); } +int BluetoothGattCharacteristic::getWriteType() { + check_initialized(); + return _obj.call_int_method(_method_getWriteType); +} void BluetoothGattCharacteristic::setWriteType(int writeType) { + check_initialized(); _obj.call_void_method(_method_setWriteType, writeType); } bool BluetoothGattCharacteristic::setValue(const std::vector& value) { + check_initialized(); + JNI::Env env; jbyteArray array = JNI::Types::toJByteArray(value); diff --git a/simpleble/src/backends/android/android/BluetoothGattCharacteristic.h b/simpleble/src/backends/android/android/BluetoothGattCharacteristic.h index 507db989..4cf06c49 100644 --- a/simpleble/src/backends/android/android/BluetoothGattCharacteristic.h +++ b/simpleble/src/backends/android/android/BluetoothGattCharacteristic.h @@ -9,6 +9,7 @@ namespace SimpleBLE { namespace Android { class BluetoothGattCharacteristic { + // See: https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic public: BluetoothGattCharacteristic(); BluetoothGattCharacteristic(JNI::Object obj); @@ -16,12 +17,14 @@ class BluetoothGattCharacteristic { // bool addDescriptor(BluetoothGattDescriptor descriptor); // BluetoothGattDescriptor getDescriptor(std::string uuid); std::vector getDescriptors(); + int getInstanceId(); int getPermissions(); int getProperties(); std::string getUuid(); int getWriteType(); void setWriteType(int writeType); + bool setValue(const std::vector& value); JNI::Object getObject() const { return _obj; } @@ -50,7 +53,8 @@ class BluetoothGattCharacteristic { static jmethodID _method_setWriteType; static jmethodID _method_setValue; - void initialize(); + static void initialize(); + void check_initialized() const; }; } // namespace Android diff --git a/simpleble/src/backends/android/android/BluetoothGattDescriptor.cpp b/simpleble/src/backends/android/android/BluetoothGattDescriptor.cpp index 0274c77e..5616c86f 100644 --- a/simpleble/src/backends/android/android/BluetoothGattDescriptor.cpp +++ b/simpleble/src/backends/android/android/BluetoothGattDescriptor.cpp @@ -34,27 +34,31 @@ void BluetoothGattDescriptor::initialize() { } } +void BluetoothGattDescriptor::check_initialized() const { + if (!_obj) throw std::runtime_error("BluetoothGattDescriptor is not initialized"); +} + BluetoothGattDescriptor::BluetoothGattDescriptor() { initialize(); } BluetoothGattDescriptor::BluetoothGattDescriptor(JNI::Object obj) : BluetoothGattDescriptor() { _obj = obj; } std::string BluetoothGattDescriptor::getUuid() { - if (!_obj) return ""; + check_initialized(); JNI::Object uuidObj = _obj.call_object_method(_method_getUuid); - if (!uuidObj) return ""; + if (!uuidObj) throw std::runtime_error("Failed to get UUID"); return UUID(uuidObj).toString(); } std::vector BluetoothGattDescriptor::getValue() { - if (!_obj) return {}; + check_initialized(); return _obj.call_byte_array_method(_method_getValue); } bool BluetoothGattDescriptor::setValue(const std::vector &value) { - if (!_obj) return false; + check_initialized(); JNI::Env env; jbyteArray jbyteArray_obj = env->NewByteArray(value.size()); diff --git a/simpleble/src/backends/android/android/BluetoothGattDescriptor.h b/simpleble/src/backends/android/android/BluetoothGattDescriptor.h index 73eb7c07..b5df681c 100644 --- a/simpleble/src/backends/android/android/BluetoothGattDescriptor.h +++ b/simpleble/src/backends/android/android/BluetoothGattDescriptor.h @@ -8,6 +8,7 @@ namespace SimpleBLE { namespace Android { class BluetoothGattDescriptor { + // See: https://developer.android.com/reference/android/bluetooth/BluetoothGattDescriptor public: BluetoothGattDescriptor(); BluetoothGattDescriptor(JNI::Object obj); @@ -32,7 +33,8 @@ class BluetoothGattDescriptor { static jmethodID _method_getValue; static jmethodID _method_setValue; - void initialize(); + static void initialize(); + void check_initialized() const; }; } // namespace Android diff --git a/simpleble/src/backends/android/android/BluetoothGattService.cpp b/simpleble/src/backends/android/android/BluetoothGattService.cpp index f50b32b6..bf616016 100644 --- a/simpleble/src/backends/android/android/BluetoothGattService.cpp +++ b/simpleble/src/backends/android/android/BluetoothGattService.cpp @@ -60,6 +60,10 @@ void BluetoothGattService::initialize() { } } +void BluetoothGattService::check_initialized() const { + if (!_obj) throw std::runtime_error("BluetoothGattService is not initialized"); +} + BluetoothGattService::BluetoothGattService() { initialize(); } @@ -82,17 +86,17 @@ BluetoothGattService::BluetoothGattService(JNI::Object obj) : BluetoothGattServi //} // std::vector BluetoothGattService::getCharacteristics() { - if (!_obj) return std::vector(); + check_initialized(); JNI::Object characteristics = _obj.call_object_method(_method_getCharacteristics); - if (!characteristics) return std::vector(); + if (!characteristics) throw std::runtime_error("Failed to get characteristics"); std::vector result; JNI::Object iterator = characteristics.call_object_method("iterator", "()Ljava/util/Iterator;"); while (iterator.call_boolean_method("hasNext", "()Z")) { JNI::Object characteristic = iterator.call_object_method("next", "()Ljava/lang/Object;"); - if (!characteristic) continue; + if (!characteristic) continue; // TODO: Should we throw an error here? result.push_back(BluetoothGattCharacteristic(characteristic)); } @@ -105,15 +109,21 @@ std::vector BluetoothGattService::getCharacteristic // return JNI::convert_list(listObj); //} -int BluetoothGattService::getInstanceId() { return _obj.call_int_method(_method_getInstanceId); } +int BluetoothGattService::getInstanceId() { + check_initialized(); + return _obj.call_int_method(_method_getInstanceId); +} -int BluetoothGattService::getType() { return _obj.call_int_method(_method_getType); } +int BluetoothGattService::getType() { + check_initialized(); + return _obj.call_int_method(_method_getType); +} std::string BluetoothGattService::getUuid() { - if (!_obj) return ""; + check_initialized(); JNI::Object uuidObj = _obj.call_object_method(_method_getUuid); - if (!uuidObj) return ""; + if (!uuidObj) throw std::runtime_error("Failed to get UUID"); return UUID(uuidObj).toString(); } diff --git a/simpleble/src/backends/android/android/BluetoothGattService.h b/simpleble/src/backends/android/android/BluetoothGattService.h index aa3a844b..77ab0b84 100644 --- a/simpleble/src/backends/android/android/BluetoothGattService.h +++ b/simpleble/src/backends/android/android/BluetoothGattService.h @@ -17,7 +17,7 @@ class BluetoothGattService { // bool addService(BluetoothGattService service); // BluetoothGattCharacteristic getCharacteristic(std::string uuid); std::vector getCharacteristics(); -// std::vector getIncludedServices(); +// std::vector getIncludedServices(); // TODO: This might be necessary if we don't see the secondary services in some other way. int getInstanceId(); int getType(); std::string getUuid(); @@ -36,7 +36,8 @@ class BluetoothGattService { static jmethodID _method_getType; static jmethodID _method_getUuid; - void initialize(); + static void initialize(); + void check_initialized() const; }; } // namespace Android diff --git a/simpleble/src/backends/android/bridge/BluetoothGattCallback.cpp b/simpleble/src/backends/android/bridge/BluetoothGattCallback.cpp index a977cf69..4370019d 100644 --- a/simpleble/src/backends/android/bridge/BluetoothGattCallback.cpp +++ b/simpleble/src/backends/android/bridge/BluetoothGattCallback.cpp @@ -1,7 +1,7 @@ #include "BluetoothGattCallback.h" #include -#include +#include "LoggingInternal.h" #include #include @@ -12,6 +12,15 @@ namespace Bridge { JNI::Class BluetoothGattCallback::_cls; std::map BluetoothGattCallback::_map; +#define GET_CALLBACK_OBJECT_OR_RETURN(thiz) ({ \ + auto it = BluetoothGattCallback::_map.find(thiz); \ + if (it == BluetoothGattCallback::_map.end()) { \ + SIMPLEBLE_LOG_FATAL("Failed to find BluetoothGattCallback object. This should never happen."); \ + return; \ + } \ + it->second; \ +}) + void BluetoothGattCallback::initialize() { JNI::Env env; @@ -80,11 +89,9 @@ void BluetoothGattCallback::wait_flag_characteristicWritePending(JNI::Object cha flag_data.cv.wait_for(lock, std::chrono::seconds(5), [&flag_data] { return !flag_data.flag; }); if (flag_data.flag) { - // TODO CLEANUP + // Timeout has occurred. throw std::runtime_error("Failed to write characteristic"); } - - // TODO CLEANUP } void BluetoothGattCallback::set_flag_characteristicReadPending(JNI::Object characteristic) { @@ -111,7 +118,7 @@ std::vector BluetoothGattCallback::wait_flag_characteristicReadPending( flag_data.cv.wait_for(lock, std::chrono::seconds(5), [&flag_data] { return !flag_data.flag; }); if (flag_data.flag) { - // TODO CLEANUP + // Timeout has occurred. throw std::runtime_error("Failed to read characteristic"); } @@ -140,11 +147,9 @@ void BluetoothGattCallback::wait_flag_descriptorWritePending(JNI::Object descrip flag_data.cv.wait_for(lock, std::chrono::seconds(5), [&flag_data] { return !flag_data.flag; }); if (flag_data.flag) { - // TODO CLEANUP + // Timeout has occurred. throw std::runtime_error("Failed to write descriptor"); } - - // TODO CLEANUP } void BluetoothGattCallback::set_flag_descriptorReadPending(JNI::Object descriptor) { @@ -170,25 +175,21 @@ std::vector BluetoothGattCallback::wait_flag_descriptorReadPending(JNI: flag_data.cv.wait_for(lock, std::chrono::seconds(5), [&flag_data] { return !flag_data.flag; }); if (flag_data.flag) { - // TODO CLEANUP + // Timeout has occurred. throw std::runtime_error("Failed to read descriptor"); } return flag_data.value; } +// JNI Callbacks + void BluetoothGattCallback::jni_onConnectionStateChangeCallback(JNIEnv* env, jobject thiz, jobject gatt, jint status, jint new_state) { auto msg = fmt::format("onConnectionStateChangeCallback status: {} new_state: {}", status, new_state); - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg.c_str()); + SIMPLEBLE_LOG_INFO(msg); - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } - - BluetoothGattCallback* obj = it->second; + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); const bool connected = new_state == 2; obj->connected = connected; SAFE_CALLBACK_CALL(obj->_callback_onConnectionStateChange, connected); @@ -196,15 +197,9 @@ void BluetoothGattCallback::jni_onConnectionStateChangeCallback(JNIEnv* env, job void BluetoothGattCallback::jni_onServicesDiscoveredCallback(JNIEnv* env, jobject thiz, jobject gatt, jint status) { auto msg = "onServicesDiscoveredCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } - - BluetoothGattCallback* obj = it->second; + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); obj->services_discovered = true; SAFE_CALLBACK_CALL(obj->_callback_onServicesDiscovered); } @@ -212,27 +207,17 @@ void BluetoothGattCallback::jni_onServicesDiscoveredCallback(JNIEnv* env, jobjec void BluetoothGattCallback::jni_onServiceChangedCallback(JNIEnv* env, jobject thiz, jobject gatt) { // NOTE: If this one gets triggered we're kinda screwed. auto msg = "onServiceChangedCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); } void BluetoothGattCallback::jni_onCharacteristicChangedCallback(JNIEnv* env, jobject thiz, jobject gatt, jobject characteristic, jbyteArray value) { auto msg = "onCharacteristicChangedCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); - - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } + SIMPLEBLE_LOG_INFO(msg); - BluetoothGattCallback* obj = it->second; + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); auto& callback = obj->_callback_onCharacteristicChanged[characteristic]; if (callback) { std::vector data = JNI::Types::fromJByteArray(value); @@ -243,97 +228,76 @@ void BluetoothGattCallback::jni_onCharacteristicChangedCallback(JNIEnv* env, job void BluetoothGattCallback::jni_onCharacteristicReadCallback(JNIEnv* env, jobject thiz, jobject gatt, jobject characteristic, jbyteArray value, jint status) { auto msg = "onCharacteristicReadCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); - - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } + SIMPLEBLE_LOG_INFO(msg); - BluetoothGattCallback* obj = it->second; + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); obj->clear_flag_characteristicReadPending(characteristic, JNI::Types::fromJByteArray(value)); } void BluetoothGattCallback::jni_onCharacteristicWriteCallback(JNIEnv* env, jobject thiz, jobject gatt, jobject characteristic, jint status) { auto msg = "onCharacteristicWriteCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } - - BluetoothGattCallback* obj = it->second; + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); obj->clear_flag_characteristicWritePending(characteristic); } void BluetoothGattCallback::jni_onDescriptorReadCallback(JNIEnv* env, jobject thiz, jobject gatt, jobject descriptor, jbyteArray value, jint status) { auto msg = "onDescriptorReadCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); - - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } + SIMPLEBLE_LOG_INFO(msg); - BluetoothGattCallback* obj = it->second; + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); obj->clear_flag_descriptorReadPending(descriptor, JNI::Types::fromJByteArray(value)); } void BluetoothGattCallback::jni_onDescriptorWriteCallback(JNIEnv* env, jobject thiz, jobject gatt, jobject descriptor, jint status) { auto msg = "onDescriptorWriteCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); - - auto it = BluetoothGattCallback::_map.find(thiz); - if (it == BluetoothGattCallback::_map.end()) { - // TODO: Throw an exception - return; - } + SIMPLEBLE_LOG_INFO(msg); - BluetoothGattCallback* obj = it->second; + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); obj->clear_flag_descriptorWritePending(descriptor); } void BluetoothGattCallback::jni_onMtuChangedCallback(JNIEnv* env, jobject thiz, jobject gatt, jint mtu, jint status) { auto msg = "onMtuChangedCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); - auto it = BluetoothGattCallback::_map.find(thiz); - if (it != BluetoothGattCallback::_map.end()) { - BluetoothGattCallback* obj = it->second; - obj->mtu = mtu; - } else { - // TODO: Throw an exception - } + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); + obj->mtu = mtu; } void BluetoothGattCallback::jni_onPhyReadCallback(JNIEnv* env, jobject thiz, jobject gatt, jint tx_phy, jint rx_phy, jint status) { auto msg = "onPhyReadCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); + + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); } void BluetoothGattCallback::jni_onPhyUpdateCallback(JNIEnv* env, jobject thiz, jobject gatt, jint tx_phy, jint rx_phy, jint status) { auto msg = "onPhyUpdateCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); + + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); } void BluetoothGattCallback::jni_onReadRemoteRssiCallback(JNIEnv* env, jobject thiz, jobject gatt, jint rssi, jint status) { auto msg = "onReadRemoteRssiCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); + + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); } void BluetoothGattCallback::jni_onReliableWriteCompletedCallback(JNIEnv* env, jobject thiz, jobject gatt, jint status) { auto msg = "onReliableWriteCompletedCallback"; - __android_log_write(ANDROID_LOG_INFO, "SimpleBLE", msg); + SIMPLEBLE_LOG_INFO(msg); + + BluetoothGattCallback* obj = GET_CALLBACK_OBJECT_OR_RETURN(thiz); } } // namespace Bridge diff --git a/simpleble/src/backends/android/bridge/BluetoothGattCallback.h b/simpleble/src/backends/android/bridge/BluetoothGattCallback.h index ffad0e4a..95be425d 100644 --- a/simpleble/src/backends/android/bridge/BluetoothGattCallback.h +++ b/simpleble/src/backends/android/bridge/BluetoothGattCallback.h @@ -66,7 +66,7 @@ class BluetoothGattCallback { private: struct FlagData { - bool flag; + bool flag = false; std::condition_variable cv; std::mutex mtx; std::vector value; diff --git a/simpleble/src/backends/android/jni/Common.hpp b/simpleble/src/backends/android/jni/Common.hpp index 0ef6c775..5e015088 100644 --- a/simpleble/src/backends/android/jni/Common.hpp +++ b/simpleble/src/backends/android/jni/Common.hpp @@ -96,7 +96,7 @@ class Object { env->ReleaseByteArrayElements(jarr, arr, JNI_ABORT); return result; } - + template @@ -243,6 +243,8 @@ class Env { // TODO: Move these to their own namespace struct JObjectComparator { + // TODO: Lazy initialize jclass and jmethodID objects. + bool operator()(const jobject& lhs, const jobject& rhs) const { if (lhs == nullptr && rhs == nullptr) { return false; // Both are null, considered equal @@ -278,6 +280,8 @@ struct JObjectComparator { }; struct JniObjectComparator { + // TODO: Lazy initialize jclass and jmethodID objects. + bool operator()(const Object& lhs, const Object& rhs) const { // Handle null object comparisons if (!lhs && !rhs) { diff --git a/simpledroidble/.idea/compiler.xml b/simpledroidble/.idea/compiler.xml index b589d56e..b86273d9 100644 --- a/simpledroidble/.idea/compiler.xml +++ b/simpledroidble/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/simpledroidble/.idea/gradle.xml b/simpledroidble/.idea/gradle.xml index 653550da..dadc8747 100644 --- a/simpledroidble/.idea/gradle.xml +++ b/simpledroidble/.idea/gradle.xml @@ -4,10 +4,23 @@