diff options
author | Sven Gothel <[email protected]> | 2020-05-10 06:17:20 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-05-10 06:17:20 +0200 |
commit | b784da70133b4b5859bb8b6f86ab48a48a6d87af (patch) | |
tree | 28f1baa5caf8e4ce1c3fb9b3592b33398e1e7c08 /java | |
parent | 0f53fde528dea4470d152d30f33f357dde1b2e10 (diff) |
Converging Java/JNI and C++ API to match tinyb interface requirements (step-2)
- BasicTypes: Align exception names w/ Java.
- BTTypes / EInfoReport: Add getDeviceIDModalias()
- DBTManager: Add getConnectionInfo(..) and setLocalName(..)
- OctetTypes: Fix put_octets(..), removed sizeof(). Adding put/get string methods
+++
DBTTypes:
- Fix Comments
- DBTDevice: Add appearance, getConnectionInfo(), connectGATT(..) and disconnectGATT().
Last two GATT's ease association of GATTHandler w/ device for tinyb binding.
- DBTDevice: Fix defaultConnect(): Differenciate le public/random
- DBTDevice: New getConnectionInfo() - also may issue deviceUpdate callback on rssi/tx_power changes
- DBTAdapter: Add missing DBTAdapterStatusListener list declaration of previous commit.
- DBTAdapter: Add misc information access for tinyb binding.
+++
Java
- DBTAdapter: Adding more tinyb implementation code, sorting methods - ~90% complete
- DBTDevice: Adding more tinyb implementation code, sorting methods - ~70% complete
Diffstat (limited to 'java')
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 105 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTDevice.java | 181 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 84 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTDevice.cxx | 281 | ||||
-rw-r--r-- | java/jni/direct_bt/helper_dbt.cxx | 28 | ||||
-rw-r--r-- | java/jni/direct_bt/helper_dbt.hpp | 4 |
6 files changed, 548 insertions, 135 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 11795f28..71ab8394 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -58,8 +58,11 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private final long discoveringNotificationRef = 0; private BluetoothNotification<Boolean> discoverableNotification = null; + private boolean isDiscoverable = false; private BluetoothNotification<Boolean> poweredNotification = null; + private boolean isPowered = false; private BluetoothNotification<Boolean> pairableNotification = null; + private boolean isPairable = false; private boolean isOpen = false; private List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>(); @@ -100,20 +103,12 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter @Override public String getName() { return name; } - public String getInterfaceName() { - throw new UnsupportedOperationException(); // FIXME - } - @Override public BluetoothType getBluetoothType() { return class_type(); } static BluetoothType class_type() { return BluetoothType.ADAPTER; } @Override - public final BluetoothAdapter clone() - { throw new UnsupportedOperationException(); } // FIXME - - @Override public BluetoothDevice find(final String name, final String address, final long timeoutMS) { final BluetoothManager manager = DBTManager.getBluetoothManager(); return (BluetoothDevice) manager.find(BluetoothType.DEVICE, name, address, this, timeoutMS); @@ -141,19 +136,40 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter return out.toString(); } - /* property accessors: */ + /* Unsupported */ @Override - public String getAlias() { throw new UnsupportedOperationException(); } // FIXME + public long getBluetoothClass() { throw new UnsupportedOperationException(); } // FIXME @Override - public void setAlias(final String value) { throw new UnsupportedOperationException(); } // FIXME + public final BluetoothAdapter clone() { throw new UnsupportedOperationException(); } // FIXME @Override - public long getBluetoothClass() { throw new UnsupportedOperationException(); } // FIXME + public String getInterfaceName() { throw new UnsupportedOperationException(); } // FIXME @Override - public native boolean getPowered(); + public long getDiscoverableTimeout() { throw new UnsupportedOperationException(); } // FIXME + + @Override + public void setDiscoverableTimout(final long value) { throw new UnsupportedOperationException(); } // FIXME + + @Override + public long getPairableTimeout() { throw new UnsupportedOperationException(); } // FIXME + + @Override + public void setPairableTimeout(final long value) { throw new UnsupportedOperationException(); } // FIXME + + @Override + public String getModalias() { throw new UnsupportedOperationException(); } // FIXME + + @Override + public String[] getUUIDs() { throw new UnsupportedOperationException(); } // FIXME + + + /* Java callbacks */ + + @Override + public boolean getPowered() { return isPowered; } @Override public synchronized void enablePoweredNotifications(final BluetoothNotification<Boolean> callback) { @@ -166,10 +182,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } @Override - public native void setPowered(boolean value); - - @Override - public native boolean getDiscoverable(); + public boolean getDiscoverable() { return isDiscoverable; } @Override public synchronized void enableDiscoverableNotifications(final BluetoothNotification<Boolean> callback) { @@ -182,19 +195,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } @Override - public native void setDiscoverable(boolean value); - - @Override - public native long getDiscoverableTimeout(); - - @Override - public native void setDiscoverableTimout(long value); - - @Override - public native BluetoothDevice connectDevice(String address, String addressType); - - @Override - public native boolean getPairable(); + public boolean getPairable() { return isPairable; } @Override public synchronized void enablePairableNotifications(final BluetoothNotification<Boolean> callback) { @@ -206,20 +207,27 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter pairableNotification = null; } + /* Native callbacks */ + + /* Native functionality / properties */ + @Override - public native void setPairable(boolean value); + public native void setPowered(boolean value); @Override - public native long getPairableTimeout(); + public native String getAlias(); @Override - public native void setPairableTimeout(long value); + public native void setAlias(final String value); @Override - public native String[] getUUIDs(); + public native void setDiscoverable(boolean value); @Override - public native String getModalias(); + public native BluetoothDevice connectDevice(String address, String addressType); + + @Override + public native void setPairable(boolean value); /* internal */ @@ -320,21 +328,30 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter final AdapterSettings changedmask, final long timestamp) { System.err.println("Adapter.StatusListener.settings: "+oldmask+" -> "+newmask+", changed "+changedmask+" on "+a); { - final BluetoothNotification<Boolean> _poweredNotification = poweredNotification; - if( null != _poweredNotification && changedmask.isSet(AdapterSettings.SettingType.POWERED) ) { - _poweredNotification.run(newmask.isSet(AdapterSettings.SettingType.POWERED)); + if( changedmask.isSet(AdapterSettings.SettingType.POWERED) ) { + isPowered = newmask.isSet(AdapterSettings.SettingType.POWERED); + final BluetoothNotification<Boolean> _poweredNotification = poweredNotification; + if( null != _poweredNotification ) { + _poweredNotification.run(isPowered); + } } } { - final BluetoothNotification<Boolean> _discoverableNotification = discoverableNotification; - if( null != _discoverableNotification && changedmask.isSet(AdapterSettings.SettingType.DISCOVERABLE) ) { - _discoverableNotification.run(newmask.isSet(AdapterSettings.SettingType.DISCOVERABLE)); + if( changedmask.isSet(AdapterSettings.SettingType.DISCOVERABLE) ) { + isDiscoverable = newmask.isSet(AdapterSettings.SettingType.DISCOVERABLE); + final BluetoothNotification<Boolean> _discoverableNotification = discoverableNotification; + if( null != _discoverableNotification ) { + _discoverableNotification.run( isDiscoverable ); + } } } { - final BluetoothNotification<Boolean> _pairableNotification = pairableNotification; - if( null != _pairableNotification && changedmask.isSet(AdapterSettings.SettingType.BONDABLE) ) { - _pairableNotification.run(newmask.isSet(AdapterSettings.SettingType.BONDABLE)); + if( changedmask.isSet(AdapterSettings.SettingType.BONDABLE) ) { + isPairable = newmask.isSet(AdapterSettings.SettingType.BONDABLE); + final BluetoothNotification<Boolean> _pairableNotification = pairableNotification; + if( null != _pairableNotification ) { + _pairableNotification.run( isPairable ); + } } } } diff --git a/java/direct_bt/tinyb/DBTDevice.java b/java/direct_bt/tinyb/DBTDevice.java index 7e482137..75f053c4 100644 --- a/java/direct_bt/tinyb/DBTDevice.java +++ b/java/direct_bt/tinyb/DBTDevice.java @@ -153,6 +153,11 @@ public class DBTDevice extends DBTObject implements BluetoothDevice } @Override + public DBTAdapter getAdapter() { + return adapter; + } + + @Override public String getAddress() { return address; } @Override @@ -164,10 +169,6 @@ public class DBTDevice extends DBTObject implements BluetoothDevice static BluetoothType class_type() { return BluetoothType.DEVICE; } @Override - public final BluetoothDevice clone() - { throw new UnsupportedOperationException(); } // FIXME - - @Override public BluetoothGattService find(final String UUID, final long timeoutMS) { final BluetoothManager manager = DBTManager.getBluetoothManager(); return (BluetoothGattService) manager.find(BluetoothType.GATT_SERVICE, @@ -186,8 +187,8 @@ public class DBTDevice extends DBTObject implements BluetoothDevice // std::string msdstr = nullptr != msd ? msd->toString() : "MSD[null]"; final String msdstr = "MSD[null]"; out.append("Device[").append(getAddress()).append(", '").append(getName()) - .append("', age ").append(t0-ts_creation).append(" ms, lup ").append(t0-ts_update).append(" ms, rssi ").append(getRSSI()) - .append(", tx-power ").append(getTxPower()).append(", ").append(msdstr).append("]"); + .append("', age ").append(t0-ts_creation).append(" ms, lup ").append(t0-ts_update).append(" ms, connected ").append(connected) + .append(", rssi ").append(getRSSI()).append(", tx-power ").append(getTxPower()).append(", ").append(msdstr).append("]"); /** if(services.size() > 0 ) { out.append("\n"); @@ -203,6 +204,26 @@ public class DBTDevice extends DBTObject implements BluetoothDevice return out.toString(); } + /* Unsupported */ + + @Override + public int getBluetoothClass() { throw new UnsupportedOperationException(); } // FIXME + + @Override + public final BluetoothDevice clone() { throw new UnsupportedOperationException(); } // FIXME + + @Override + public boolean pair() throws BluetoothException { throw new UnsupportedOperationException(); } // FIXME + + @Override + public boolean cancelPairing() throws BluetoothException { throw new UnsupportedOperationException(); } // FIXME + + @Override + public String getAlias() { return null; } // FIXME + + @Override + public void setAlias(final String value) { throw new UnsupportedOperationException(); } // FIXME + /* internal */ private native void initImpl(); @@ -211,14 +232,19 @@ public class DBTDevice extends DBTObject implements BluetoothDevice @Override public final void enableConnectedNotifications(final BluetoothNotification<Boolean> callback) { - connectedNotifications = callback; + synchronized(userCallbackLock) { + userConnectedNotificationsCB = callback; + } + } + @Override + public final void disableConnectedNotifications() { + synchronized(userCallbackLock) { + userConnectedNotificationsCB = null; + } } - private BluetoothNotification<Boolean> connectedNotifications = null; - private boolean connected = false; @Override public final boolean getConnected() { return connected; } - // private native boolean getConnectedImpl(); @Override public final boolean disconnect() throws BluetoothException { @@ -226,8 +252,13 @@ public class DBTDevice extends DBTObject implements BluetoothDevice if( connected ) { res = disconnectImpl(); if( res ) { - connectedNotifications.run(Boolean.FALSE); + // FIXME: Split up - may offload to other thread + // Currently service resolution performed in connectImpl()! + servicesResolved = false; + userServicesResolvedNotificationsCB.run(Boolean.FALSE); + connected = false; + userConnectedNotificationsCB.run(Boolean.FALSE); } } return res; @@ -240,144 +271,152 @@ public class DBTDevice extends DBTObject implements BluetoothDevice if( !connected ) { res = connectImpl(); if( res ) { - connectedNotifications.run(Boolean.TRUE); connected = true; + userConnectedNotificationsCB.run(Boolean.TRUE); + + // FIXME: Split up - may offload to other thread + // Currently service resolution performed in connectImpl()! + servicesResolved = true; + userServicesResolvedNotificationsCB.run(Boolean.TRUE); } } return res; } private native boolean connectImpl() throws BluetoothException; - /* DBT method calls: */ - - @Override - public native boolean connectProfile(String arg_UUID) throws BluetoothException; + /* DBT Java callbacks */ @Override - public native boolean disconnectProfile(String arg_UUID) throws BluetoothException; + public final void enableRSSINotifications(final BluetoothNotification<Short> callback) { + synchronized(userCallbackLock) { + userRSSINotificationsCB = callback; + } + } @Override - public boolean pair() throws BluetoothException - { throw new UnsupportedOperationException(); } // FIXME + public final void disableRSSINotifications() { + synchronized(userCallbackLock) { + userRSSINotificationsCB = null; + } + } - @Override - public native boolean remove() throws BluetoothException; @Override - public boolean cancelPairing() throws BluetoothException - { throw new UnsupportedOperationException(); } // FIXME + public final void enableManufacturerDataNotifications(final BluetoothNotification<Map<Short, byte[]> > callback) { + synchronized(userCallbackLock) { + userManufDataNotificationsCB = callback; + } + } @Override - public native List<BluetoothGattService> getServices(); - - /* property accessors: */ + public final void disableManufacturerDataNotifications() { + synchronized(userCallbackLock) { + userManufDataNotificationsCB = null; + } + } - @Override - public String getAlias() { return null; } // FIXME @Override - public void setAlias(final String value) - { throw new UnsupportedOperationException(); } // FIXME + public final void enableServicesResolvedNotifications(final BluetoothNotification<Boolean> callback) { + synchronized(userCallbackLock) { + userServicesResolvedNotificationsCB = callback; + } + } @Override - public native int getBluetoothClass(); + public void disableServicesResolvedNotifications() { + synchronized(userCallbackLock) { + userServicesResolvedNotificationsCB = null; + } + } @Override - public native short getAppearance(); + public boolean getServicesResolved () { return servicesResolved; } @Override - public native String getIcon(); + public short getAppearance() { return appearance; } - @Override - public native boolean getPaired(); + /* DBT native callbacks */ @Override - public native void enablePairedNotifications(BluetoothNotification<Boolean> callback); + public native void enableBlockedNotifications(BluetoothNotification<Boolean> callback); @Override - public native void disablePairedNotifications(); + public void disableBlockedNotifications() { } // FIXME @Override - public native boolean getTrusted(); + public native void enableServiceDataNotifications(BluetoothNotification<Map<String, byte[]> > callback); @Override - public native void enableTrustedNotifications(BluetoothNotification<Boolean> callback); + public void disableServiceDataNotifications() { } // FIXME @Override - public native void disableTrustedNotifications(); + public native void enablePairedNotifications(BluetoothNotification<Boolean> callback); @Override - public native void setTrusted(boolean value); + public void disablePairedNotifications() { } // FIXME @Override - public native boolean getBlocked(); + public native void enableTrustedNotifications(BluetoothNotification<Boolean> callback); @Override - public native void enableBlockedNotifications(BluetoothNotification<Boolean> callback); + public void disableTrustedNotifications() { } // FIXME - @Override - public native void disableBlockedNotifications(); - @Override - public native void setBlocked(boolean value); + /* DBT native method calls: */ @Override - public native boolean getLegacyPairing(); + public native boolean connectProfile(String arg_UUID) throws BluetoothException; @Override - public native short getRSSI(); + public native boolean disconnectProfile(String arg_UUID) throws BluetoothException; - @Override - public native void enableRSSINotifications(BluetoothNotification<Short> callback); + @Override + public native boolean remove() throws BluetoothException; @Override - public native void disableRSSINotifications(); + public native List<BluetoothGattService> getServices(); - @Override - public native void disableConnectedNotifications(); + /* property accessors: */ @Override - public native String[] getUUIDs(); + public native String getIcon(); @Override - public native String getModalias(); + public native boolean getPaired(); @Override - public native DBTAdapter getAdapter(); + public native boolean getTrusted(); @Override - public native Map<Short, byte[]> getManufacturerData(); + public native void setTrusted(boolean value); @Override - public native void enableManufacturerDataNotifications(BluetoothNotification<Map<Short, byte[]> > callback); + public native boolean getBlocked(); @Override - public native void disableManufacturerDataNotifications(); - + public native void setBlocked(boolean value); @Override - public native Map<String, byte[]> getServiceData(); + public native boolean getLegacyPairing(); @Override - public native void enableServiceDataNotifications(BluetoothNotification<Map<String, byte[]> > callback); + public native short getRSSI(); @Override - public native void disableServiceDataNotifications(); + public native String[] getUUIDs(); @Override - public native short getTxPower (); + public native String getModalias(); @Override - public native boolean getServicesResolved (); + public native Map<Short, byte[]> getManufacturerData(); @Override - public final void enableServicesResolvedNotifications(final BluetoothNotification<Boolean> callback) { - servicesResolvedNotifications = callback; - } - private BluetoothNotification<Boolean> servicesResolvedNotifications = null; + public native Map<String, byte[]> getServiceData(); @Override - public native void disableServicesResolvedNotifications(); + public native short getTxPower (); @Override protected native void deleteImpl(); diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 6a8c4aa6..825285bb 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -499,3 +499,87 @@ void Java_direct_1bt_tinyb_DBTAdapter_enableDiscoveringNotifications(JNIEnv *env rethrow_and_raise_java_exception(env); } } + +// +// misc +// + +void Java_direct_1bt_tinyb_DBTAdapter_setPowered(JNIEnv *env, jobject obj, jboolean value) { + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + adapter->setPowered(JNI_TRUE == value ? true : false); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + +jstring Java_direct_1bt_tinyb_DBTAdapter_getAlias(JNIEnv *env, jobject obj) { + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + return from_string_to_jstring(env, adapter->getLocalName().getName()); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + +void Java_direct_1bt_tinyb_DBTAdapter_setAlias(JNIEnv *env, jobject obj, jstring jnewalias) { + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + std::string newalias = from_jstring_to_string(env, jnewalias); + adapter->setLocalName(newalias, std::string()); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + +void Java_direct_1bt_tinyb_DBTAdapter_setDiscoverable(JNIEnv *env, jobject obj, jboolean value) { + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + adapter->setDiscoverable(JNI_TRUE == value ? true : false); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + +jobject Java_direct_1bt_tinyb_DBTAdapter_connectDevice(JNIEnv *env, jobject obj, jstring jaddress, jstring jaddressType) { + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + std::string saddress = from_jstring_to_string(env, jaddress); + EUI48 address(saddress); + std::shared_ptr<DBTDevice> device = adapter->findDiscoveredDevice(address); + if( nullptr != device ) { + const BDAddressType addressType = fromJavaAdressTypeToBDAddressType(env, jaddressType); + const BDAddressType addressTypeDevice = device->getAddressType(); + if( addressTypeDevice != addressType ) { + // oops? + WARN_PRINT("DBTAdapter::connectDevice: AddressType mismatch, ignoring request: Requested %s, Device %s %s", + getBDAddressTypeString(addressType).c_str(), getBDAddressTypeString(addressTypeDevice).c_str(), + device->toString().c_str()); + } + std::shared_ptr<JavaAnonObj> jDeviceRef = device->getJavaObject(); + JavaGlobalObj::check(jDeviceRef, E_FILE_LINE); + + device->defaultConnect(); + return JavaGlobalObj::GetObject(jDeviceRef); + } + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + +void Java_direct_1bt_tinyb_DBTAdapter_setPairable(JNIEnv *env, jobject obj, jboolean value) { + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + adapter->setBondable(JNI_TRUE == value ? true : false); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} diff --git a/java/jni/direct_bt/DBTDevice.cxx b/java/jni/direct_bt/DBTDevice.cxx index 68634807..e5da621b 100644 --- a/java/jni/direct_bt/DBTDevice.cxx +++ b/java/jni/direct_bt/DBTDevice.cxx @@ -75,64 +75,305 @@ void Java_direct_1bt_tinyb_DBTDevice_deleteImpl(JNIEnv *env, jobject obj) } } -jshort Java_direct_1bt_tinyb_DBTDevice_getRSSI(JNIEnv *env, jobject obj) +jboolean Java_direct_1bt_tinyb_DBTDevice_disconnectImpl(JNIEnv *env, jobject obj) { try { DBTDevice *device = getInstance<DBTDevice>(env, obj); - return device->getRSSI(); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + device->disconnect(); } catch(...) { rethrow_and_raise_java_exception(env); } - return 0; + return JNI_TRUE; } -jshort Java_direct_1bt_tinyb_DBTDevice_getTxPower(JNIEnv *env, jobject obj) +jboolean Java_direct_1bt_tinyb_DBTDevice_connectImpl(JNIEnv *env, jobject obj) { try { DBTDevice *device = getInstance<DBTDevice>(env, obj); - return device->getTxPower(); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + uint16_t chandle = device->defaultConnect(); + if( 0 == chandle ) { + return JNI_FALSE; + } + std::shared_ptr<GATTHandler> gatt = device->connectGATT(); + if( nullptr != gatt ) { + // FIXME: Split up - may offload to other thread + std::vector<GATTPrimaryServiceRef> & primServices = gatt->discoverCompletePrimaryServices(); + + std::shared_ptr<GenericAccess> ga = gatt->getGenericAccess(primServices); + if( nullptr != ga ) { + env->SetShortField(obj, getField(env, obj, "appearance", "S"), static_cast<jshort>(ga->category)); + java_exception_check_and_throw(env, E_FILE_LINE); + DBG_PRINT("GATT connected to GenericAccess: %s", ga->toString().c_str()); + } +#if 0 + std::shared_ptr<DeviceInformation> di = gatt->getDeviceInformation(primServices); + if( nullptr != di ) { + DBG_PRINT("GATT connected to DeviceInformation: %s", di->toString().c_str()); + } +#endif + return JNI_TRUE; + } } catch(...) { rethrow_and_raise_java_exception(env); } - return 0; + return JNI_FALSE; } -#if 0 -jboolean Java_direct_1bt_tinyb_DBTDevice_getConnectedImpl(JNIEnv *env, jobject obj) +// +// getter +// + +jobject Java_direct_1bt_tinyb_DBTDevice_getServices(JNIEnv *env, jobject obj) { + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return nullptr; + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + +jshort Java_direct_1bt_tinyb_DBTDevice_getAppearance(JNIEnv *env, jobject obj) { try { DBTDevice *device = getInstance<DBTDevice>(env, obj); - const DBTAdapter & adapter = device->getAdapter(); - std::shared_ptr<HCISession> session = adapter.getOpenSession(); - if( nullptr == session || !session->isOpen() ) { - return JNI_FALSE; - } - return nullptr != session->findConnectedLEDevice(device->getAddress()); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return (jshort) device->getAppearance(); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return (jshort)0; +} + +jstring Java_direct_1bt_tinyb_DBTDevice_getIcon(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return nullptr; // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; // FIXME; +} + +jboolean Java_direct_1bt_tinyb_DBTDevice_getPaired(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return JNI_FALSE; // FIXME } catch(...) { rethrow_and_raise_java_exception(env); } return JNI_FALSE; } -#endif -jboolean Java_direct_1bt_tinyb_DBTDevice_disconnectImpl(JNIEnv *env, jobject obj) +jboolean Java_direct_1bt_tinyb_DBTDevice_getTrusted(JNIEnv *env, jobject obj) { try { DBTDevice *device = getInstance<DBTDevice>(env, obj); - device->disconnect(); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return JNI_FALSE; // FIXME } catch(...) { rethrow_and_raise_java_exception(env); } - return JNI_TRUE; + return JNI_FALSE; } -jboolean Java_direct_1bt_tinyb_DBTDevice_connectImpl(JNIEnv *env, jobject obj) +void Java_direct_1bt_tinyb_DBTDevice_setTrusted(JNIEnv *env, jobject obj, jboolean value) { try { DBTDevice *device = getInstance<DBTDevice>(env, obj); - return device->defaultConnect(); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + (void)value; + // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + +jboolean Java_direct_1bt_tinyb_DBTDevice_getBlocked(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return JNI_FALSE; // FIXME } catch(...) { rethrow_and_raise_java_exception(env); } return JNI_FALSE; } + +void Java_direct_1bt_tinyb_DBTDevice_setBlocked(JNIEnv *env, jobject obj, jboolean value) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + (void)value; + // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + +jboolean JNICALL Java_direct_1bt_tinyb_DBTDevice_getLegacyPairing(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return JNI_FALSE; // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return JNI_FALSE; +} + +jshort Java_direct_1bt_tinyb_DBTDevice_getRSSI(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return (jshort) device->getRSSI(); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return 0; +} + + +jobjectArray Java_direct_1bt_tinyb_DBTDevice_getUUIDs(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return nullptr; // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + +jstring Java_direct_1bt_tinyb_DBTDevice_getModalias(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return nullptr; // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + +jobject Java_direct_1bt_tinyb_DBTDevice_getManufacturerData(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return nullptr; // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + +jobject Java_direct_1bt_tinyb_DBTDevice_getServiceData(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return nullptr; // FIXME + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + +jshort Java_direct_1bt_tinyb_DBTDevice_getTxPower(JNIEnv *env, jobject obj) +{ + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + return (jshort) device->getTxPower(); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return 0; +} + +#if 0 +// +// Connected +// + +static void disableConnectedNotifications(JNIEnv *env, jobject obj, DBTManager &mgmt) +{ + InvocationFunc<bool, std::shared_ptr<MgmtEvent>> * funcptr = + getObjectRef<InvocationFunc<bool, std::shared_ptr<MgmtEvent>>>(env, obj, "connectedNotificationRef"); + if( nullptr != funcptr ) { + FunctionDef<bool, std::shared_ptr<MgmtEvent>> funcDef( funcptr ); + funcptr = nullptr; + setObjectRef(env, obj, funcptr, "connectedNotificationRef"); // clear java ref + int count; + if( 1 != ( count = mgmt.removeMgmtEventCallback(MgmtEvent::Opcode::DISCOVERING, funcDef) ) ) { + throw direct_bt::InternalError(std::string("removeMgmtEventCallback of ")+funcDef.toString()+" not 1 but "+std::to_string(count), E_FILE_LINE); + } + } +} +void Java_direct_1bt_tinyb_DBTDevice_disableConnectedNotificationsImpl(JNIEnv *env, jobject obj) +{ + // org.tinyb.BluetoothAdapterStatusListener + try { + DBTDevice *device = getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + DBTManager & mgmt = device->getAdapter().getManager(); + + disableConnectedNotifications(env, obj, mgmt); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} +void Java_direct_1bt_tinyb_DBTDevice_enableConnectedNotificationsImpl(JNIEnv *env, jobject obj, jobject javaCallback) +{ + // org.tinyb.BluetoothAdapterStatusListener + try { + DBTDevice *device= getInstance<DBTDevice>(env, obj); + JavaGlobalObj::check(device->getJavaObject(), E_FILE_LINE); + DBTAdapter & adapter = device->getAdapter(); + DBTManager & mgmt = adapter.getManager(); + + disableConnectedNotifications(env, obj, mgmt); + + bool(*nativeCallback)(JNIGlobalRef&, std::shared_ptr<MgmtEvent>) = + [](JNIGlobalRef& javaCallback_ref, std::shared_ptr<MgmtEvent> e)->bool { + const MgmtEvtConnected &event = *static_cast<const MgmtEvtConnected *>(e.get()); + + jclass notification = search_class(*jni_env, *javaCallback_ref); + jmethodID method = search_method(*jni_env, notification, "run", "(Ljava/lang/Object;)V", false); + jni_env->DeleteLocalRef(notification); + + jclass boolean_cls = search_class(*jni_env, "java/lang/Boolean"); + jmethodID constructor = search_method(*jni_env, boolean_cls, "<init>", "(Z)V", false); + + jobject result = jni_env->NewObject(boolean_cls, constructor, event.getEnabled() ? JNI_TRUE : JNI_FALSE); + jni_env->DeleteLocalRef(boolean_cls); + + jni_env->CallVoidMethod(*javaCallback_ref, method, result); + jni_env->DeleteLocalRef(result); + return true; + }; + // move JNIGlobalRef into CaptureInvocationFunc and operator== includes javaCallback comparison + FunctionDef<bool, std::shared_ptr<MgmtEvent>> funcDef = bindCaptureFunc(JNIGlobalRef(javaCallback), nativeCallback); + setObjectRef(env, obj, funcDef.cloneFunction(), "discoveringNotificationRef"); // set java ref + mgmt.addMgmtEventCallback(adapter->dev_id, MgmtEvent::Opcode::DISCOVERING, funcDef); + mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_DISCONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceDisconnectedCB)); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + +#endif diff --git a/java/jni/direct_bt/helper_dbt.cxx b/java/jni/direct_bt/helper_dbt.cxx index b3431edc..06edc598 100644 --- a/java/jni/direct_bt/helper_dbt.cxx +++ b/java/jni/direct_bt/helper_dbt.cxx @@ -63,3 +63,31 @@ jobject direct_bt::convert_vector_to_jobject(JNIEnv *env, std::vector<std::share #endif +static std::string jStringEmpty(""); +static std::string jAddressTypePublic("public"); +static std::string jAddressTypeRandom("random"); + +BDAddressType direct_bt::fromJavaAdressTypeToBDAddressType(JNIEnv *env, jstring jAddressType) { + if( nullptr != jAddressType ) { + std::string saddressType = from_jstring_to_string(env, jAddressType); + if( jAddressTypePublic == saddressType ) { + return BDAddressType::BDADDR_LE_PUBLIC; + } + if( jAddressTypeRandom == saddressType ) { + return BDAddressType::BDADDR_LE_RANDOM; + } + } + return BDAddressType::BDADDR_BREDR; +} +jstring direct_bt::fromBDAddressTypeToJavaAddressType(JNIEnv *env, BDAddressType bdAddressType) { + switch( bdAddressType ) { + case BDAddressType::BDADDR_LE_PUBLIC: + return from_string_to_jstring(env, jAddressTypePublic); + case BDAddressType::BDADDR_LE_RANDOM: + return from_string_to_jstring(env, jAddressTypeRandom); + case BDAddressType::BDADDR_BREDR: + // fall through intended + default: + return from_string_to_jstring(env, jStringEmpty); + } +} diff --git a/java/jni/direct_bt/helper_dbt.hpp b/java/jni/direct_bt/helper_dbt.hpp index 5598c011..0264c795 100644 --- a/java/jni/direct_bt/helper_dbt.hpp +++ b/java/jni/direct_bt/helper_dbt.hpp @@ -31,6 +31,7 @@ #include "direct_bt/JavaUplink.hpp" #include "direct_bt/BasicTypes.hpp" +#include "direct_bt/BTAddress.hpp" namespace direct_bt { @@ -108,6 +109,9 @@ namespace direct_bt { #endif + BDAddressType fromJavaAdressTypeToBDAddressType(JNIEnv *env, jstring jAddressType); + jstring fromBDAddressTypeToJavaAddressType(JNIEnv *env, BDAddressType bdAddressType); + } // namespace direct_bt #endif /* HELPER_DBT_HPP_ */ |