From 99bcd1f4fb27efc1937916f7237c7c6340fba9fa Mon Sep 17 00:00:00 2001 From: Greg Date: Fri, 22 Nov 2019 23:33:45 -0500 Subject: [PATCH] Add discoverCharacteristics() for Android. --- BleConnect.java | 17 ++++++++++-- ble_android.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++--- jni_android.c | 24 +++++++++++++++-- jni_android.h | 1 + 4 files changed, 105 insertions(+), 7 deletions(-) diff --git a/BleConnect.java b/BleConnect.java index 72b9b2b..fea3cf2 100644 --- a/BleConnect.java +++ b/BleConnect.java @@ -13,6 +13,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; @@ -119,7 +120,7 @@ public class BleConnect extends Fragment { } public void onServicesDiscovered(BluetoothGatt gatt, int status) { for (BluetoothGattService serv : gatt.getServices()) { - onDiscoverService(device.getAddress(), serv.getUuid().toString()); + onDiscoverService(device.getAddress(), serv.getUuid().toString(), serv); } } }; @@ -154,6 +155,17 @@ public class BleConnect extends Fragment { bluetoothGatt.discoverServices(); } + public void discoverCharacteristics(BluetoothGattService serv) { + Log.d("gio","BleConnect: discoverCharacteristics()"); + if (bluetoothGatt == null || device == null) { + return; + } + for (BluetoothGattCharacteristic chr : serv.getCharacteristics()) { + Log.d("gio","BleConnect: -- " + chr.getUuid().toString()); + onDiscoverCharacteristic(device.getAddress(), serv.getUuid().toString(), serv, chr.getUuid().toString(), chr); + } + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d("gio", "BleConnect: onActivityResult()"); if (requestCode == REQUEST_ENABLE_BT) { @@ -175,6 +187,7 @@ public class BleConnect extends Fragment { static private native void updateState(int s); static private native void onScan(String name, String id, int rssi, BluetoothDevice dev); static private native void onConnect(String id); - static private native void onDiscoverService(String id, String uuid); + static private native void onDiscoverService(String id, String uuid, BluetoothGattService serv); + static private native void onDiscoverCharacteristic(String id, String suuid, BluetoothGattService serv, String cuuid, BluetoothGattCharacteristic chr); } diff --git a/ble_android.go b/ble_android.go index 51f9c0c..3d487b1 100644 --- a/ble_android.go +++ b/ble_android.go @@ -36,8 +36,15 @@ type Peripheral struct { device C.jobject } -type Service string -type Characteristic string +type Service struct { + UUID string + service C.jobject +} + +type Characteristic struct { + UUID string + characteristic C.jobject +} // Internal global variables @@ -168,6 +175,16 @@ func (x Peripheral) DiscoverServices() { //DiscoverCharacteristics asks a Peripheral for the Characteristics related //to a Service func (p Peripheral) DiscoverCharacteristics(serv Service) { + //launch a goroutine because this function calls back directly + //from the same thread. + go func() { + connect() + log.Printf("discovering characteristics") + runInJVM(func(env *C.JNIEnv) { + C.discoverCharacteristics(env, gBLE.handle.BleConnect, serv.service) + }) + log.Printf("discovering characteristics done") + }() } //SetNotifyValue subscribes to a characteristic @@ -267,7 +284,7 @@ func goOnConnect(cid *C.char) { } //export goOnDiscoverService -func goOnDiscoverService(cid *C.char, cuuid *C.char) { +func goOnDiscoverService(cid, cuuid *C.char, serv C.jobject) { id := C.GoString(cid) uuid := C.GoString(cuuid) @@ -288,8 +305,55 @@ func goOnDiscoverService(cid *C.char, cuuid *C.char) { log.Printf("Go: peripheral not found!") } + service := Service{ + UUID: uuid, + service: serv, + } gBLE.events <- DiscoverServiceEvent{ Peripheral: peripheral, Gatt: gatt.Service{uuid}, + Service: service, + } +} + +//export goOnDiscoverCharacteristic +func goOnDiscoverCharacteristic(cid, csuuid *C.char, serv C.jobject, ccuuid *C.char, char C.jobject) { + id := C.GoString(cid) + suuid := C.GoString(csuuid) + cuuid := C.GoString(ccuuid) + log.Printf("goOnDiscoverCharacteristic: %s", cuuid) + + var peripheral Peripheral + found := false + + gBLE.peripherals.Lock() + for _, item := range gBLE.peripherals.items { + if item.p.Identifier == id { + peripheral = item.p + found = true + break + } + } + gBLE.peripherals.Unlock() + + if !found { + log.Printf("Go: peripheral not found!") + } + + service := Service{ + UUID: suuid, + service: serv, + } + + characteristic := Characteristic{ + UUID: cuuid, + characteristic: char, + } + + gBLE.events <- DiscoverCharacteristicEvent{ + Peripheral: peripheral, + Service: service, + Characteristic: characteristic, + Gatt: gatt.Characteristic{cuuid}, } } diff --git a/jni_android.c b/jni_android.c index dc50263..bab0661 100644 --- a/jni_android.c +++ b/jni_android.c @@ -45,6 +45,13 @@ discoverServices(JNIEnv *env, jobject b, jobject p) { (*env)->CallVoidMethod(env, b, mid, p); } +void +discoverCharacteristics(JNIEnv *env, jobject b, jobject s) { + jclass cls = (*env)->GetObjectClass(env, b); + jmethodID mid = (*env)->GetMethodID(env, cls, "discoverCharacteristics", "(Landroid/bluetooth/BluetoothGattService;)V"); + (*env)->CallVoidMethod(env, b, mid, s); +} + jint GetEnv(JavaVM *vm, JNIEnv **env, jint version) { return (*vm)->GetEnv(vm, (void **)env, version); @@ -83,10 +90,23 @@ Java_st_wow_git_ble_BleConnect_onConnect(JNIEnv *env, jclass class, jstring jid) } void -Java_st_wow_git_ble_BleConnect_onDiscoverService(JNIEnv *env, jclass class, jstring jid, jstring juuid) { +Java_st_wow_git_ble_BleConnect_onDiscoverService(JNIEnv *env, jclass class, jstring jid, jstring juuid, jobject serv) { char* id = (*env)->GetStringUTFChars(env, jid, NULL); char* uuid = (*env)->GetStringUTFChars(env, juuid, NULL); - goOnDiscoverService(id, uuid); + jobject gserv = (*env)->NewGlobalRef(env, serv); + goOnDiscoverService(id, uuid, gserv); (*env)->ReleaseStringUTFChars(env, jid, id); (*env)->ReleaseStringUTFChars(env, juuid, uuid); } + +void +Java_st_wow_git_ble_BleConnect_onDiscoverCharacteristic(JNIEnv *env, jclass class, jstring jid, jstring jsuuid, jobject serv, jstring jcuuid, jobject chr) { + char* id = (*env)->GetStringUTFChars(env, jid, NULL); + char* suuid = (*env)->GetStringUTFChars(env, jsuuid, NULL); + char* cuuid = (*env)->GetStringUTFChars(env, jcuuid, NULL); + jobject gchr = (*env)->NewGlobalRef(env, chr); + goOnDiscoverCharacteristic(id, suuid, serv, cuuid, gchr); + (*env)->ReleaseStringUTFChars(env, jid, id); + (*env)->ReleaseStringUTFChars(env, jsuuid, suuid); + +} diff --git a/jni_android.h b/jni_android.h index e88cae8..784d0a1 100644 --- a/jni_android.h +++ b/jni_android.h @@ -6,6 +6,7 @@ void stopScan(JNIEnv *env, jobject b); void connect(JNIEnv *env, jobject b, jobject d); void disconnect(JNIEnv *env, jobject b); void discoverServices(JNIEnv *env, jobject b, jobject p); +void discoverCharacteristics(JNIEnv *env, jobject b, jobject s); jint GetEnv(JavaVM *vm, JNIEnv **env, jint version); jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args); jint DetachCurrentThread(JavaVM *vm);