Skip to content

Commit

Permalink
feat(): add optional onDisconnect callback to connect method
Browse files Browse the repository at this point in the history
  • Loading branch information
pwespi committed Feb 13, 2021
1 parent 319098f commit 1eefe64
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 17 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,14 +389,15 @@ Stop scanning for BLE devices. For an example, see [usage](#usage).
### connect(...)

```typescript
connect(deviceId: string) => Promise<void>
connect(deviceId: string, onDisconnect?: ((deviceId: string) => void) | undefined) => Promise<void>
```

Connect to a peripheral BLE device. For an example, see [usage](#usage).

| Param | Type | Description |
| -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------- |
| **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) |
| Param | Type | Description |
| ------------------ | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) |
| **`onDisconnect`** | <code>((deviceId: string) =&gt; void)</code> | Optional disconnect callback function that will be used when the device disconnects |

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.ParcelUuid
import android.util.Log
import com.getcapacitor.*
import com.getcapacitor.Logger.config
import java.util.*
Expand Down Expand Up @@ -206,7 +207,13 @@ class BluetoothLe : Plugin() {

val device: Device
try {
device = Device(activity.applicationContext, bluetoothAdapter!!, deviceId)
device = Device(
activity.applicationContext,
bluetoothAdapter!!,
deviceId
) { ->
onDisconnect(deviceId)
}
} catch (e: IllegalArgumentException) {
call.reject("Invalid deviceId")
return
Expand All @@ -223,6 +230,10 @@ class BluetoothLe : Plugin() {
}
}

private fun onDisconnect(deviceId: String) {
notifyListeners("disconnected|${deviceId}", null)
}

@PluginMethod
fun disconnect(call: PluginCall) {
val device = getDevice(call) ?: return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Device(
private val context: Context,
private val bluetoothAdapter: BluetoothAdapter,
private val address: String,
private val onDisconnect: () -> Unit
) {
companion object {
private val TAG = Device::class.java.simpleName
Expand Down Expand Up @@ -51,6 +52,7 @@ class Device(
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
connectionState = STATE_DISCONNECTED
onDisconnect()
Log.d(TAG, "Disconnected from GATT server.")
resolve("disconnect", "Disconnected.")
}
Expand Down
10 changes: 9 additions & 1 deletion ios/Plugin/DeviceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,14 @@ class DeviceManager: NSObject, CBCentralManagerDelegate {
}
self.reject(key, "Failed to connect.")
}

func setOnDisconnected(_ device: Device, _ callback: @escaping Callback) {
let key = "onDisconnected|\(device.getId())"
self.callbackMap[key] = callback
}

func disconnect(_ device: Device, _ callback: @escaping Callback) {
let key = "disconnect|\(device.getPeripheral().identifier.uuidString)"
let key = "disconnect|\(device.getId())"
self.callbackMap[key] = callback
print("Disconnecting from peripheral", device.getPeripheral())
self.centralManager.cancelPeripheralConnection(device.getPeripheral())
Expand All @@ -214,7 +219,10 @@ class DeviceManager: NSObject, CBCentralManagerDelegate {
// didDisconnectPeripheral
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
let key = "disconnect|\(peripheral.identifier.uuidString)"
let keyOnDisconnected = "onDisconnected|\(peripheral.identifier.uuidString)"
self.resolve(keyOnDisconnected, "Disconnected.")
if error != nil {
print(error!.localizedDescription)
self.reject(key, error!.localizedDescription)
return
}
Expand Down
4 changes: 4 additions & 0 deletions ios/Plugin/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ public class BluetoothLe: CAPPlugin {
call.reject(message)
}
})
self.deviceManager?.setOnDisconnected(device, {(success, message) -> Void in
let key = "disconnected|\(device.getId())"
self.notifyListeners(key, data: nil)
})
self.deviceManager?.connect(device, {(success, message) -> Void in
if success {
print("Connected to peripheral. Waiting for service discovery.")
Expand Down
35 changes: 25 additions & 10 deletions src/bleClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,12 @@ export interface BleClientInterface {
/**
* Connect to a peripheral BLE device. For an example, see [usage](#usage).
* @param deviceId The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan))
* @param onDisconnect Optional disconnect callback function that will be used when the device disconnects
*/
connect(deviceId: string): Promise<void>;
connect(
deviceId: string,
onDisconnect?: (deviceId: string) => void,
): Promise<void>;

/**
* Disconnect from a peripheral BLE device. For an example, see [usage](#usage).
Expand Down Expand Up @@ -130,7 +134,7 @@ export interface BleClientInterface {

class BleClientClass implements BleClientInterface {
scanListener: PluginListenerHandle | null = null;
notifyListeners = new Map<string, PluginListenerHandle>();
eventListeners = new Map<string, PluginListenerHandle>();

async initialize(): Promise<void> {
await BluetoothLe.initialize();
Expand All @@ -145,17 +149,17 @@ class BleClientClass implements BleClientInterface {
callback: (value: boolean) => void,
): Promise<void> {
const key = `onEnabledChanged`;
this.notifyListeners.get(key)?.remove();
this.eventListeners.get(key)?.remove();
const listener = BluetoothLe.addListener(key, result => {
callback(result.value);
});
this.notifyListeners.set(key, listener);
this.eventListeners.set(key, listener);
await BluetoothLe.startEnabledNotifications();
}

async stopEnabledNotifications(): Promise<void> {
const key = `onEnabledChanged`;
this.notifyListeners.get(key)?.remove();
this.eventListeners.get(key)?.remove();
await BluetoothLe.stopEnabledNotifications();
}

Expand Down Expand Up @@ -189,7 +193,18 @@ class BleClientClass implements BleClientInterface {
await BluetoothLe.stopLEScan();
}

async connect(deviceId: string): Promise<void> {
async connect(
deviceId: string,
onDisconnect?: (deviceId: string) => void,
): Promise<void> {
if (onDisconnect) {
const key = `disconnected|${deviceId}`;
this.eventListeners.get(key)?.remove();
const listener = BluetoothLe.addListener(key, () => {
onDisconnect(deviceId);
});
this.eventListeners.set(key, listener);
}
await BluetoothLe.connect({ deviceId });
}

Expand Down Expand Up @@ -236,11 +251,11 @@ class BleClientClass implements BleClientInterface {
callback: (value: DataView) => void,
): Promise<void> {
const key = `notification|${deviceId}|${service}|${characteristic}`;
this.notifyListeners.get(key)?.remove();
this.eventListeners.get(key)?.remove();
const listener = BluetoothLe.addListener(key, (event: ReadResult) => {
callback(this.convertValue(event?.value));
});
this.notifyListeners.set(key, listener);
this.eventListeners.set(key, listener);
await BluetoothLe.startNotifications({
deviceId,
service,
Expand All @@ -254,8 +269,8 @@ class BleClientClass implements BleClientInterface {
characteristic: string,
): Promise<void> {
const key = `notification|${service}|${characteristic}`;
this.notifyListeners.get(key)?.remove();
this.notifyListeners.delete(key);
this.eventListeners.get(key)?.remove();
this.eventListeners.delete(key);
await BluetoothLe.stopNotifications({
deviceId,
service,
Expand Down
11 changes: 10 additions & 1 deletion src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,16 @@ export class BluetoothLeWeb extends WebPlugin implements BluetoothLePlugin {
}

async connect(options: ConnectOptions): Promise<void> {
await this.getDevice(options.deviceId).gatt?.connect();
const device = await this.getDevice(options.deviceId);
device.removeEventListener('gattserverdisconnected', this.onDisconnected);
device.addEventListener('gattserverdisconnected', this.onDisconnected);
await device.gatt?.connect();
}

private onDisconnected(event: Event) {
const deviceId = (event.target as BluetoothDevice).id;
const key = `disconnected|${deviceId}`;
BluetoothLe.notifyListeners(key, null);
}

async disconnect(options: ConnectOptions): Promise<void> {
Expand Down

0 comments on commit 1eefe64

Please sign in to comment.