Skip to content

Commit

Permalink
Release 2.1.0
Browse files Browse the repository at this point in the history
Release 2.1.0
  • Loading branch information
mikolak authored Jan 24, 2020
2 parents e311868 + 14cfe9b commit 70f6795
Show file tree
Hide file tree
Showing 14 changed files with 333 additions and 87 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ example/android/res/values/strings_en.arb
res/values/strings_en.arb
lib/generated/
example/lib/generated/
example/.flutter-plugins-dependencies
.dart_tool/
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 2.1.0

* **BREAKING** ScanResult.AdvertisementData.ManufacturerData has changed type from Int8List to Uint8List
* Fix issue with invalid value of manufacturer data in scan results
* Fix issue with initialising plugin from a service without an active activity
* Update README with information about permissions
* Fix issue with default value of MTU when connecting to a peripheral on Android
* Fix issue where first few notifications right after start of monitoring a characteristic could get lost

## 2.0.1

* Fix issue with automatically generated transaction IDs.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Using that instance you then obtain an instance of _Peripheral_,

For more informations, see [REFERENCE](https://github.com/Polidea/FlutterBleLib/blob/master/REFERENCE.md).

**Notice:** this library will not handle any permissions for you. To be able to scan for peripherals on Android you need `ACCESS_FINE_LOCATION` [according to Android Developer Guide](https://developer.android.com/guide/topics/connectivity/bluetooth-le#permissions).

### Initialising
```dart
BleManager bleManager = BleManager();
Expand Down
13 changes: 10 additions & 3 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,13 @@ All of the following methods belong to Peripheral instance.
Duration timeout});
```
Attempts to connect to the peripheral.

`autoConnect` waits for device to be discoverable before attempting connection; Android-specific. [See more](https://github.com/Polidea/RxAndroidBle#auto-connect)
`requestMtu` defaults to 23.

`requestMtu` defaults to 0, which means the library won't set it. Valid values according to BLE specification are between 23 and 512. **IMPORTANT** can be requested only once: if you pass this argument, then every call to `requestMtu()` will fail.

`refreshGatt` forces GATT to refresh its cache; Android-specific.

If connection has not been established by `timeout`, the operation fails. `timeout` defaults to 30 seconds.
```dart
Stream<PeripheralConnectionState> observeConnectionState(
Expand Down Expand Up @@ -165,7 +169,10 @@ Reads current RSSI if the device is connected.
}
```
Request peripheral to set a different MTU. On iOS only returns the current value.
Return the MTU set by peripheral after request.
Returns the MTU set by peripheral after the request.

MTU can be requested only once in the lifetime of the connection, meaning this call will fail if it was set prior by either passing a valid value to `connect(requestMtu: int)` or calling this function.

## Characteristic convenience methods
Finds first service with specified UUID and first characteristic
in said service with specified UUID and then performs the requested operation.
Expand Down Expand Up @@ -255,4 +262,4 @@ Writes value to this characteristic. It is user's responsibility to choose wheth
```dart
Stream<Uint8List> monitor({String transactionId});
```
Operation is cancellable, which allows the user to terminate the notifications from the peripheral for this characteristic.
Operation is cancellable, which allows the user to terminate the notifications from the peripheral for this characteristic.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public static void registerWith(Registrar registrar) {
final EventChannel connectionStateChannel = new EventChannel(registrar.messenger(), ChannelName.CONNECTION_STATE_CHANGE_EVENTS);
final EventChannel characteristicMonitorChannel = new EventChannel(registrar.messenger(), ChannelName.MONITOR_CHARACTERISTIC);

final FlutterBleLibPlugin plugin = new FlutterBleLibPlugin(registrar.activity().getApplicationContext());
final FlutterBleLibPlugin plugin = new FlutterBleLibPlugin(registrar.context());

channel.setMethodCallHandler(plugin);

Expand Down
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ PODS:
- MultiplatformBleAdapter (0.0.4)

DEPENDENCIES:
- Flutter (from `.symlinks/flutter/ios-release`)
- Flutter (from `.symlinks/flutter/ios`)
- flutter_ble_lib (from `.symlinks/plugins/flutter_ble_lib/ios`)

SPEC REPOS:
https://github.com/cocoapods/specs.git:
https://github.com/CocoaPods/Specs.git:
- MultiplatformBleAdapter

EXTERNAL SOURCES:
Flutter:
:path: ".symlinks/flutter/ios-release"
:path: ".symlinks/flutter/ios"
flutter_ble_lib:
:path: ".symlinks/plugins/flutter_ble_lib/ios"

Expand All @@ -26,4 +26,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932

COCOAPODS: 1.7.5
COCOAPODS: 1.8.4
8 changes: 2 additions & 6 deletions ios/Classes/Event/AdapterStateStreamHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@ - (FlutterError * _Nullable)onListenWithArguments:(id _Nullable)arguments eventS
}
}

- (void)onNewAdapterState:(NSArray *)bluetoothAdapterState {
- (void)onNewAdapterState:(NSString *)bluetoothAdapterState {
@synchronized (self) {
if (adapterStateSink != nil) {
if (bluetoothAdapterState[0] == [NSNull null]) {
adapterStateSink(bluetoothAdapterState[1]);
} else {
adapterStateSink([FlutterErrorFactory flutterErrorFromJSONString:bluetoothAdapterState[0]]);
}
adapterStateSink(bluetoothAdapterState);
}
}
}
Expand Down
139 changes: 83 additions & 56 deletions lib/internal/bridge/characteristics_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,29 +147,26 @@ mixin CharacteristicsMixin on FlutterBLE {
int characteristicIdentifier,
String transactionId,
) {
_methodChannel.invokeMethod(
MethodName.monitorCharacteristicForIdentifier,
<String, dynamic>{
ArgumentName.characteristicIdentifier: characteristicIdentifier,
ArgumentName.transactionId: transactionId,
},
);
return _characteristicsMonitoringEvents
.map(
(rawJsonValue) =>
_parseCharacteristicWithValueWithTransactionIdResponse(
peripheral, rawJsonValue),
)
.where(
(characteristic) =>
characteristic._id == characteristicIdentifier &&
equalsIgnoreAsciiCase(
transactionId ?? "", characteristic.transactionId ?? ""),
)
.map((characteristicWithValue) => characteristicWithValue.value)
.handleError((errorJson) =>
_throwErrorIfMatchesWithTransactionId(errorJson, transactionId))
.transform(CancelOnErrorStreamTransformer());
void Function() startMonitoring = () => _methodChannel.invokeMethod(
MethodName.monitorCharacteristicForIdentifier,
<String, dynamic>{
ArgumentName.characteristicIdentifier: characteristicIdentifier,
ArgumentName.transactionId: transactionId,
},
);

bool Function(CharacteristicWithValueAndTransactionId)
characteristicFilter = (characteristic) =>
characteristic._id == characteristicIdentifier &&
equalsIgnoreAsciiCase(
transactionId ?? "", characteristic.transactionId ?? "");

return _createMonitoringStream(
startMonitoring,
characteristicFilter,
peripheral,
transactionId,
).map((characteristicWithValue) => characteristicWithValue.value);
}

Stream<CharacteristicWithValue> monitorCharacteristicForDevice(
Expand All @@ -178,27 +175,29 @@ mixin CharacteristicsMixin on FlutterBLE {
String characteristicUUID,
String transactionId,
) {
_methodChannel.invokeMethod(
MethodName.monitorCharacteristicForDevice,
<String, dynamic>{
ArgumentName.deviceIdentifier: peripheral.identifier,
ArgumentName.serviceUuid: serviceUuid,
ArgumentName.characteristicUuid: characteristicUUID,
ArgumentName.transactionId: transactionId,
},
);
return _characteristicsMonitoringEvents
.map((rawJsonValue) =>
_parseCharacteristicWithValueWithTransactionIdResponse(
peripheral, rawJsonValue))
.where((characteristic) =>
void Function() startMonitoring = () => _methodChannel.invokeMethod(
MethodName.monitorCharacteristicForDevice,
<String, dynamic>{
ArgumentName.deviceIdentifier: peripheral.identifier,
ArgumentName.serviceUuid: serviceUuid,
ArgumentName.characteristicUuid: characteristicUUID,
ArgumentName.transactionId: transactionId,
},
);

bool Function(CharacteristicWithValueAndTransactionId)
characteristicsFilter = (characteristic) =>
equalsIgnoreAsciiCase(characteristicUUID, characteristic.uuid) &&
equalsIgnoreAsciiCase(serviceUuid, characteristic.service.uuid) &&
equalsIgnoreAsciiCase(
transactionId ?? "", characteristic.transactionId ?? ""))
.handleError((errorJson) =>
_throwErrorIfMatchesWithTransactionId(errorJson, transactionId))
.transform(CancelOnErrorStreamTransformer());
transactionId ?? "", characteristic.transactionId ?? "");

return _createMonitoringStream(
startMonitoring,
characteristicsFilter,
peripheral,
transactionId,
);
}

Stream<CharacteristicWithValue> monitorCharacteristicForService(
Expand All @@ -207,30 +206,58 @@ mixin CharacteristicsMixin on FlutterBLE {
String characteristicUUID,
String transactionId,
) {
_methodChannel.invokeMethod(
MethodName.monitorCharacteristicForService,
<String, dynamic>{
ArgumentName.serviceIdentifier: serviceIdentifier,
ArgumentName.characteristicUuid: characteristicUUID,
ArgumentName.transactionId: transactionId,
},
void Function() startMonitoring = () => _methodChannel.invokeMethod(
MethodName.monitorCharacteristicForService,
<String, dynamic>{
ArgumentName.serviceIdentifier: serviceIdentifier,
ArgumentName.characteristicUuid: characteristicUUID,
ArgumentName.transactionId: transactionId,
},
);

bool Function(CharacteristicWithValueAndTransactionId)
characteristicFilter = (characteristic) =>
equalsIgnoreAsciiCase(characteristicUUID, characteristic.uuid) &&
serviceIdentifier == characteristic.service._id &&
equalsIgnoreAsciiCase(
transactionId ?? "", characteristic.transactionId ?? "");

return _createMonitoringStream(
startMonitoring,
characteristicFilter,
peripheral,
transactionId,
);
return _characteristicsMonitoringEvents
}

Stream<CharacteristicWithValue> _createMonitoringStream(
void Function() onListen,
bool Function(CharacteristicWithValueAndTransactionId) filter,
Peripheral peripheral,
String transactionId,
) {
Stream<CharacteristicWithValue> stream = _characteristicsMonitoringEvents
.map(
(rawJsonValue) =>
_parseCharacteristicWithValueWithTransactionIdResponse(
peripheral, rawJsonValue),
)
.where(
(characteristic) =>
equalsIgnoreAsciiCase(characteristicUUID, characteristic.uuid) &&
serviceIdentifier == characteristic.service._id &&
equalsIgnoreAsciiCase(
transactionId ?? "", characteristic.transactionId ?? ""),
)
.where(filter)
.handleError((errorJson) =>
_throwErrorIfMatchesWithTransactionId(errorJson, transactionId))
.transform(CancelOnErrorStreamTransformer());

StreamController<CharacteristicWithValue> streamController =
StreamController.broadcast(
onListen: onListen,
onCancel: () => cancelTransaction(transactionId),
);

streamController
.addStream(stream, cancelOnError: true)
.then((_) => streamController?.close());

return streamController.stream;
}

CharacteristicWithValueAndTransactionId
Expand Down
12 changes: 6 additions & 6 deletions lib/internal/bridge/lib_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ abstract class FlutterBLE {

final MethodChannel _methodChannel =
const MethodChannel(ChannelName.flutterBleLib);

Future<void> cancelTransaction(String transactionId) async {
await _methodChannel.invokeMethod(MethodName.cancelTransaction,
<String, String>{ArgumentName.transactionId: transactionId});
return;
}
}

class FlutterBleLib extends FlutterBLE
Expand Down Expand Up @@ -55,10 +61,4 @@ class FlutterBleLib extends FlutterBLE
await _methodChannel.invokeMethod(MethodName.destroyClient);
return;
}

Future<void> cancelTransaction(String transactionId) async {
await _methodChannel.invokeMethod(MethodName.cancelTransaction,
<String, String>{ArgumentName.transactionId: transactionId});
return;
}
}
5 changes: 2 additions & 3 deletions lib/peripheral.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ abstract class _PeripheralMetadata {
}

class Peripheral {
static const int _minimumMtu = 23;

static const int NO_MTU_NEGOTIATION = 0;
ManagerForPeripheral _manager;

String name;
Expand All @@ -20,7 +19,7 @@ class Peripheral {

Future<void> connect(
{bool isAutoConnect = false,
int requestMtu = _minimumMtu,
int requestMtu = NO_MTU_NEGOTIATION,
bool refreshGatt = false,
Duration timeout}) =>
_manager.connectToPeripheral(identifier,
Expand Down
14 changes: 7 additions & 7 deletions lib/scan_result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ class ScanResult {
}

class AdvertisementData {
Int8List manufacturerData;
Map<String, Int8List> serviceData;
Uint8List manufacturerData;
Map<String, Uint8List> serviceData;
List<String> serviceUUIDs;
String localName;
int txPowerLevel;
List<String> solicitedServiceUUIDs;

AdvertisementData._fromJson(Map<String, dynamic> json)
: manufacturerData =
_decodeBase64OrNull(_ScanResultMetadata.manufacturerData),
_decodeBase64OrNull(json[_ScanResultMetadata.manufacturerData]),
serviceData =
_getServiceDataOrNull(json[_ScanResultMetadata.serviceData]),
serviceUUIDs =
Expand All @@ -52,16 +52,16 @@ class AdvertisementData {
solicitedServiceUUIDs = _mapToListOfStringsOrNull(
json[_ScanResultMetadata.solicitedServiceUuids]);

static Map<String, Int8List> _getServiceDataOrNull(
static Map<String, Uint8List> _getServiceDataOrNull(
Map<String, dynamic> serviceData) {
return serviceData?.map(
(key, value) => MapEntry(key, Int8List.fromList(base64Decode(value))),
(key, value) => MapEntry(key, base64Decode(value)),
);
}

static Int8List _decodeBase64OrNull(String base64Value) {
static Uint8List _decodeBase64OrNull(String base64Value) {
if (base64Value != null)
return Int8List.fromList(base64.decode(base64Value));
return base64.decode(base64Value);
else
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_ble_lib
description: FlutterBle Library is a flutter library that supports BLE operations. It uses MultiPlatformBleAdapter as a native backend..
version: 2.0.1
version: 2.1.0
author: "Polidea <[email protected]>"
homepage: https://github.com/Polidea/FlutterBleLib

Expand Down
Loading

0 comments on commit 70f6795

Please sign in to comment.