arguments static method
Implementation
static Map<String, dynamic> arguments(
String action,
Map<String, dynamic> raw, {
bool allowBindings = false,
}) {
if (!actions.contains(action)) {
throw const FormatException('Unknown BLE action.');
}
final keys = <String>{
if (action == 'bluetooth.scan') ...[
'serviceUuids',
'timeoutMs',
'maxDevices',
],
if (action == 'bluetooth.connect') ...['deviceId', 'timeoutMs'],
if (const {
'bluetooth.read',
'bluetooth.write',
'bluetooth.subscribe',
'bluetooth.unsubscribe',
}.contains(action)) ...[
'serviceUuid',
'characteristicUuid',
],
if (action == 'bluetooth.write') ...['valueHex', 'withoutResponse'],
};
if (raw.keys.any((key) => !keys.contains(key))) {
throw const FormatException('Unknown BLE action property.');
}
Object bound(Object? value, Object Function(Object?) validate) {
if (allowBindings &&
value is String &&
value.length <= 256 &&
RegExp(
r'^\{\{\s*(?:state|item|form|route)\.[^{}]+\s*\}\}$',
).hasMatch(value)) {
return value;
}
return validate(value);
}
int integer(Object? value, int fallback, int minimum, int maximum) {
value ??= fallback;
if (value is! int || value < minimum || value > maximum) {
throw const FormatException('Invalid BLE operation limit.');
}
return value;
}
return {
if (action == 'bluetooth.scan') ...{
'serviceUuids': uuids(raw['serviceUuids'] ?? const []),
'timeoutMs': integer(raw['timeoutMs'], 5000, 500, maxScanMs),
'maxDevices': integer(raw['maxDevices'], 20, 1, maxDevices),
},
if (action == 'bluetooth.connect') ...{
'deviceId': bound(raw['deviceId'], deviceId),
'timeoutMs': integer(raw['timeoutMs'], 10000, 1000, maxScanMs),
},
if (keys.contains('serviceUuid')) ...{
'serviceUuid': bound(raw['serviceUuid'], uuid),
'characteristicUuid': bound(raw['characteristicUuid'], uuid),
},
if (action == 'bluetooth.write') ...{
'valueHex': bound(
raw['valueHex'],
(v) => hex(v, limit: maxWriteBytes, empty: false),
),
'withoutResponse':
raw['withoutResponse'] == null || raw['withoutResponse'] is bool
? raw['withoutResponse'] ?? false
: throw const FormatException('withoutResponse must be boolean.'),
},
};
}