summaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-05-10 06:17:20 +0200
committerSven Gothel <[email protected]>2020-05-10 06:17:20 +0200
commitb784da70133b4b5859bb8b6f86ab48a48a6d87af (patch)
tree28f1baa5caf8e4ce1c3fb9b3592b33398e1e7c08 /java
parent0f53fde528dea4470d152d30f33f357dde1b2e10 (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.java105
-rw-r--r--java/direct_bt/tinyb/DBTDevice.java181
-rw-r--r--java/jni/direct_bt/DBTAdapter.cxx84
-rw-r--r--java/jni/direct_bt/DBTDevice.cxx281
-rw-r--r--java/jni/direct_bt/helper_dbt.cxx28
-rw-r--r--java/jni/direct_bt/helper_dbt.hpp4
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_ */