Android 平台开发 (#1)

* 修复 UUID 创建失败的问题

* 移除 scanning 属性

* 临时提交

* CentralManager 开发 & 示例项目开发

* CentralManager 开发 & 示例项目开发

* android 插件生命周期监听

* 修改 API

* 示例程序开发

* 修改字体,添加 API,解决后台问题

* Central#connect API

* 蓝牙连接部分开发

* 蓝牙连接部分开发

* 解决一些问题

* 解决一些问题

* Connect API 优化

* 添加 API

* example 开发

* API 基本完成

* 消息重命名

* API 修改,Android 实现

* 删除多余代码

* 删除多余文件

* 解决 descriptor 自动生成报错的问题

* 还原 Kotlin 版本,广播处理代码迁移至 dart 端

* Kotlin 版本升至 1.5.20

* 解决特征值通知没有在主线程触发的问题,优化代码

* 引入哈希值,避免对象销毁后继续使用

* 使用下拉刷新代替搜索按钮

* 解决由于热重载和蓝牙关闭产生的问题

* 更新插件信息

* 更新 README 和 CHANGELOG

* 更新许可证

* 添加注释

* 添加注释,central 拆分
This commit is contained in:
iAMD
2021-07-01 17:35:54 +08:00
committed by GitHub
parent f138b8e11e
commit 6bc1a364fb
59 changed files with 20524 additions and 443 deletions

View File

@ -1,3 +1,6 @@
## 0.0.1 ## 0.0.1
* TODO: Describe initial release. - Add central APIs.
- Add implements on Android.
- Add example.
- Add test.

22
LICENSE
View File

@ -1 +1,21 @@
TODO: Add your license here. MIT License
Copyright (c) 2021 yanshouwang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,15 +1,42 @@
# bluetooth_low_energy # Bluetooth Low Energy
A new flutter plugin project. A bluetooth low energy plugin for flutter, which can be used to develope central role apps.
## Features
### Central APIs
- [x] Discover advertisements.
- [x] Connect/Disconnect to GATTs.
- [x] Read/Write/Notify characteristics.
- [x] Read/Write descriptors.
### Peripheral APIs
- [ ] Add/Send advertisements.
- [ ] Add services
- [ ] Add/Listen/Write characteristics
- [ ] Add/Listen/Write descriptors.
- [ ] Listen GATT connect/disconnect events.
## Getting Started ## Getting Started
This project is a starting point for a Flutter Add `bluetooth_low_energy` as a [dependency in your pubspec.yaml file](https://flutter.dev/using-packages/).
[plug-in package](https://flutter.dev/developing-packages/),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter, view our ```
[online documentation](https://flutter.dev/docs), which offers tutorials, dependencies:
samples, guidance on mobile development, and a full API reference. bluetooth_low_energy: ^<latest-version>
```
### Android
Make sure you have a `miniSdkVersion` with 21 or higher in your `android/app/build.gradle` file, now we only support Android 5.0 or above.
*Note*: Bluetooth Low Energy doesn't work on Android emulators, so use physical devices which has bluetooth features for development.
### iOS
TO BE DONE.
## Issues
- Only support Android for now, iOS will available as soon as possible.
- Only support central APIs for now.

View File

@ -2,10 +2,11 @@ group 'dev.yanshouwang.bluetooth_low_energy'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
buildscript { buildscript {
ext.kotlin_version = '1.3.50' ext.kotlin_version = '1.5.20'
repositories { repositories {
google() google()
jcenter() mavenCentral()
maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
} }
dependencies { dependencies {
@ -17,7 +18,8 @@ buildscript {
rootProject.allprojects { rootProject.allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
} }
} }
@ -31,10 +33,11 @@ android {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 21
} }
} }
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.protobuf:protobuf-kotlin:3.17.3'
} }

View File

@ -1,3 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.yanshouwang.bluetooth_low_energy"> package="dev.yanshouwang.bluetooth_low_energy">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest> </manifest>

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,687 @@
package dev.yanshouwang.bluetooth_low_energy package dev.yanshouwang.bluetooth_low_energy
import android.Manifest
import android.bluetooth.*
import android.bluetooth.le.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import android.os.DeadObjectException
import android.os.Handler
import android.os.ParcelUuid
import android.util.Log
import androidx.annotation.NonNull import androidx.annotation.NonNull
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.protobuf.ByteString
import dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.*
import dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.MessageCategory.*
import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.EventChannel.EventSink
import io.flutter.plugin.common.EventChannel.StreamHandler
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener
import java.util.*
const val NAMESPACE = "yanshouwang.dev/bluetooth_low_energy"
typealias StartScanHandler = (code: Int) -> Unit
typealias RequestPermissionsHandler = (granted: Boolean) -> Unit
/** BluetoothLowEnergyPlugin */ /** BluetoothLowEnergyPlugin */
class BluetoothLowEnergyPlugin: FlutterPlugin, MethodCallHandler { class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler, ActivityAware, RequestPermissionsResultListener {
/// The MethodChannel that will the communication between Flutter and native Android companion object {
/// private const val CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"
/// This local reference serves to register the plugin with the Flutter Engine and unregister it private const val BLUETOOTH_ADAPTER_STATE_UNKNOWN = -1
/// when the Flutter Engine is detached from the Activity private const val NO_ERROR = 0
private lateinit var channel : MethodChannel private const val INVALID_REQUEST = 1
private const val REQUEST_PERMISSION_FAILED = 2
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { private const val REQUEST_MTU_FAILED = 3
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "bluetooth_low_energy") private const val DISCOVER_SERVICES_FAILED = 4
channel.setMethodCallHandler(this) private const val READ_CHARACTERISTIC_FAILED = 5
private const val WRITE_CHARACTERISTIC_FAILED = 6
private const val NOTIFY_CHARACTERISTIC_FAILED = 7
private const val READ_DESCRIPTOR_FAILED = 8
private const val WRITE_DESCRIPTOR_FAILED = 9
private const val REQUEST_CODE = 443
} }
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { private lateinit var method: MethodChannel
if (call.method == "getPlatformVersion") { private lateinit var event: EventChannel
result.success("Android ${android.os.Build.VERSION.RELEASE}") private lateinit var context: Context
} else {
result.notImplemented() private var binding: ActivityPluginBinding? = null
private var sink: EventSink? = null
private val bluetoothAvailable by lazy { context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) }
private val bluetoothManager by lazy { context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager }
private val bluetoothAdapter by lazy { bluetoothManager.adapter }
private val handler by lazy { Handler(context.mainLooper) }
private val bluetoothStateReceiver by lazy {
object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val oldState = intent!!.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BLUETOOTH_ADAPTER_STATE_UNKNOWN).opened
val newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BLUETOOTH_ADAPTER_STATE_UNKNOWN).opened
// TODO: clear status when bluetooth closed.
if (newState == oldState) return
val closed = !newState
if (closed && scanning) scanning = false
val event = Message.newBuilder()
.setCategory(BLUETOOTH_STATE)
.setState(newState)
.build()
.toByteArray()
sink?.success(event)
} }
} }
}
private val hasPermission
get() = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
private var requestPermissionsHandler: RequestPermissionsHandler? = null
private var scanCode = NO_ERROR
private var scanning = false
private val scanCallback by lazy {
object : ScanCallback() {
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
scanCode = errorCode
}
override fun onScanResult(callbackType: Int, result: ScanResult?) {
super.onScanResult(callbackType, result)
if (result == null) return
val address = result.device.address
val rssi = result.rssi
val record = result.scanRecord
val advertisements =
if (record == null) ByteString.EMPTY
else ByteString.copyFrom(record.bytes)
val builder = Discovery.newBuilder()
.setAddress(address)
.setRssi(rssi)
.setAdvertisements(advertisements)
val discovery = builder.build()
val event = Message.newBuilder()
.setCategory(CENTRAL_DISCOVERED)
.setDiscovery(discovery)
.build()
.toByteArray()
sink?.success(event)
}
override fun onBatchScanResults(results: MutableList<ScanResult>?) {
super.onBatchScanResults(results)
if (results == null) return
for (result in results) {
val address = result.device.address
val rssi = result.rssi
val record = result.scanRecord
val advertisements =
if (record == null) ByteString.EMPTY
else ByteString.copyFrom(record.bytes)
val builder = Discovery.newBuilder()
.setAddress(address)
.setRssi(rssi)
.setAdvertisements(advertisements)
val discovery = builder.build()
val event = Message.newBuilder()
.setCategory(CENTRAL_DISCOVERED)
.setDiscovery(discovery)
.build()
.toByteArray()
sink?.success(event)
}
}
}
}
private val gatts by lazy { mutableMapOf<String, BluetoothGatt>() }
private val connects by lazy { mutableMapOf<String, Result>() }
private val mtus by lazy { mutableMapOf<String, Int>() }
private val disconnects by lazy { mutableMapOf<String, Result>() }
private val characteristicReads by lazy { mutableMapOf<Int, Result>() }
private val characteristicWrites by lazy { mutableMapOf<Int, Result>() }
private val descriptorReads by lazy { mutableMapOf<Int, Result>() }
private val descriptorWrites by lazy { mutableMapOf<Int, Result>() }
private val bluetoothGattCallback by lazy {
object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
super.onConnectionStateChange(gatt, status, newState)
val address = gatt!!.device.address
when (status) {
BluetoothGatt.GATT_SUCCESS -> {
when (newState) {
BluetoothProfile.STATE_DISCONNECTED -> {
gatts.remove(address)!!.close()
val disconnect = disconnects.remove(address)
if (disconnect != null) handler.post { disconnect.success() }
else {
// An adapter closed event
val id = gatt.hashCode()
val connectionLost = ConnectionLost.newBuilder()
.setId(id)
.setErrorCode(status)
.build()
val event = Message.newBuilder()
.setCategory(GATT_CONNECTION_LOST)
.setConnectionLost(connectionLost)
.build()
.toByteArray()
handler.post { sink?.success(event) }
}
}
BluetoothProfile.STATE_CONNECTED -> {
val code = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
// TODO: how to get exact MTU size of this device here?
if (gatt.requestMtu(512)) NO_ERROR
else REQUEST_MTU_FAILED
}
else -> {
if (gatt.discoverServices()) {
// Just use 23 as MTU before LOLLIPOP.
mtus[address] = 23
NO_ERROR
} else DISCOVER_SERVICES_FAILED
}
}
if (code != NO_ERROR) {
gatts.remove(address)!!.close()
val connect = connects.remove(address)!!
handler.post { connect.error(code) }
}
}
else -> throw NotImplementedError() // should never be called.
}
}
else -> {
gatts.remove(address)!!.close()
val connect = connects.remove(address)
val disconnect = disconnects.remove(address)
when {
connect != null -> handler.post { connect.error(status) }
disconnect != null -> handler.post { disconnect.error(status) }
else -> {
val id = gatt.hashCode()
val connectionLost = ConnectionLost.newBuilder()
.setId(id)
.setErrorCode(status)
.build()
val event = Message.newBuilder()
.setCategory(GATT_CONNECTION_LOST)
.setConnectionLost(connectionLost)
.build()
.toByteArray()
handler.post { sink?.success(event) }
}
}
}
}
}
override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) {
super.onMtuChanged(gatt, mtu, status)
val address = gatt!!.device.address
val code = when (status) {
BluetoothGatt.GATT_SUCCESS -> {
if (gatt.discoverServices()) {
mtus[address] = mtu
NO_ERROR
} else DISCOVER_SERVICES_FAILED
}
else -> status
}
if (code != NO_ERROR) {
gatts.remove(address)!!.close()
val connect = connects.remove(address)!!
handler.post { connect.error(code) }
}
}
override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
super.onServicesDiscovered(gatt, status)
val address = gatt!!.device.address
val connect = connects.remove(address)!!
val mtu = mtus.remove(address)!!
when (status) {
BluetoothGatt.GATT_SUCCESS -> {
val id = gatt.hashCode()
val services = gatt.services.map { service ->
val serviceId = service.hashCode()
val serviceUUID = service.uuid.toString()
val characteristics = service.characteristics.map { characteristic ->
val characteristicId = characteristic.hashCode()
val characteristicUUID = characteristic.uuid.toString()
val properties = characteristic.properties
val canRead = properties and BluetoothGattCharacteristic.PROPERTY_READ != 0
val canWrite = properties and BluetoothGattCharacteristic.PROPERTY_WRITE != 0
val canWriteWithoutResponse = properties and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE != 0
val canNotify = properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY != 0
val descriptors = characteristic.descriptors.map { descriptor ->
val descriptorId = descriptor.hashCode()
val descriptorUUID = descriptor.uuid.toString()
GattDescriptor.newBuilder()
.setId(descriptorId)
.setUuid(descriptorUUID)
.build()
}
GattCharacteristic.newBuilder()
.setId(characteristicId)
.setUuid(characteristicUUID)
.setCanRead(canRead)
.setCanWrite(canWrite)
.setCanWriteWithoutResponse(canWriteWithoutResponse)
.setCanNotify(canNotify)
.addAllDescriptors(descriptors)
.build()
}
GattService.newBuilder()
.setId(serviceId)
.setUuid(serviceUUID)
.addAllCharacteristics(characteristics).build()
}
val reply = GATT.newBuilder()
.setId(id)
.setMtu(mtu)
.addAllServices(services)
.build()
.toByteArray()
handler.post { connect.success(reply) }
}
else -> {
gatts.remove(address)!!.close()
handler.post { connect.error(status) }
}
}
}
override fun onCharacteristicRead(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int) {
super.onCharacteristicRead(gatt, characteristic, status)
val key = characteristic!!.hashCode()
val read = characteristicReads.remove(key)!!
when (status) {
BluetoothGatt.GATT_SUCCESS -> handler.post { read.success(characteristic.value) }
else -> handler.post { read.error(status) }
}
}
override fun onCharacteristicWrite(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int) {
super.onCharacteristicWrite(gatt, characteristic, status)
val key = characteristic!!.hashCode()
val write = characteristicWrites.remove(key)!!
when (status) {
BluetoothGatt.GATT_SUCCESS -> handler.post { write.success() }
else -> handler.post { write.error(status) }
}
}
override fun onCharacteristicChanged(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?) {
super.onCharacteristicChanged(gatt, characteristic)
val id = characteristic!!.hashCode()
val value = ByteString.copyFrom(characteristic.value)
val characteristicValue = GattCharacteristicValue.newBuilder()
.setId(id)
.setValue(value)
.build()
val event = Message.newBuilder()
.setCategory(GATT_CHARACTERISTIC_NOTIFY)
.setCharacteristicValue(characteristicValue)
.build()
.toByteArray()
handler.post { sink?.success(event) }
}
override fun onDescriptorRead(gatt: BluetoothGatt?, descriptor: BluetoothGattDescriptor?, status: Int) {
super.onDescriptorRead(gatt, descriptor, status)
val key = descriptor!!.hashCode()
val read = descriptorReads.remove(key)!!
when (status) {
BluetoothGatt.GATT_SUCCESS -> handler.post { read.success(descriptor.value) }
else -> handler.post { read.error(status) }
}
}
override fun onDescriptorWrite(gatt: BluetoothGatt?, descriptor: BluetoothGattDescriptor?, status: Int) {
super.onDescriptorWrite(gatt, descriptor, status)
val key = descriptor!!.hashCode()
val write = descriptorWrites.remove(key)!!
when (status) {
BluetoothGatt.GATT_SUCCESS -> handler.post { write.success() }
else -> handler.post { write.error(status) }
}
}
}
}
private fun startScan(services: List<String>, startScanHandler: StartScanHandler) {
val filters = services.map { service ->
val serviceUUID = ParcelUuid.fromString(service)
ScanFilter.Builder()
.setServiceUuid(serviceUUID)
.build()
}
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build()
bluetoothAdapter.bluetoothLeScanner.startScan(filters, settings, scanCallback)
// use handler.post to delay until #onScanFailed executed.
handler.post {
val code = scanCode
when (code) {
NO_ERROR -> scanning = true
else -> scanCode = NO_ERROR
}
startScanHandler.invoke(code)
}
}
private fun stopScan() {
bluetoothAdapter.bluetoothLeScanner.stopScan(scanCallback)
scanning = false
}
override fun onAttachedToEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
method = MethodChannel(binding.binaryMessenger, "$NAMESPACE/method")
method.setMethodCallHandler(this)
event = EventChannel(binding.binaryMessenger, "$NAMESPACE/event")
event.setStreamHandler(this)
context = binding.applicationContext
// Register bluetooth adapter state receiver.
val adapterStateFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
context.registerReceiver(bluetoothStateReceiver, adapterStateFilter)
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null) // Clear connections.
for (gatt in gatts.values) gatt.close()
gatts.clear()
// Stop scan.
if (scanning) stopScan()
// Unregister bluetooth adapter state receiver.
context.unregisterReceiver(bluetoothStateReceiver)
event.setStreamHandler(null)
method.setMethodCallHandler(null)
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
val category = call.category
if (category != BLUETOOTH_AVAILABLE && category != BLUETOOTH_STATE && !bluetoothAdapter.state.opened) result.error(INVALID_REQUEST)
else when (category) {
BLUETOOTH_AVAILABLE -> result.success(bluetoothAvailable)
BLUETOOTH_STATE -> result.success(bluetoothAdapter.state.opened)
CENTRAL_START_DISCOVERY -> {
when {
requestPermissionsHandler != null -> result.error(INVALID_REQUEST)
else -> {
val startDiscovery = Runnable {
val data = call.arguments<ByteArray>()
val arguments = StartDiscoveryArguments.parseFrom(data)
val startScanHandler: StartScanHandler = { code ->
when (code) {
NO_ERROR -> result.success()
else -> result.error(code)
}
}
startScan(arguments.servicesList, startScanHandler)
}
when {
hasPermission -> startDiscovery.run()
else -> {
requestPermissionsHandler = { granted ->
if (granted) startDiscovery.run()
else result.error(REQUEST_PERMISSION_FAILED)
}
val permissions = arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
ActivityCompat.requestPermissions(binding!!.activity, permissions, REQUEST_CODE)
}
}
}
}
}
CENTRAL_STOP_DISCOVERY -> {
stopScan()
result.success()
}
CENTRAL_DISCOVERED -> result.notImplemented()
CENTRAL_CONNECT -> {
val data = call.arguments<ByteArray>()
val arguments = ConnectArguments.parseFrom(data)
val address = arguments.address
val connect = connects[address]
var gatt = gatts[address]
if (connect != null || gatt != null) {
result.error(INVALID_REQUEST)
} else {
val device = bluetoothAdapter.getRemoteDevice(address)
gatt = when {
// Use TRANSPORT_LE to avoid none flag device on Android 23 or later.
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> device.connectGatt(context, false, bluetoothGattCallback, BluetoothDevice.TRANSPORT_LE)
else -> device.connectGatt(context, false, bluetoothGattCallback)
}
connects[address] = result
gatts[address] = gatt
}
}
GATT_DISCONNECT -> {
val data = call.arguments<ByteArray>()
val arguments = GattDisconnectArguments.parseFrom(data)
val address = arguments.address
val disconnect = disconnects[address]
val gatt = gatts[address]
if (disconnect != null || gatt == null || gatt.hashCode() != arguments.id) {
result.error(INVALID_REQUEST)
} else {
disconnects[address] = result
gatt.disconnect()
}
}
GATT_CONNECTION_LOST -> result.notImplemented()
GATT_CHARACTERISTIC_READ -> {
val data = call.arguments<ByteArray>()
val arguments = GattCharacteristicReadArguments.parseFrom(data)
val gatt = gatts[arguments.address]
if (gatt == null) result.error(INVALID_REQUEST)
else {
val serviceUUID = UUID.fromString(arguments.serviceUuid)
val service = gatt.getService(serviceUUID)
val uuid = UUID.fromString(arguments.uuid)
val characteristic = service.getCharacteristic(uuid)
val id = characteristic.hashCode()
val characteristicRead = characteristicReads[id]
if (characteristicRead != null || id != arguments.id) result.error(INVALID_REQUEST)
else {
val failed = !gatt.readCharacteristic(characteristic)
if (failed) result.error(READ_CHARACTERISTIC_FAILED)
else characteristicReads[id] = result
}
}
}
GATT_CHARACTERISTIC_WRITE -> {
val data = call.arguments<ByteArray>()
val arguments = GattCharacteristicWriteArguments.parseFrom(data)
val gatt = gatts[arguments.address]
if (gatt == null) result.error(INVALID_REQUEST)
else {
val serviceUUID = UUID.fromString(arguments.serviceUuid)
val service = gatt.getService(serviceUUID)
val uuid = UUID.fromString(arguments.uuid)
val characteristic = service.getCharacteristic(uuid)
val id = characteristic.hashCode()
val characteristicWrite = characteristicWrites[id]
if (characteristicWrite != null || id != arguments.id) result.error(INVALID_REQUEST)
else {
characteristic.value = arguments.value.toByteArray()
characteristic.writeType =
if (arguments.withoutResponse) BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
else BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
val failed = !gatt.writeCharacteristic(characteristic)
if (failed) result.error(WRITE_CHARACTERISTIC_FAILED)
else characteristicWrites[id] = result
}
}
}
GATT_CHARACTERISTIC_NOTIFY -> {
val data = call.arguments<ByteArray>()
val arguments = GattCharacteristicNotifyArguments.parseFrom(data)
val gatt = gatts[arguments.address]
if (gatt == null) result.error(INVALID_REQUEST)
else {
val serviceUUID = UUID.fromString(arguments.serviceUuid)
val service = gatt.getService(serviceUUID)
val uuid = UUID.fromString(arguments.uuid)
val characteristic = service.getCharacteristic(uuid)
val id = characteristic.hashCode()
val descriptorUUID = UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG)
val descriptor = characteristic.getDescriptor(descriptorUUID)
val descriptorId = descriptor.hashCode()
val descriptorWrite = descriptorWrites[descriptorId]
if (descriptorWrite != null || id != arguments.id) result.error(INVALID_REQUEST)
else {
var failed = !gatt.setCharacteristicNotification(characteristic, arguments.state)
if (failed) result.error(NOTIFY_CHARACTERISTIC_FAILED)
else {
descriptor.value =
if (arguments.state) BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
else BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
failed = !gatt.writeDescriptor(descriptor)
if (failed) result.error(WRITE_DESCRIPTOR_FAILED)
else descriptorWrites[descriptorId] = result
}
}
}
}
GATT_DESCRIPTOR_READ -> {
val data = call.arguments<ByteArray>()
val arguments = GattDescriptorReadArguments.parseFrom(data)
val gatt = gatts[arguments.address]
if (gatt == null) result.error(INVALID_REQUEST)
else {
val serviceUUID = UUID.fromString(arguments.serviceUuid)
val service = gatt.getService(serviceUUID)
val characteristicUUID = UUID.fromString(arguments.characteristicUuid)
val characteristic = service.getCharacteristic(characteristicUUID)
val uuid = UUID.fromString(arguments.uuid)
val descriptor = characteristic.getDescriptor(uuid)
val id = descriptor.hashCode()
val descriptorRead = descriptorReads[id]
if (descriptorRead != null || id != arguments.id) result.error(INVALID_REQUEST)
else {
val failed = !gatt.readDescriptor(descriptor)
if (failed) result.error(READ_DESCRIPTOR_FAILED)
else descriptorReads[id] = result
}
}
}
GATT_DESCRIPTOR_WRITE -> {
val data = call.arguments<ByteArray>()
val arguments = GattDescriptorWriteArguments.parseFrom(data)
val gatt = gatts[arguments.address]
if (gatt == null) result.error(INVALID_REQUEST)
else {
val serviceUUID = UUID.fromString(arguments.serviceUuid)
val service = gatt.getService(serviceUUID)
val characteristicUUID = UUID.fromString(arguments.characteristicUuid)
val characteristic = service.getCharacteristic(characteristicUUID)
val uuid = UUID.fromString(arguments.uuid)
val descriptor = characteristic.getDescriptor(uuid)
val id = descriptor.hashCode()
val descriptorWrite = descriptorWrites[id]
if (descriptorWrite != null || id != arguments.id) result.error(INVALID_REQUEST)
else {
val failed = !gatt.writeDescriptor(descriptor)
if (failed) result.error(WRITE_DESCRIPTOR_FAILED)
else descriptorWrites[id] = result
}
}
}
UNRECOGNIZED -> result.notImplemented()
}
}
override fun onListen(arguments: Any?, sink: EventSink?) {
Log.d(TAG, "onListen")
this.sink = sink
}
override fun onCancel(arguments: Any?) {
Log.d(TAG, "onCancel")
// This must be a hot reload for now, clear all status here.
// Clear connections.
for (gatt in gatts.values) gatt.close()
gatts.clear()
// Stop scan.
if (scanning) stopScan()
sink = null
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
this.binding = binding
this.binding!!.addRequestPermissionsResultListener(this)
}
override fun onDetachedFromActivity() {
binding!!.removeRequestPermissionsResultListener(this)
binding = null
}
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
onAttachedToActivity(binding)
}
override fun onDetachedFromActivityForConfigChanges() {
onDetachedFromActivity()
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>?,
grantResults: IntArray?
): Boolean {
return when {
requestCode != REQUEST_CODE || requestPermissionsHandler == null -> false
else -> {
val granted =
grantResults != null && grantResults.all { result -> result == PackageManager.PERMISSION_GRANTED }
requestPermissionsHandler!!.invoke(granted)
requestPermissionsHandler = null
true
}
}
} }
} }
fun Result.success() {
success(null)
}
fun Result.error(code: Int, message: String? = null, details: String? = null) {
error("$code", message, details)
}
val Any.TAG: String
get() = this::class.java.simpleName
val MethodCall.category: MessageCategory
get() = valueOf(method)
val Int.opened: Boolean
get() = when (this) {
BluetoothAdapter.STATE_OFF -> false
BluetoothAdapter.STATE_TURNING_ON -> false
BluetoothAdapter.STATE_ON -> true
BluetoothAdapter.STATE_TURNING_OFF -> true
else -> false
}

View File

@ -0,0 +1,45 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun connectArguments(block: dev.yanshouwang.bluetooth_low_energy.ConnectArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectArguments =
dev.yanshouwang.bluetooth_low_energy.ConnectArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectArguments.newBuilder()).apply { block() }._build()
object ConnectArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectArguments = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.ConnectArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectArguments =
dev.yanshouwang.bluetooth_low_energy.ConnectArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,62 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun connectionLost(block: dev.yanshouwang.bluetooth_low_energy.ConnectionLostKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost =
dev.yanshouwang.bluetooth_low_energy.ConnectionLostKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost.newBuilder()).apply { block() }._build()
object ConnectionLostKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost = _builder.build()
/**
* <code>int32 id = 1;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 1;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>int32 error_code = 2;</code>
*/
var errorCode: kotlin.Int
@JvmName("getErrorCode")
get() = _builder.getErrorCode()
@JvmName("setErrorCode")
set(value) {
_builder.setErrorCode(value)
}
/**
* <code>int32 error_code = 2;</code>
*/
fun clearErrorCode() {
_builder.clearErrorCode()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost.copy(block: dev.yanshouwang.bluetooth_low_energy.ConnectionLostKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost =
dev.yanshouwang.bluetooth_low_energy.ConnectionLostKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,79 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun discovery(block: dev.yanshouwang.bluetooth_low_energy.DiscoveryKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery =
dev.yanshouwang.bluetooth_low_energy.DiscoveryKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery.newBuilder()).apply { block() }._build()
object DiscoveryKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
/**
* <code>sint32 rssi = 2;</code>
*/
var rssi: kotlin.Int
@JvmName("getRssi")
get() = _builder.getRssi()
@JvmName("setRssi")
set(value) {
_builder.setRssi(value)
}
/**
* <code>sint32 rssi = 2;</code>
*/
fun clearRssi() {
_builder.clearRssi()
}
/**
* <code>bytes advertisements = 3;</code>
*/
var advertisements: com.google.protobuf.ByteString
@JvmName("getAdvertisements")
get() = _builder.getAdvertisements()
@JvmName("setAdvertisements")
set(value) {
_builder.setAdvertisements(value)
}
/**
* <code>bytes advertisements = 3;</code>
*/
fun clearAdvertisements() {
_builder.clearAdvertisements()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery.copy(block: dev.yanshouwang.bluetooth_low_energy.DiscoveryKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery =
dev.yanshouwang.bluetooth_low_energy.DiscoveryKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,125 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gATT(block: dev.yanshouwang.bluetooth_low_energy.GATTKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GATT =
dev.yanshouwang.bluetooth_low_energy.GATTKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GATT.newBuilder()).apply { block() }._build()
object GATTKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GATT.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GATT.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GATT = _builder.build()
/**
* <code>int32 id = 1;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 1;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>int32 mtu = 2;</code>
*/
var mtu: kotlin.Int
@JvmName("getMtu")
get() = _builder.getMtu()
@JvmName("setMtu")
set(value) {
_builder.setMtu(value)
}
/**
* <code>int32 mtu = 2;</code>
*/
fun clearMtu() {
_builder.clearMtu()
}
/**
* An uninstantiable, behaviorless type to represent the field in
* generics.
*/
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
class ServicesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattService services = 3;</code>
*/
val services: com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService, ServicesProxy>
@kotlin.jvm.JvmSynthetic
get() = com.google.protobuf.kotlin.DslList(
_builder.getServicesList()
)
/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattService services = 3;</code>
* @param value The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addServices")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService, ServicesProxy>.add(value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService) {
_builder.addServices(value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattService services = 3;</code>
* @param value The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignServices")
inline operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService, ServicesProxy>.plusAssign(value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService) {
add(value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattService services = 3;</code>
* @param values The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addAllServices")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService, ServicesProxy>.addAll(values: kotlin.collections.Iterable<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService>) {
_builder.addAllServices(values)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattService services = 3;</code>
* @param values The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignAllServices")
inline operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService, ServicesProxy>.plusAssign(values: kotlin.collections.Iterable<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService>) {
addAll(values)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattService services = 3;</code>
* @param index The index to set the value at.
* @param value The services to set.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("setServices")
operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService, ServicesProxy>.set(index: kotlin.Int, value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService) {
_builder.setServices(index, value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattService services = 3;</code>
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("clearServices")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService, ServicesProxy>.clear() {
_builder.clearServices()
}}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GATT.copy(block: dev.yanshouwang.bluetooth_low_energy.GATTKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GATT =
dev.yanshouwang.bluetooth_low_energy.GATTKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,193 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattCharacteristic(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic.newBuilder()).apply { block() }._build()
object GattCharacteristicKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic = _builder.build()
/**
* <code>int32 id = 1;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 1;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>string uuid = 2;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 2;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
/**
* An uninstantiable, behaviorless type to represent the field in
* generics.
*/
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
class DescriptorsProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattDescriptor descriptors = 3;</code>
*/
val descriptors: com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor, DescriptorsProxy>
@kotlin.jvm.JvmSynthetic
get() = com.google.protobuf.kotlin.DslList(
_builder.getDescriptorsList()
)
/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattDescriptor descriptors = 3;</code>
* @param value The descriptors to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addDescriptors")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor, DescriptorsProxy>.add(value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor) {
_builder.addDescriptors(value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattDescriptor descriptors = 3;</code>
* @param value The descriptors to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignDescriptors")
inline operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor, DescriptorsProxy>.plusAssign(value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor) {
add(value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattDescriptor descriptors = 3;</code>
* @param values The descriptors to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addAllDescriptors")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor, DescriptorsProxy>.addAll(values: kotlin.collections.Iterable<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor>) {
_builder.addAllDescriptors(values)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattDescriptor descriptors = 3;</code>
* @param values The descriptors to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignAllDescriptors")
inline operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor, DescriptorsProxy>.plusAssign(values: kotlin.collections.Iterable<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor>) {
addAll(values)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattDescriptor descriptors = 3;</code>
* @param index The index to set the value at.
* @param value The descriptors to set.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("setDescriptors")
operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor, DescriptorsProxy>.set(index: kotlin.Int, value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor) {
_builder.setDescriptors(index, value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattDescriptor descriptors = 3;</code>
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("clearDescriptors")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor, DescriptorsProxy>.clear() {
_builder.clearDescriptors()
}
/**
* <code>bool canRead = 4;</code>
*/
var canRead: kotlin.Boolean
@JvmName("getCanRead")
get() = _builder.getCanRead()
@JvmName("setCanRead")
set(value) {
_builder.setCanRead(value)
}
/**
* <code>bool canRead = 4;</code>
*/
fun clearCanRead() {
_builder.clearCanRead()
}
/**
* <code>bool canWrite = 5;</code>
*/
var canWrite: kotlin.Boolean
@JvmName("getCanWrite")
get() = _builder.getCanWrite()
@JvmName("setCanWrite")
set(value) {
_builder.setCanWrite(value)
}
/**
* <code>bool canWrite = 5;</code>
*/
fun clearCanWrite() {
_builder.clearCanWrite()
}
/**
* <code>bool canWriteWithoutResponse = 6;</code>
*/
var canWriteWithoutResponse: kotlin.Boolean
@JvmName("getCanWriteWithoutResponse")
get() = _builder.getCanWriteWithoutResponse()
@JvmName("setCanWriteWithoutResponse")
set(value) {
_builder.setCanWriteWithoutResponse(value)
}
/**
* <code>bool canWriteWithoutResponse = 6;</code>
*/
fun clearCanWriteWithoutResponse() {
_builder.clearCanWriteWithoutResponse()
}
/**
* <code>bool canNotify = 7;</code>
*/
var canNotify: kotlin.Boolean
@JvmName("getCanNotify")
get() = _builder.getCanNotify()
@JvmName("setCanNotify")
set(value) {
_builder.setCanNotify(value)
}
/**
* <code>bool canNotify = 7;</code>
*/
fun clearCanNotify() {
_builder.clearCanNotify()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic.copy(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,113 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattCharacteristicNotifyArguments(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicNotifyArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicNotifyArguments =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicNotifyArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicNotifyArguments.newBuilder()).apply { block() }._build()
object GattCharacteristicNotifyArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicNotifyArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicNotifyArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicNotifyArguments = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
/**
* <code>string service_uuid = 2;</code>
*/
var serviceUuid: kotlin.String
@JvmName("getServiceUuid")
get() = _builder.getServiceUuid()
@JvmName("setServiceUuid")
set(value) {
_builder.setServiceUuid(value)
}
/**
* <code>string service_uuid = 2;</code>
*/
fun clearServiceUuid() {
_builder.clearServiceUuid()
}
/**
* <code>string uuid = 3;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 3;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
/**
* <code>int32 id = 4;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 4;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>bool state = 5;</code>
*/
var state: kotlin.Boolean
@JvmName("getState")
get() = _builder.getState()
@JvmName("setState")
set(value) {
_builder.setState(value)
}
/**
* <code>bool state = 5;</code>
*/
fun clearState() {
_builder.clearState()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicNotifyArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicNotifyArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicNotifyArguments =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicNotifyArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,96 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattCharacteristicReadArguments(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicReadArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicReadArguments =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicReadArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicReadArguments.newBuilder()).apply { block() }._build()
object GattCharacteristicReadArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicReadArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicReadArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicReadArguments = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
/**
* <code>string service_uuid = 2;</code>
*/
var serviceUuid: kotlin.String
@JvmName("getServiceUuid")
get() = _builder.getServiceUuid()
@JvmName("setServiceUuid")
set(value) {
_builder.setServiceUuid(value)
}
/**
* <code>string service_uuid = 2;</code>
*/
fun clearServiceUuid() {
_builder.clearServiceUuid()
}
/**
* <code>string uuid = 3;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 3;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
/**
* <code>int32 id = 4;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 4;</code>
*/
fun clearId() {
_builder.clearId()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicReadArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicReadArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicReadArguments =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicReadArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,62 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattCharacteristicValue(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValueKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValueKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue.newBuilder()).apply { block() }._build()
object GattCharacteristicValueKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue = _builder.build()
/**
* <code>int32 id = 3;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 3;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>bytes value = 4;</code>
*/
var value: com.google.protobuf.ByteString
@JvmName("getValue")
get() = _builder.getValue()
@JvmName("setValue")
set(value) {
_builder.setValue(value)
}
/**
* <code>bytes value = 4;</code>
*/
fun clearValue() {
_builder.clearValue()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue.copy(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValueKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValueKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,130 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattCharacteristicWriteArguments(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicWriteArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicWriteArguments =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicWriteArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicWriteArguments.newBuilder()).apply { block() }._build()
object GattCharacteristicWriteArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicWriteArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicWriteArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicWriteArguments = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
/**
* <code>string service_uuid = 2;</code>
*/
var serviceUuid: kotlin.String
@JvmName("getServiceUuid")
get() = _builder.getServiceUuid()
@JvmName("setServiceUuid")
set(value) {
_builder.setServiceUuid(value)
}
/**
* <code>string service_uuid = 2;</code>
*/
fun clearServiceUuid() {
_builder.clearServiceUuid()
}
/**
* <code>string uuid = 3;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 3;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
/**
* <code>int32 id = 4;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 4;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>bytes value = 5;</code>
*/
var value: com.google.protobuf.ByteString
@JvmName("getValue")
get() = _builder.getValue()
@JvmName("setValue")
set(value) {
_builder.setValue(value)
}
/**
* <code>bytes value = 5;</code>
*/
fun clearValue() {
_builder.clearValue()
}
/**
* <code>bool withoutResponse = 6;</code>
*/
var withoutResponse: kotlin.Boolean
@JvmName("getWithoutResponse")
get() = _builder.getWithoutResponse()
@JvmName("setWithoutResponse")
set(value) {
_builder.setWithoutResponse(value)
}
/**
* <code>bool withoutResponse = 6;</code>
*/
fun clearWithoutResponse() {
_builder.clearWithoutResponse()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicWriteArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.GattCharacteristicWriteArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicWriteArguments =
dev.yanshouwang.bluetooth_low_energy.GattCharacteristicWriteArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,62 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattDescriptor(block: dev.yanshouwang.bluetooth_low_energy.GattDescriptorKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor =
dev.yanshouwang.bluetooth_low_energy.GattDescriptorKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor.newBuilder()).apply { block() }._build()
object GattDescriptorKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor = _builder.build()
/**
* <code>int32 id = 1;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 1;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>string uuid = 2;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 2;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor.copy(block: dev.yanshouwang.bluetooth_low_energy.GattDescriptorKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptor =
dev.yanshouwang.bluetooth_low_energy.GattDescriptorKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,113 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattDescriptorReadArguments(block: dev.yanshouwang.bluetooth_low_energy.GattDescriptorReadArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorReadArguments =
dev.yanshouwang.bluetooth_low_energy.GattDescriptorReadArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorReadArguments.newBuilder()).apply { block() }._build()
object GattDescriptorReadArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorReadArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorReadArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorReadArguments = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
/**
* <code>string service_uuid = 2;</code>
*/
var serviceUuid: kotlin.String
@JvmName("getServiceUuid")
get() = _builder.getServiceUuid()
@JvmName("setServiceUuid")
set(value) {
_builder.setServiceUuid(value)
}
/**
* <code>string service_uuid = 2;</code>
*/
fun clearServiceUuid() {
_builder.clearServiceUuid()
}
/**
* <code>string characteristic_uuid = 3;</code>
*/
var characteristicUuid: kotlin.String
@JvmName("getCharacteristicUuid")
get() = _builder.getCharacteristicUuid()
@JvmName("setCharacteristicUuid")
set(value) {
_builder.setCharacteristicUuid(value)
}
/**
* <code>string characteristic_uuid = 3;</code>
*/
fun clearCharacteristicUuid() {
_builder.clearCharacteristicUuid()
}
/**
* <code>string uuid = 4;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 4;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
/**
* <code>int32 id = 5;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 5;</code>
*/
fun clearId() {
_builder.clearId()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorReadArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.GattDescriptorReadArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorReadArguments =
dev.yanshouwang.bluetooth_low_energy.GattDescriptorReadArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,130 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattDescriptorWriteArguments(block: dev.yanshouwang.bluetooth_low_energy.GattDescriptorWriteArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorWriteArguments =
dev.yanshouwang.bluetooth_low_energy.GattDescriptorWriteArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorWriteArguments.newBuilder()).apply { block() }._build()
object GattDescriptorWriteArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorWriteArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorWriteArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorWriteArguments = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
/**
* <code>string service_uuid = 2;</code>
*/
var serviceUuid: kotlin.String
@JvmName("getServiceUuid")
get() = _builder.getServiceUuid()
@JvmName("setServiceUuid")
set(value) {
_builder.setServiceUuid(value)
}
/**
* <code>string service_uuid = 2;</code>
*/
fun clearServiceUuid() {
_builder.clearServiceUuid()
}
/**
* <code>string characteristic_uuid = 3;</code>
*/
var characteristicUuid: kotlin.String
@JvmName("getCharacteristicUuid")
get() = _builder.getCharacteristicUuid()
@JvmName("setCharacteristicUuid")
set(value) {
_builder.setCharacteristicUuid(value)
}
/**
* <code>string characteristic_uuid = 3;</code>
*/
fun clearCharacteristicUuid() {
_builder.clearCharacteristicUuid()
}
/**
* <code>string uuid = 4;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 4;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
/**
* <code>int32 id = 5;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 5;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>bytes value = 6;</code>
*/
var value: com.google.protobuf.ByteString
@JvmName("getValue")
get() = _builder.getValue()
@JvmName("setValue")
set(value) {
_builder.setValue(value)
}
/**
* <code>bytes value = 6;</code>
*/
fun clearValue() {
_builder.clearValue()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorWriteArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.GattDescriptorWriteArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDescriptorWriteArguments =
dev.yanshouwang.bluetooth_low_energy.GattDescriptorWriteArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,62 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattDisconnectArguments(block: dev.yanshouwang.bluetooth_low_energy.GattDisconnectArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDisconnectArguments =
dev.yanshouwang.bluetooth_low_energy.GattDisconnectArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDisconnectArguments.newBuilder()).apply { block() }._build()
object GattDisconnectArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDisconnectArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDisconnectArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDisconnectArguments = _builder.build()
/**
* <code>string address = 1;</code>
*/
var address: kotlin.String
@JvmName("getAddress")
get() = _builder.getAddress()
@JvmName("setAddress")
set(value) {
_builder.setAddress(value)
}
/**
* <code>string address = 1;</code>
*/
fun clearAddress() {
_builder.clearAddress()
}
/**
* <code>int32 id = 2;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 2;</code>
*/
fun clearId() {
_builder.clearId()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDisconnectArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.GattDisconnectArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattDisconnectArguments =
dev.yanshouwang.bluetooth_low_energy.GattDisconnectArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,125 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun gattService(block: dev.yanshouwang.bluetooth_low_energy.GattServiceKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService =
dev.yanshouwang.bluetooth_low_energy.GattServiceKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService.newBuilder()).apply { block() }._build()
object GattServiceKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService = _builder.build()
/**
* <code>int32 id = 1;</code>
*/
var id: kotlin.Int
@JvmName("getId")
get() = _builder.getId()
@JvmName("setId")
set(value) {
_builder.setId(value)
}
/**
* <code>int32 id = 1;</code>
*/
fun clearId() {
_builder.clearId()
}
/**
* <code>string uuid = 2;</code>
*/
var uuid: kotlin.String
@JvmName("getUuid")
get() = _builder.getUuid()
@JvmName("setUuid")
set(value) {
_builder.setUuid(value)
}
/**
* <code>string uuid = 2;</code>
*/
fun clearUuid() {
_builder.clearUuid()
}
/**
* An uninstantiable, behaviorless type to represent the field in
* generics.
*/
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
class CharacteristicsProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattCharacteristic characteristics = 3;</code>
*/
val characteristics: com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic, CharacteristicsProxy>
@kotlin.jvm.JvmSynthetic
get() = com.google.protobuf.kotlin.DslList(
_builder.getCharacteristicsList()
)
/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattCharacteristic characteristics = 3;</code>
* @param value The characteristics to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addCharacteristics")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic, CharacteristicsProxy>.add(value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic) {
_builder.addCharacteristics(value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattCharacteristic characteristics = 3;</code>
* @param value The characteristics to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignCharacteristics")
inline operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic, CharacteristicsProxy>.plusAssign(value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic) {
add(value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattCharacteristic characteristics = 3;</code>
* @param values The characteristics to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addAllCharacteristics")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic, CharacteristicsProxy>.addAll(values: kotlin.collections.Iterable<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic>) {
_builder.addAllCharacteristics(values)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattCharacteristic characteristics = 3;</code>
* @param values The characteristics to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignAllCharacteristics")
inline operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic, CharacteristicsProxy>.plusAssign(values: kotlin.collections.Iterable<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic>) {
addAll(values)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattCharacteristic characteristics = 3;</code>
* @param index The index to set the value at.
* @param value The characteristics to set.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("setCharacteristics")
operator fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic, CharacteristicsProxy>.set(index: kotlin.Int, value: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic) {
_builder.setCharacteristics(index, value)
}/**
* <code>repeated .dev.yanshouwang.bluetooth_low_energy.GattCharacteristic characteristics = 3;</code>
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("clearCharacteristics")
fun com.google.protobuf.kotlin.DslList<dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristic, CharacteristicsProxy>.clear() {
_builder.clearCharacteristics()
}}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService.copy(block: dev.yanshouwang.bluetooth_low_energy.GattServiceKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattService =
dev.yanshouwang.bluetooth_low_energy.GattServiceKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,172 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun message(block: dev.yanshouwang.bluetooth_low_energy.MessageKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message =
dev.yanshouwang.bluetooth_low_energy.MessageKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message.newBuilder()).apply { block() }._build()
object MessageKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message = _builder.build()
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.MessageCategory category = 1;</code>
*/
var category: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.MessageCategory
@JvmName("getCategory")
get() = _builder.getCategory()
@JvmName("setCategory")
set(value) {
_builder.setCategory(value)
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.MessageCategory category = 1;</code>
*/
fun clearCategory() {
_builder.clearCategory()
}
/**
* <code>bool state = 2;</code>
*/
var state: kotlin.Boolean
@JvmName("getState")
get() = _builder.getState()
@JvmName("setState")
set(value) {
_builder.setState(value)
}
/**
* <code>bool state = 2;</code>
*/
fun clearState() {
_builder.clearState()
}
/**
* <code>bool state = 2;</code>
* @return Whether the state field is set.
*/
fun hasState(): kotlin.Boolean {
return _builder.hasState()
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.Discovery discovery = 3;</code>
*/
var discovery: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Discovery
@JvmName("getDiscovery")
get() = _builder.getDiscovery()
@JvmName("setDiscovery")
set(value) {
_builder.setDiscovery(value)
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.Discovery discovery = 3;</code>
*/
fun clearDiscovery() {
_builder.clearDiscovery()
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.Discovery discovery = 3;</code>
* @return Whether the discovery field is set.
*/
fun hasDiscovery(): kotlin.Boolean {
return _builder.hasDiscovery()
}
/**
* <code>bool scanning = 4;</code>
*/
var scanning: kotlin.Boolean
@JvmName("getScanning")
get() = _builder.getScanning()
@JvmName("setScanning")
set(value) {
_builder.setScanning(value)
}
/**
* <code>bool scanning = 4;</code>
*/
fun clearScanning() {
_builder.clearScanning()
}
/**
* <code>bool scanning = 4;</code>
* @return Whether the scanning field is set.
*/
fun hasScanning(): kotlin.Boolean {
return _builder.hasScanning()
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.ConnectionLost connectionLost = 5;</code>
*/
var connectionLost: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.ConnectionLost
@JvmName("getConnectionLost")
get() = _builder.getConnectionLost()
@JvmName("setConnectionLost")
set(value) {
_builder.setConnectionLost(value)
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.ConnectionLost connectionLost = 5;</code>
*/
fun clearConnectionLost() {
_builder.clearConnectionLost()
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.ConnectionLost connectionLost = 5;</code>
* @return Whether the connectionLost field is set.
*/
fun hasConnectionLost(): kotlin.Boolean {
return _builder.hasConnectionLost()
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValue characteristicValue = 6;</code>
*/
var characteristicValue: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.GattCharacteristicValue
@JvmName("getCharacteristicValue")
get() = _builder.getCharacteristicValue()
@JvmName("setCharacteristicValue")
set(value) {
_builder.setCharacteristicValue(value)
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValue characteristicValue = 6;</code>
*/
fun clearCharacteristicValue() {
_builder.clearCharacteristicValue()
}
/**
* <code>.dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValue characteristicValue = 6;</code>
* @return Whether the characteristicValue field is set.
*/
fun hasCharacteristicValue(): kotlin.Boolean {
return _builder.hasCharacteristicValue()
}
val valueCase: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message.ValueCase
@JvmName("getValueCase")
get() = _builder.getValueCase()
fun clearValue() {
_builder.clearValue()
}
}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message.copy(block: dev.yanshouwang.bluetooth_low_energy.MessageKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.Message =
dev.yanshouwang.bluetooth_low_energy.MessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -0,0 +1,96 @@
//Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message.proto
package dev.yanshouwang.bluetooth_low_energy;
@kotlin.jvm.JvmSynthetic
inline fun startDiscoveryArguments(block: dev.yanshouwang.bluetooth_low_energy.StartDiscoveryArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.StartDiscoveryArguments =
dev.yanshouwang.bluetooth_low_energy.StartDiscoveryArgumentsKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.StartDiscoveryArguments.newBuilder()).apply { block() }._build()
object StartDiscoveryArgumentsKt {
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
@com.google.protobuf.kotlin.ProtoDslMarker
class Dsl private constructor(
@kotlin.jvm.JvmField private val _builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.StartDiscoveryArguments.Builder
) {
companion object {
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.StartDiscoveryArguments.Builder): Dsl = Dsl(builder)
}
@kotlin.jvm.JvmSynthetic
@kotlin.PublishedApi
internal fun _build(): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.StartDiscoveryArguments = _builder.build()
/**
* An uninstantiable, behaviorless type to represent the field in
* generics.
*/
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
class ServicesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
/**
* <code>repeated string services = 1;</code>
* @return A list containing the services.
*/
val services: com.google.protobuf.kotlin.DslList<kotlin.String, ServicesProxy>
@kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
get() = com.google.protobuf.kotlin.DslList(
_builder.getServicesList()
)
/**
* <code>repeated string services = 1;</code>
* @param value The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addServices")
fun com.google.protobuf.kotlin.DslList<kotlin.String, ServicesProxy>.add(value: kotlin.String) {
_builder.addServices(value)
}
/**
* <code>repeated string services = 1;</code>
* @param value The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignServices")
operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ServicesProxy>.plusAssign(value: kotlin.String) {
_builder.addServices(value)
}
/**
* <code>repeated string services = 1;</code>
* @param values The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("addAllServices")
fun com.google.protobuf.kotlin.DslList<kotlin.String, ServicesProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
_builder.addAllServices(values)
}
/**
* <code>repeated string services = 1;</code>
* @param values The services to add.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("plusAssignAllServices")
operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ServicesProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
_builder.addAllServices(values)
}
/**
* <code>repeated string services = 1;</code>
* @param index The index to set the value at.
* @param value The services to set.
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("setServices")
operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ServicesProxy>.set(index: kotlin.Int, value: kotlin.String) {
_builder.setServices(index, value)
}/**
* <code>repeated string services = 1;</code>
*/
@kotlin.jvm.JvmSynthetic
@kotlin.jvm.JvmName("clearServices")
fun com.google.protobuf.kotlin.DslList<kotlin.String, ServicesProxy>.clear() {
_builder.clearServices()
}}
}
@kotlin.jvm.JvmSynthetic
inline fun dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.StartDiscoveryArguments.copy(block: dev.yanshouwang.bluetooth_low_energy.StartDiscoveryArgumentsKt.Dsl.() -> Unit): dev.yanshouwang.bluetooth_low_energy.MessageOuterClass.StartDiscoveryArguments =
dev.yanshouwang.bluetooth_low_energy.StartDiscoveryArgumentsKt.Dsl._create(this.toBuilder()).apply { block() }._build()

View File

@ -33,9 +33,8 @@ android {
} }
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "dev.yanshouwang.bluetooth_low_energy_example" applicationId "dev.yanshouwang.bluetooth_low_energy_example"
minSdkVersion 16 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName

View File

@ -1,8 +1,9 @@
buildscript { buildscript {
ext.kotlin_version = '1.3.50' ext.kotlin_version = '1.5.20'
repositories { repositories {
google() google()
jcenter() mavenCentral()
maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
} }
dependencies { dependencies {
@ -14,7 +15,8 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
} }
} }

View File

@ -3,4 +3,5 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip #distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-6.7-all.zip

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,8 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart'; import 'views.dart';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
void main() { void main() {
runApp(MyApp()); runApp(MyApp());
@ -22,14 +20,13 @@ class _MyAppState extends State<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
home: Scaffold( theme: ThemeData(
appBar: AppBar( fontFamily: 'IBM Plex Mono',
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: \n'),
),
), ),
home: HomeView(),
routes: {
'gatt': (context) => GattView(),
},
); );
} }
} }

3
example/lib/views.dart Normal file
View File

@ -0,0 +1,3 @@
export 'views/home_view.dart';
export 'views/gatt_view.dart';
export 'views/flip_view.dart';

View File

@ -0,0 +1,37 @@
import 'package:bluetooth_low_energy_example/widgets.dart';
import 'package:flutter/material.dart';
class FlipView extends StatelessWidget {
final front = Container(
height: 300,
width: 300,
color: Colors.orange,
child: Center(
child: Text('正面'),
),
);
final back = Container(
height: 300,
width: 300,
color: Colors.blue,
child: Center(
child: Text(
'反面',
style: TextStyle(color: Colors.white),
),
),
);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: FlipCard(
front: front,
back: back,
),
),
),
);
}
}

View File

@ -0,0 +1,383 @@
import 'dart:async';
import 'dart:convert';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
import 'package:convert/convert.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class GattView extends StatefulWidget {
const GattView({Key? key}) : super(key: key);
@override
_GattViewState createState() => _GattViewState();
}
class _GattViewState extends State<GattView> {
final ValueNotifier<ConnectionState> state;
GATT? gatt;
StreamSubscription? connectionLostSubscription;
final ValueNotifier<GattService?> service;
final ValueNotifier<GattCharacteristic?> characteristic;
final TextEditingController writeController;
final ValueNotifier<Map<GattCharacteristic, StreamSubscription>> notifies;
final ValueNotifier<List<String>> logs;
late MAC address;
_GattViewState()
: state = ValueNotifier(ConnectionState.disconnected),
service = ValueNotifier(null),
characteristic = ValueNotifier(null),
writeController = TextEditingController(),
notifies = ValueNotifier({}),
logs = ValueNotifier([]);
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
address = ModalRoute.of(context)!.settings.arguments as MAC;
return Scaffold(
appBar: AppBar(
title: Text('$address'),
actions: [
connectionView,
],
),
body: bodyView,
);
}
void Function()? disposeListener;
@override
void dispose() {
super.dispose();
if (state.value != ConnectionState.disconnected) {
disposeListener ??= () => disposeGATT();
state.addListener(disposeListener!);
if (state.value == ConnectionState.connected) {
disconnect();
}
} else {
state.dispose();
service.dispose();
characteristic.dispose();
notifies.dispose();
logs.dispose();
}
}
void disposeGATT() {
switch (state.value) {
case ConnectionState.connected:
disconnect();
break;
case ConnectionState.disconnected:
state.removeListener(disposeListener!);
state.dispose();
service.dispose();
characteristic.dispose();
notifies.dispose();
logs.dispose();
break;
default:
break;
}
}
void connect() async {
try {
state.value = ConnectionState.connecting;
gatt = await central.connect(address);
state.value = ConnectionState.connected;
connectionLostSubscription = gatt!.connectionLost.listen(
(errorCode) async {
for (var subscription in notifies.value.values) {
await subscription.cancel();
}
await connectionLostSubscription!.cancel();
gatt = null;
connectionLostSubscription = null;
service.value = null;
characteristic.value = null;
notifies.value.clear();
logs.value.clear();
state.value = ConnectionState.disconnected;
},
);
} on PlatformException {
state.value = ConnectionState.disconnected;
}
}
void disconnect() async {
try {
state.value = ConnectionState.disconnecting;
await gatt!.disconnect();
for (var subscription in notifies.value.values) {
await subscription.cancel();
}
await connectionLostSubscription!.cancel();
gatt = null;
connectionLostSubscription = null;
service.value = null;
characteristic.value = null;
notifies.value.clear();
logs.value.clear();
state.value = ConnectionState.disconnected;
} on PlatformException {
state.value = ConnectionState.connected;
}
}
}
enum ConnectionState {
disconnected,
connecting,
connected,
disconnecting,
}
extension on _GattViewState {
Widget get connectionView {
return ValueListenableBuilder(
valueListenable: state,
builder: (context, ConnectionState stateValue, child) {
void Function()? onPressed;
var data = '';
switch (stateValue) {
case ConnectionState.disconnected:
onPressed = connect;
data = '连接';
break;
case ConnectionState.connected:
onPressed = disconnect;
data = '断开';
break;
default:
break;
}
return TextButton(
onPressed: onPressed,
child: Text(
data,
style: TextStyle(
color: Colors.white,
),
),
);
},
);
}
Widget get bodyView {
return ValueListenableBuilder(
valueListenable: state,
builder: (context, ConnectionState stateValue, child) {
switch (stateValue) {
case ConnectionState.disconnected:
return disconnectedView;
case ConnectionState.connecting:
return connectingView;
case ConnectionState.connected:
return connectedView;
case ConnectionState.disconnecting:
return disconnectingView;
default:
throw UnimplementedError();
}
},
);
}
Widget get disconnectedView {
return Center(
child: Text('未连接'),
);
}
Widget get connectingView {
return Center(
child: Text('正在建立连接'),
);
}
Widget get connectedView {
return ValueListenableBuilder(
valueListenable: service,
builder: (context, GattService? serviceValue, child) {
final services = gatt!.services.values
.map((service) => DropdownMenuItem<GattService>(
value: service,
child: Text(
service.uuid.name,
softWrap: false,
),
))
.toList();
final serviceView = DropdownButton<GattService>(
isExpanded: true,
hint: Text('选择服务'),
value: serviceValue,
items: services,
onChanged: (value) {
service.value = value;
characteristic.value = null;
},
);
final views = <Widget>[serviceView];
if (serviceValue != null) {
final characteristics = serviceValue.characteristics.values
.map((characteristic) => DropdownMenuItem(
value: characteristic,
child: Text(
characteristic.uuid.name,
softWrap: false,
),
))
.toList();
final characteristicView = ValueListenableBuilder(
valueListenable: characteristic,
builder: (context, GattCharacteristic? characteristicValue, child) {
final canWrite = characteristicValue != null &&
(characteristicValue.canWrite ||
characteristicValue.canWriteWithoutResponse);
final canRead =
characteristicValue != null && characteristicValue.canRead;
final canNotify =
characteristicValue != null && characteristicValue.canNotify;
final readAndNotifyView = Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: canRead
? () async {
final value = await characteristicValue!.read();
final time = DateTime.now().display;
final log = '[$time][READ] ${hex.encode(value)}';
logs.value = [...logs.value, log];
}
: null,
icon: Icon(Icons.archive),
),
ValueListenableBuilder(
valueListenable: notifies,
builder: (context,
Map<GattCharacteristic, StreamSubscription>
notifiesValue,
child) {
final notifying =
notifiesValue.containsKey(characteristicValue);
return IconButton(
onPressed: canNotify
? () async {
if (notifying) {
await characteristicValue!.notify(false);
await notifiesValue
.remove(characteristicValue)!
.cancel();
} else {
await characteristicValue!.notify(true);
notifiesValue[characteristicValue] =
characteristicValue.valueChanged
.listen((value) {
final time = DateTime.now().display;
final log =
'[$time][NOTIFY] ${hex.encode(value)}';
logs.value = [...logs.value, log];
});
}
notifies.value = {...notifiesValue};
}
: null,
icon: Icon(
Icons.notifications,
color: notifying ? Colors.blue : null,
),
);
}),
],
);
final controllerView = TextField(
controller: writeController,
decoration: InputDecoration(
suffixIcon: IconButton(
onPressed: canWrite
? () {
final value = utf8.encode(writeController.text);
final withoutResponse =
!characteristicValue!.canWrite;
characteristicValue.write(value,
withoutResponse: withoutResponse);
}
: null,
icon: Icon(Icons.send),
),
),
);
return Column(
children: [
DropdownButton<GattCharacteristic>(
isExpanded: true,
hint: Text('选择特征值'),
value: characteristicValue,
items: characteristics,
onChanged: (value) => characteristic.value = value,
),
readAndNotifyView,
controllerView,
],
);
},
);
views.add(characteristicView);
}
final loggerView = Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: ValueListenableBuilder(
valueListenable: logs,
builder: (context, List<String> logsValue, child) {
return ListView.builder(
itemCount: logsValue.length,
itemBuilder: (context, i) {
final log = logsValue[i];
return Text(log);
},
);
}),
),
);
views.add(loggerView);
return Container(
padding: EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: views,
),
);
},
);
}
Widget get disconnectingView {
return Center(
child: Text('正在断开连接'),
);
}
}
extension on DateTime {
String get display {
final hh = hour.toString().padLeft(2, '0');
final mm = minute.toString().padLeft(2, '0');
final ss = second.toString().padLeft(2, '0');
return '$hh:$mm:$ss';
}
}

View File

@ -0,0 +1,232 @@
import 'dart:async';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
import 'package:convert/convert.dart';
import 'package:flutter/material.dart';
class HomeView extends StatefulWidget {
const HomeView({Key? key}) : super(key: key);
@override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
final ValueNotifier<bool> discovering;
final ValueNotifier<Map<MAC, Discovery>> discoveries;
late StreamSubscription<bool> stateSubscription;
late StreamSubscription<Discovery> discoverySubscription;
_HomeViewState()
: discovering = ValueNotifier(false),
discoveries = ValueNotifier({});
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addObserver(this);
stateSubscription = central.stateChanged.listen((state) {
if (state) {
startDiscovery();
} else {
discoveries.value = {};
discovering.value = false;
}
});
discoverySubscription = central.discovered.listen(
(discovery) {
discoveries.value[discovery.address] = discovery;
discoveries.value = {...discoveries.value};
},
);
startDiscovery();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
}
@override
void dispose() {
stopDiscovery();
stateSubscription.cancel();
discoverySubscription.cancel();
discoveries.dispose();
discovering.dispose();
WidgetsBinding.instance!.removeObserver(this);
print('dispose');
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: bodyView,
);
}
void startDiscovery() async {
final state = await central.state;
if (!state) return;
await central.startDiscovery();
discovering.value = true;
}
void stopDiscovery() async {
final state = await central.state;
if (!state) return;
await central.stopDiscovery();
discovering.value = false;
}
void showAdvertisements(Discovery discovery) {
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
elevation: 0.0,
builder: (context) => buildAdvertisementsView(discovery),
);
}
void showGattView(Discovery discovery) async {
stopDiscovery();
await Navigator.of(context).pushNamed(
'gatt',
arguments: discovery.address,
);
startDiscovery();
}
}
extension on _HomeViewState {
Widget get bodyView {
return FutureBuilder<bool>(
future: central.state,
builder: (context, snapshot) => snapshot.hasData
? StreamBuilder<bool>(
stream: central.stateChanged,
initialData: snapshot.data,
builder: (context, snapshot) =>
snapshot.data! ? discoveriesView : closedView,
)
: closedView,
);
}
Widget get closedView {
return Center(
child: Text('蓝牙未开启'),
);
}
Widget get discoveriesView {
return RefreshIndicator(
onRefresh: () async => discoveries.value = {},
child: ValueListenableBuilder(
valueListenable: discoveries,
builder: (context, Map<MAC, Discovery> discoveries, child) {
return ListView.builder(
padding: EdgeInsets.all(6.0),
itemCount: discoveries.length,
itemBuilder: (context, i) {
final discovery = discoveries.values.elementAt(i);
return Card(
color: Colors.amber,
clipBehavior: Clip.antiAlias,
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(12.0),
bottomLeft: Radius.circular(12.0)),
),
margin: EdgeInsets.all(6.0),
key: Key(discovery.address.name),
child: InkWell(
splashColor: Colors.purple,
onTap: () => showGattView(discovery),
onLongPress: () => showAdvertisements(discovery),
child: Container(
height: 100.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(discovery.name ?? 'NaN'),
Text(discovery.address.name),
],
),
Text(discovery.rssi.toString()),
],
),
),
),
);
},
);
},
),
);
}
Widget buildAdvertisementsView(Discovery discovery) {
final widgets = <Widget>[
Row(
children: [
Text('Type'),
Expanded(
child: Center(
child: Text('Value'),
),
),
],
),
Divider(),
];
for (final entry in discovery.advertisements.entries) {
final key = entry.key.toRadixString(16).padLeft(2, '0');
final value = hex.encode(entry.value);
final widget = Row(
children: [
Text('0x$key'),
Container(width: 12.0),
Expanded(
child: Text(
'$value',
softWrap: true,
),
),
],
);
widgets.add(widget);
if (entry.key != discovery.advertisements.entries.last.key) {
final divider = Divider();
widgets.add(divider);
}
}
return Container(
margin: const EdgeInsets.all(12.0),
child: Material(
elevation: 1.0,
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.0),
bottomRight: Radius.circular(12.0),
),
),
clipBehavior: Clip.antiAlias,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: widgets,
),
),
),
);
}
}

1
example/lib/widgets.dart Normal file
View File

@ -0,0 +1 @@
export 'widgets/flip_card.dart';

View File

@ -0,0 +1,106 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class FlipCard extends StatefulWidget {
final Widget? front;
final Widget? back;
const FlipCard({
Key? key,
@required this.front,
@required this.back,
}) : assert(front != null),
assert(back != null),
super(key: key);
@override
_FlipCardState createState() => _FlipCardState();
}
class _FlipCardState extends State<FlipCard> with TickerProviderStateMixin {
final ValueNotifier<double> angle;
late AnimationController animationController;
late Animation<double> frontAnimation;
late Animation<double> backAnimation;
_FlipCardState() : angle = ValueNotifier(0.0);
bool isFront = true;
bool hasHalf = false;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1000),
);
animationController.addListener(() {
if (animationController.value > 0.5) {
if (hasHalf == false) {
isFront = !isFront;
}
hasHalf = true;
}
setState(() {});
});
animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
hasHalf = false;
}
});
frontAnimation = Tween(begin: 0.0, end: 0.5).animate(
CurvedAnimation(
parent: animationController,
curve: Interval(0.0, 0.5, curve: Curves.easeIn),
),
);
backAnimation = Tween(begin: 1.5, end: 2.0).animate(CurvedAnimation(
parent: animationController,
curve: Interval(0.5, 1.0, curve: Curves.easeOut)));
}
void animate() {
animationController.stop();
animationController.value = 0;
animationController.forward();
}
@override
void dispose() {
super.dispose();
animationController.dispose();
}
@override
Widget build(BuildContext context) {
if (animationController.status == AnimationStatus.forward) {
if (hasHalf == true) {
angle.value = backAnimation.value;
} else {
angle.value = frontAnimation.value;
}
}
return GestureDetector(
onHorizontalDragUpdate: (details) {
print(details.delta);
angle.value += 0.01;
},
child: Container(
child: ValueListenableBuilder(
valueListenable: angle,
builder: (BuildContext context, double angle, Widget? child) {
return Transform(
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(angle),
alignment: Alignment.center,
child: IndexedStack(
index: isFront ? 0 : 1,
children: <Widget>[widget.front!, widget.back!],
),
);
},
),
),
);
}
}

View File

@ -51,7 +51,7 @@ packages:
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
convert: convert:
dependency: transitive dependency: "direct main"
description: description:
name: convert name: convert
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
@ -83,6 +83,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_simple_treeview:
dependency: "direct main"
description:
name: flutter_simple_treeview
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.0-nullsafety.1"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter

View File

@ -21,6 +21,8 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
convert: ^3.0.0
flutter_simple_treeview: ^3.0.0-nullsafety.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -68,3 +70,12 @@ flutter:
# #
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages # see https://flutter.dev/custom-fonts/#from-packages
fonts:
- family: IBM Plex Mono
fonts:
- asset: fonts/IBMPlexMono-Regular.ttf
- asset: fonts/IBMPlexMono-Italic.ttf
style: italic
- asset: fonts/IBMPlexMono-Bold.ttf
weight: 700

View File

@ -1,7 +1,20 @@
export 'src/bluetooth_manager.dart'; library bluetooth_low_energy;
export 'src/bluetooth.dart';
export 'src/discovery.dart'; import 'dart:async';
export 'src/uuid.dart'; import 'dart:convert';
export 'src/gatt_service.dart';
export 'src/gatt_characteristic.dart'; import 'package:convert/convert.dart';
export 'src/gatt_descriptor.dart';
import 'src/message.pb.dart' as proto;
import 'src/util.dart';
part 'src/bluetooth.dart';
part 'src/central.dart';
part 'src/discovery.dart';
part 'src/gatt.dart';
part 'src/gatt_service.dart';
part 'src/gatt_characteristic.dart';
part 'src/gatt_descriptor.dart';
part 'src/mac.dart';
part 'src/uuid.dart';
part 'src/extension.dart';

View File

@ -1,9 +1,32 @@
import 'mac.dart'; part of bluetooth_low_energy;
/// The abstract base class that manages central and peripheral objects.
abstract class Bluetooth { abstract class Bluetooth {
MAC get address; /// The availability of the bluetooth.
Future<bool> get available;
/// The current state of the bluetooth.
Future<bool> get state;
/// The bluetooths state changed.
Stream<bool> get stateChanged;
} }
abstract class Central extends Bluetooth {} class _Bluetooth implements Bluetooth {
@override
Future<bool> get available => method
.invokeMethod<bool>(proto.MessageCategory.BLUETOOTH_AVAILABLE.name)
.then((value) => value!);
abstract class Peripheral extends Bluetooth {} @override
Future<bool> get state => method
.invokeMethod<bool>(proto.MessageCategory.BLUETOOTH_STATE.name)
.then((value) => value!);
@override
Stream<bool> get stateChanged => stream
.map((event) => proto.Message.fromBuffer(event))
.where((message) =>
message.category == proto.MessageCategory.BLUETOOTH_STATE)
.map((message) => message.state);
}

View File

@ -1,133 +0,0 @@
import 'bluetooth.dart';
import 'channel.dart';
import 'discovery.dart';
import 'exception.dart';
import 'message.pb.dart' as message;
import 'uuid.dart';
/// The abstract base class that manages central and peripheral objects.
abstract class BluetoothManager {
/// The current state of the manager.
Future<BluetoothManagerState> get state;
/// The central managers state changed.
Stream<BluetoothManagerState> get stateChanged;
factory BluetoothManager() => _BluetoothManager();
}
class _BluetoothManager implements BluetoothManager {
@override
Future<BluetoothManagerState> get state => method
.invokeMethod<int>(message.MessageCategory.BLUETOOTH_MANAGER_STATE.name)
.then((i) => message.BluetoothManagerState.valueOf(i!)!.model);
@override
Stream<BluetoothManagerState> get stateChanged => stream
.map((i) => message.Message.fromBuffer(i))
.where(
(i) => i.category == message.MessageCategory.BLUETOOTH_MANAGER_STATE)
.map((i) => i.state.model);
}
/// An object that scans for, discovers, connects to, and manages peripherals.
abstract class CentralManager extends BluetoothManager {
/// A Boolean value that indicates whether the central is currently scanning.
Stream<bool> get scanning;
/// The central manager discovered a peripheral while scanning for devices.
Stream<Discovery> get discovered;
/// The central manager disconnected from a peripheral.
Stream<ConnectionLostException> get connectionLost;
/// Establishes a local connection to a peripheral.
Future connect(Peripheral peripheral);
/// Cancels an active or pending local connection to a peripheral.
Future disconnect(Peripheral peripheral);
/// Scans for peripherals that are advertising services.
Future startDiscovery({List<UUID>? services});
/// Asks the central manager to stop scanning for peripherals.
Future stopDiscovery();
factory CentralManager() => _CentralManager();
}
class _CentralManager extends _BluetoothManager implements CentralManager {
@override
Future connect(Peripheral peripheral) {
// TODO: implement connect
throw UnimplementedError();
}
@override
// TODO: implement connectionLost
Stream<ConnectionLostException> get connectionLost =>
throw UnimplementedError();
@override
Future disconnect(Peripheral peripheral) {
// TODO: implement disconnect
throw UnimplementedError();
}
@override
// TODO: implement discovered
Stream<Discovery> get discovered => throw UnimplementedError();
@override
// TODO: implement scanning
Stream<bool> get scanning => throw UnimplementedError();
@override
Future startDiscovery({List<UUID>? services}) => method.invokeMethod(
message.MessageCategory.CENTRAL_MANAGER_START_DISCOVERY.name,
services?.map((e) => e.value).toList());
@override
Future stopDiscovery() => method.invokeMethod(
message.MessageCategory.CENTRAL_MANAGER_STOP_DISCOVERY.name);
}
/// The possible states of a bluetooth manager.
enum BluetoothManagerState {
/// The managers state is unknown.
unknown,
/// A state that indicates the connection with the system service was momentarily lost.
resetting,
/// A state that indicates this device doesnt support the bluetooth low energy central or client role.
unsupported,
/// A state that indicates the application isnt authorized to use the bluetooth low energy role.
unauthorized,
/// A state that indicates bluetooth is currently powered off.
poweredOff,
/// A state that indicates bluetooth is currently powered on and available to use.
poweredOn,
}
/// The current authorization state of a bluetooth manager.
enum BluetoothManagerAuthorization {
/// A state that indicates the user has yet to authorize bluetooth for this app.
notDetermined,
/// A state that indicates this app isnt authorized to use Bluetooth.
restricted,
/// A state that indicates the user explicitly denied bluetooth access for this app.
denied,
/// A state that indicates the user has authorized bluetooth at any time.
allowedAlways,
}
extension on message.BluetoothManagerState {
BluetoothManagerState get model => BluetoothManagerState.values[value];
}

52
lib/src/central.dart Normal file
View File

@ -0,0 +1,52 @@
part of bluetooth_low_energy;
final Central central = _Central();
/// An object that scans for, discovers, connects to, and manages peripherals.
abstract class Central extends Bluetooth {
/// The central discovered a peripheral while scanning for devices.
Stream<Discovery> get discovered;
/// Start discover peripherals that are advertising services.
Future startDiscovery({List<UUID>? services});
/// Stop discover peripherals.
Future stopDiscovery();
/// Establishes a local connection to a peripheral.
Future<GATT> connect(MAC address);
}
class _Central extends _Bluetooth implements Central {
@override
Stream<Discovery> get discovered => stream
.map((event) => proto.Message.fromBuffer(event))
.where((message) =>
message.category == proto.MessageCategory.CENTRAL_DISCOVERED)
.map((message) => message.discovery.conversion);
@override
Future startDiscovery({List<UUID>? services}) {
final name = proto.MessageCategory.CENTRAL_START_DISCOVERY.name;
final arguments = proto.StartDiscoveryArguments(
services: services?.map((uuid) => uuid.name),
).writeToBuffer();
return method.invokeMethod(name, arguments);
}
@override
Future stopDiscovery() {
final name = proto.MessageCategory.CENTRAL_STOP_DISCOVERY.name;
return method.invokeMethod(name);
}
@override
Future<GATT> connect(MAC address) {
final name = proto.MessageCategory.CENTRAL_CONNECT.name;
final arguments =
proto.ConnectArguments(address: address.name).writeToBuffer();
return method
.invokeMethod<List<int>>(name, arguments)
.then((value) => proto.GATT.fromBuffer(value!).convert(address));
}
}

View File

@ -1,7 +1,24 @@
import 'bluetooth.dart'; part of bluetooth_low_energy;
/// TO BE DONE.
abstract class Discovery { abstract class Discovery {
Peripheral get peripheral; /// TO BE DONE.
MAC get address;
/// TO BE DONE.
int get rssi; int get rssi;
/// TO BE DONE.
Map<int, List<int>> get advertisements; Map<int, List<int>> get advertisements;
} }
class _Discovery implements Discovery {
@override
final MAC address;
@override
final int rssi;
@override
final Map<int, List<int>> advertisements;
_Discovery(this.address, this.rssi, this.advertisements);
}

View File

@ -1,9 +0,0 @@
import 'bluetooth.dart';
abstract class Exception {
String get message;
}
abstract class ConnectionLostException extends Exception {
Peripheral get peripheral;
}

149
lib/src/extension.dart Normal file
View File

@ -0,0 +1,149 @@
part of bluetooth_low_energy;
extension on String {
String get nameOfMAC {
final upper = toUpperCase();
final exp = RegExp(
r'^[0-9A-F]{2}(:[0-9A-F]{2}){5}$',
multiLine: true,
caseSensitive: true,
);
if (exp.hasMatch(upper)) {
return upper;
}
throw ArgumentError.value(this);
}
List<int> get valueOfMAC {
final from = RegExp(r':');
final encoded = replaceAll(from, '');
return hex.decode(encoded);
}
String get nameOfUUID {
final upper = toUpperCase();
final exp0 = RegExp(
r'[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$',
multiLine: true,
caseSensitive: true,
);
if (exp0.hasMatch(upper)) {
return upper;
}
final exp1 = RegExp(
r'^[0-9A-F]{4}$',
multiLine: true,
caseSensitive: true,
);
if (exp1.hasMatch(upper)) {
return '0000$upper-0000-1000-8000-00805F9B34FB';
}
throw ArgumentError.value(this);
}
List<int> get valueOfUUID {
final from = RegExp(r'-');
final encoded = replaceAll(from, '');
return hex.decode(encoded);
}
MAC get conversionOfMAC => MAC(this);
UUID get conversionOfUUID => UUID(this);
}
extension on proto.Discovery {
Discovery get conversion {
final convertedAdvertisements = <int, List<int>>{};
var start = 0;
while (start < advertisements.length) {
final length = advertisements[start++];
if (length == 0) {
break;
}
final end = start + length;
final key = advertisements[start++];
final value = advertisements.sublist(start, end);
start = end;
convertedAdvertisements[key] = value;
}
return _Discovery(address.conversionOfMAC, rssi, convertedAdvertisements);
}
}
extension on proto.GATT {
GATT convert(MAC address) {
final convertedServices = {
for (var service in services)
service.uuid.conversionOfUUID: service.convert(address)
};
return _GATT(address, id, mtu, convertedServices);
}
}
extension on proto.GattService {
GattService convert(MAC address) {
final convertedUUID = uuid.conversionOfUUID;
final convertedCharacteristics = {
for (var characteristic in characteristics)
characteristic.uuid.conversionOfUUID:
characteristic.convert(address, convertedUUID)
};
return _GattService(
address,
id,
convertedUUID,
convertedCharacteristics,
);
}
}
extension on proto.GattCharacteristic {
GattCharacteristic convert(MAC address, UUID serviceUUID) {
final convertedUUID = uuid.conversionOfUUID;
final convertedDescriptors = {
for (var descriptor in descriptors)
descriptor.uuid.conversionOfUUID:
descriptor.convert(address, serviceUUID, convertedUUID)
};
return _GattCharacteristic(
address,
serviceUUID,
id,
convertedUUID,
convertedDescriptors,
canRead,
canWrite,
canWriteWithoutResponse,
canNotify,
);
}
}
extension on proto.GattDescriptor {
GattDescriptor convert(
MAC address, UUID serviceUUID, UUID characteristicUUID) {
final convertedUUID = uuid.conversionOfUUID;
return _GattDescriptor(
address,
serviceUUID,
characteristicUUID,
id,
convertedUUID,
);
}
}
/// TO BE DONE.
extension DiscoveryX on Discovery {
/// TO BE DONE.
String? get name {
if (advertisements.containsKey(0x08)) {
return utf8.decode(advertisements[0x08]!);
} else if (advertisements.containsKey(0x09)) {
return utf8.decode(advertisements[0x09]!);
} else {
return null;
}
}
}

44
lib/src/gatt.dart Normal file
View File

@ -0,0 +1,44 @@
part of bluetooth_low_energy;
/// TO BE DONE.
abstract class GATT {
/// TO BE DONE.
int get mtu;
/// TO BE DONE.
Stream<int> get connectionLost;
/// TO BE DONE.
Map<UUID, GattService> get services;
/// TO BE DONE.
Future disconnect();
}
class _GATT implements GATT {
_GATT(this.address, this.id, this.mtu, this.services);
final MAC address;
final int id;
@override
final int mtu;
@override
final Map<UUID, GattService> services;
@override
Stream<int> get connectionLost => stream
.map((event) => proto.Message.fromBuffer(event))
.where((event) =>
event.category == proto.MessageCategory.GATT_CONNECTION_LOST &&
event.connectionLost.id == id)
.map((event) => event.connectionLost.errorCode);
@override
Future disconnect() {
final name = proto.MessageCategory.GATT_DISCONNECT.name;
final arguments =
proto.GattDisconnectArguments(address: address.name, id: id)
.writeToBuffer();
return method.invokeMethod(name, arguments);
}
}

View File

@ -0,0 +1,114 @@
part of bluetooth_low_energy;
/// TO BE DONE.
abstract class GattCharacteristic {
/// TO BE DONE.
UUID get uuid;
/// TO BE DONE.
Map<UUID, GattDescriptor> get descriptors;
/// TO BE DONE.
bool get canRead;
/// TO BE DONE.
bool get canWrite;
/// TO BE DONE.
bool get canWriteWithoutResponse;
/// TO BE DONE.
bool get canNotify;
/// TO BE DONE.
Stream<List<int>> get valueChanged;
/// TO BE DONE.
Future<List<int>> read();
/// TO BE DONE.
Future write(List<int> value, {bool withoutResponse = false});
/// TO BE DONE.
Future notify(bool state);
}
class _GattCharacteristic implements GattCharacteristic {
_GattCharacteristic(
this.address,
this.serviceUUID,
this.id,
this.uuid,
this.descriptors,
this.canRead,
this.canWrite,
this.canWriteWithoutResponse,
this.canNotify,
);
final MAC address;
final UUID serviceUUID;
final int id;
@override
final UUID uuid;
@override
final Map<UUID, GattDescriptor> descriptors;
@override
final bool canRead;
@override
final bool canWrite;
@override
final bool canWriteWithoutResponse;
@override
final bool canNotify;
@override
Stream<List<int>> get valueChanged => stream
.map((event) => proto.Message.fromBuffer(event))
.where((message) =>
message.category ==
proto.MessageCategory.GATT_CHARACTERISTIC_NOTIFY &&
message.characteristicValue.id == id)
.map((message) => message.characteristicValue.value);
@override
Future<List<int>> read() {
final name = proto.MessageCategory.GATT_CHARACTERISTIC_READ.name;
final arguments = proto.GattCharacteristicReadArguments(
address: address.name,
serviceUuid: serviceUUID.name,
uuid: uuid.name,
id: id,
).writeToBuffer();
return method
.invokeListMethod<int>(name, arguments)
.then((value) => value!);
}
@override
Future write(List<int> value, {bool withoutResponse = false}) {
final name = proto.MessageCategory.GATT_CHARACTERISTIC_WRITE.name;
final arguments = proto.GattCharacteristicWriteArguments(
address: address.name,
serviceUuid: serviceUUID.name,
uuid: uuid.name,
id: id,
value: value,
withoutResponse: withoutResponse,
).writeToBuffer();
return method.invokeMethod(name, arguments);
}
@override
Future notify(bool state) {
final name = proto.MessageCategory.GATT_CHARACTERISTIC_NOTIFY.name;
final arguments = proto.GattCharacteristicNotifyArguments(
address: address.name,
serviceUuid: serviceUUID.name,
uuid: uuid.name,
id: id,
state: state,
).writeToBuffer();
return method.invokeMethod(name, arguments);
}
}

View File

@ -0,0 +1,59 @@
part of bluetooth_low_energy;
/// TO BE DONE.
abstract class GattDescriptor {
/// TO BE DONE.
UUID get uuid;
/// TO BE DONE.
Future<List<int>> read();
/// TO BE DONE.
Future write(List<int> value);
}
class _GattDescriptor implements GattDescriptor {
_GattDescriptor(
this.address,
this.serviceUUID,
this.characteristicUUID,
this.id,
this.uuid,
);
final MAC address;
final UUID serviceUUID;
final UUID characteristicUUID;
final int id;
@override
final UUID uuid;
@override
Future<List<int>> read() {
final name = proto.MessageCategory.GATT_DESCRIPTOR_READ.name;
final arguments = proto.GattDescriptorReadArguments(
address: address.name,
serviceUuid: serviceUUID.name,
characteristicUuid: characteristicUUID.name,
uuid: uuid.name,
id: id,
).writeToBuffer();
return method
.invokeListMethod<int>(name, arguments)
.then((value) => value!);
}
@override
Future write(List<int> value) {
final name = proto.MessageCategory.GATT_DESCRIPTOR_WRITE.name;
final arguments = proto.GattDescriptorWriteArguments(
address: address.name,
serviceUuid: serviceUUID.name,
characteristicUuid: characteristicUUID.name,
uuid: uuid.name,
id: id,
value: value,
).writeToBuffer();
return method.invokeMethod(name, arguments);
}
}

View File

@ -0,0 +1,21 @@
part of bluetooth_low_energy;
/// TO BE DONE.
abstract class GattService {
/// TO BE DONE.
UUID get uuid;
/// TO BE DONE.
Map<UUID, GattCharacteristic> get characteristics;
}
class _GattService implements GattService {
_GattService(this.address, this.id, this.uuid, this.characteristics);
final MAC address;
final int id;
@override
final UUID uuid;
@override
final Map<UUID, GattCharacteristic> characteristics;
}

View File

@ -1,3 +1,34 @@
part of bluetooth_low_energy;
/// TO BE DONE.
abstract class MAC { abstract class MAC {
/// TO BE DONE.
List<int> get value; List<int> get value;
/// TO BE DONE.
String get name;
/// TO BE DONE.
factory MAC(String str) => _MAC(str);
}
class _MAC implements MAC {
@override
final String name;
@override
final List<int> value;
@override
final int hashCode;
_MAC(String str) : this.name(str.nameOfMAC);
_MAC.name(String name) : this.nameValue(name, name.valueOfMAC);
_MAC.nameValue(this.name, this.value) : hashCode = equality.hash(value);
@override
String toString() => name;
@override
bool operator ==(other) => other is MAC && other.hashCode == hashCode;
} }

File diff suppressed because it is too large Load Diff

View File

@ -10,16 +10,34 @@ import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb; import 'package:protobuf/protobuf.dart' as $pb;
class MessageCategory extends $pb.ProtobufEnum { class MessageCategory extends $pb.ProtobufEnum {
static const MessageCategory BLUETOOTH_MANAGER_STATE = MessageCategory._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BLUETOOTH_MANAGER_STATE'); static const MessageCategory BLUETOOTH_AVAILABLE = MessageCategory._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BLUETOOTH_AVAILABLE');
static const MessageCategory CENTRAL_MANAGER_START_DISCOVERY = MessageCategory._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CENTRAL_MANAGER_START_DISCOVERY'); static const MessageCategory BLUETOOTH_STATE = MessageCategory._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BLUETOOTH_STATE');
static const MessageCategory CENTRAL_MANAGER_STOP_DISCOVERY = MessageCategory._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CENTRAL_MANAGER_STOP_DISCOVERY'); static const MessageCategory CENTRAL_START_DISCOVERY = MessageCategory._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CENTRAL_START_DISCOVERY');
static const MessageCategory CENTRAL_MANAGER_DISCOVERED = MessageCategory._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CENTRAL_MANAGER_DISCOVERED'); static const MessageCategory CENTRAL_STOP_DISCOVERY = MessageCategory._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CENTRAL_STOP_DISCOVERY');
static const MessageCategory CENTRAL_DISCOVERED = MessageCategory._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CENTRAL_DISCOVERED');
static const MessageCategory CENTRAL_CONNECT = MessageCategory._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CENTRAL_CONNECT');
static const MessageCategory GATT_DISCONNECT = MessageCategory._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GATT_DISCONNECT');
static const MessageCategory GATT_CONNECTION_LOST = MessageCategory._(7, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GATT_CONNECTION_LOST');
static const MessageCategory GATT_CHARACTERISTIC_READ = MessageCategory._(8, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GATT_CHARACTERISTIC_READ');
static const MessageCategory GATT_CHARACTERISTIC_WRITE = MessageCategory._(9, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GATT_CHARACTERISTIC_WRITE');
static const MessageCategory GATT_CHARACTERISTIC_NOTIFY = MessageCategory._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GATT_CHARACTERISTIC_NOTIFY');
static const MessageCategory GATT_DESCRIPTOR_READ = MessageCategory._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GATT_DESCRIPTOR_READ');
static const MessageCategory GATT_DESCRIPTOR_WRITE = MessageCategory._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GATT_DESCRIPTOR_WRITE');
static const $core.List<MessageCategory> values = <MessageCategory> [ static const $core.List<MessageCategory> values = <MessageCategory> [
BLUETOOTH_MANAGER_STATE, BLUETOOTH_AVAILABLE,
CENTRAL_MANAGER_START_DISCOVERY, BLUETOOTH_STATE,
CENTRAL_MANAGER_STOP_DISCOVERY, CENTRAL_START_DISCOVERY,
CENTRAL_MANAGER_DISCOVERED, CENTRAL_STOP_DISCOVERY,
CENTRAL_DISCOVERED,
CENTRAL_CONNECT,
GATT_DISCONNECT,
GATT_CONNECTION_LOST,
GATT_CHARACTERISTIC_READ,
GATT_CHARACTERISTIC_WRITE,
GATT_CHARACTERISTIC_NOTIFY,
GATT_DESCRIPTOR_READ,
GATT_DESCRIPTOR_WRITE,
]; ];
static final $core.Map<$core.int, MessageCategory> _byValue = $pb.ProtobufEnum.initByValue(values); static final $core.Map<$core.int, MessageCategory> _byValue = $pb.ProtobufEnum.initByValue(values);
@ -28,26 +46,3 @@ class MessageCategory extends $pb.ProtobufEnum {
const MessageCategory._($core.int v, $core.String n) : super(v, n); const MessageCategory._($core.int v, $core.String n) : super(v, n);
} }
class BluetoothManagerState extends $pb.ProtobufEnum {
static const BluetoothManagerState UNKNOWN = BluetoothManagerState._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UNKNOWN');
static const BluetoothManagerState RESETTING = BluetoothManagerState._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RESETTING');
static const BluetoothManagerState UNSUPPORTED = BluetoothManagerState._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UNSUPPORTED');
static const BluetoothManagerState UNAUTHORIZED = BluetoothManagerState._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UNAUTHORIZED');
static const BluetoothManagerState POWERED_OFF = BluetoothManagerState._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'POWERED_OFF');
static const BluetoothManagerState POWERED_ON = BluetoothManagerState._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'POWERED_ON');
static const $core.List<BluetoothManagerState> values = <BluetoothManagerState> [
UNKNOWN,
RESETTING,
UNSUPPORTED,
UNAUTHORIZED,
POWERED_OFF,
POWERED_ON,
];
static final $core.Map<$core.int, BluetoothManagerState> _byValue = $pb.ProtobufEnum.initByValue(values);
static BluetoothManagerState? valueOf($core.int value) => _byValue[value];
const BluetoothManagerState._($core.int v, $core.String n) : super(v, n);
}

View File

@ -12,36 +12,34 @@ import 'dart:typed_data' as $typed_data;
const MessageCategory$json = const { const MessageCategory$json = const {
'1': 'MessageCategory', '1': 'MessageCategory',
'2': const [ '2': const [
const {'1': 'BLUETOOTH_MANAGER_STATE', '2': 0}, const {'1': 'BLUETOOTH_AVAILABLE', '2': 0},
const {'1': 'CENTRAL_MANAGER_START_DISCOVERY', '2': 1}, const {'1': 'BLUETOOTH_STATE', '2': 1},
const {'1': 'CENTRAL_MANAGER_STOP_DISCOVERY', '2': 2}, const {'1': 'CENTRAL_START_DISCOVERY', '2': 2},
const {'1': 'CENTRAL_MANAGER_DISCOVERED', '2': 3}, const {'1': 'CENTRAL_STOP_DISCOVERY', '2': 3},
const {'1': 'CENTRAL_DISCOVERED', '2': 4},
const {'1': 'CENTRAL_CONNECT', '2': 5},
const {'1': 'GATT_DISCONNECT', '2': 6},
const {'1': 'GATT_CONNECTION_LOST', '2': 7},
const {'1': 'GATT_CHARACTERISTIC_READ', '2': 8},
const {'1': 'GATT_CHARACTERISTIC_WRITE', '2': 9},
const {'1': 'GATT_CHARACTERISTIC_NOTIFY', '2': 10},
const {'1': 'GATT_DESCRIPTOR_READ', '2': 11},
const {'1': 'GATT_DESCRIPTOR_WRITE', '2': 12},
], ],
}; };
/// Descriptor for `MessageCategory`. Decode as a `google.protobuf.EnumDescriptorProto`. /// Descriptor for `MessageCategory`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List messageCategoryDescriptor = $convert.base64Decode('Cg9NZXNzYWdlQ2F0ZWdvcnkSGwoXQkxVRVRPT1RIX01BTkFHRVJfU1RBVEUQABIjCh9DRU5UUkFMX01BTkFHRVJfU1RBUlRfRElTQ09WRVJZEAESIgoeQ0VOVFJBTF9NQU5BR0VSX1NUT1BfRElTQ09WRVJZEAISHgoaQ0VOVFJBTF9NQU5BR0VSX0RJU0NPVkVSRUQQAw=='); final $typed_data.Uint8List messageCategoryDescriptor = $convert.base64Decode('Cg9NZXNzYWdlQ2F0ZWdvcnkSFwoTQkxVRVRPT1RIX0FWQUlMQUJMRRAAEhMKD0JMVUVUT09USF9TVEFURRABEhsKF0NFTlRSQUxfU1RBUlRfRElTQ09WRVJZEAISGgoWQ0VOVFJBTF9TVE9QX0RJU0NPVkVSWRADEhYKEkNFTlRSQUxfRElTQ09WRVJFRBAEEhMKD0NFTlRSQUxfQ09OTkVDVBAFEhMKD0dBVFRfRElTQ09OTkVDVBAGEhgKFEdBVFRfQ09OTkVDVElPTl9MT1NUEAcSHAoYR0FUVF9DSEFSQUNURVJJU1RJQ19SRUFEEAgSHQoZR0FUVF9DSEFSQUNURVJJU1RJQ19XUklURRAJEh4KGkdBVFRfQ0hBUkFDVEVSSVNUSUNfTk9USUZZEAoSGAoUR0FUVF9ERVNDUklQVE9SX1JFQUQQCxIZChVHQVRUX0RFU0NSSVBUT1JfV1JJVEUQDA==');
@$core.Deprecated('Use bluetoothManagerStateDescriptor instead')
const BluetoothManagerState$json = const {
'1': 'BluetoothManagerState',
'2': const [
const {'1': 'UNKNOWN', '2': 0},
const {'1': 'RESETTING', '2': 1},
const {'1': 'UNSUPPORTED', '2': 2},
const {'1': 'UNAUTHORIZED', '2': 3},
const {'1': 'POWERED_OFF', '2': 4},
const {'1': 'POWERED_ON', '2': 5},
],
};
/// Descriptor for `BluetoothManagerState`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List bluetoothManagerStateDescriptor = $convert.base64Decode('ChVCbHVldG9vdGhNYW5hZ2VyU3RhdGUSCwoHVU5LTk9XThAAEg0KCVJFU0VUVElORxABEg8KC1VOU1VQUE9SVEVEEAISEAoMVU5BVVRIT1JJWkVEEAMSDwoLUE9XRVJFRF9PRkYQBBIOCgpQT1dFUkVEX09OEAU=');
@$core.Deprecated('Use messageDescriptor instead') @$core.Deprecated('Use messageDescriptor instead')
const Message$json = const { const Message$json = const {
'1': 'Message', '1': 'Message',
'2': const [ '2': const [
const {'1': 'category', '3': 1, '4': 1, '5': 14, '6': '.MessageCategory', '10': 'category'}, const {'1': 'category', '3': 1, '4': 1, '5': 14, '6': '.dev.yanshouwang.bluetooth_low_energy.MessageCategory', '10': 'category'},
const {'1': 'state', '3': 2, '4': 1, '5': 14, '6': '.BluetoothManagerState', '9': 0, '10': 'state'}, const {'1': 'state', '3': 2, '4': 1, '5': 8, '9': 0, '10': 'state'},
const {'1': 'discovery', '3': 3, '4': 1, '5': 11, '6': '.dev.yanshouwang.bluetooth_low_energy.Discovery', '9': 0, '10': 'discovery'},
const {'1': 'scanning', '3': 4, '4': 1, '5': 8, '9': 0, '10': 'scanning'},
const {'1': 'connectionLost', '3': 5, '4': 1, '5': 11, '6': '.dev.yanshouwang.bluetooth_low_energy.ConnectionLost', '9': 0, '10': 'connectionLost'},
const {'1': 'characteristicValue', '3': 6, '4': 1, '5': 11, '6': '.dev.yanshouwang.bluetooth_low_energy.GattCharacteristicValue', '9': 0, '10': 'characteristicValue'},
], ],
'8': const [ '8': const [
const {'1': 'value'}, const {'1': 'value'},
@ -49,37 +47,191 @@ const Message$json = const {
}; };
/// Descriptor for `Message`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `Message`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List messageDescriptor = $convert.base64Decode('CgdNZXNzYWdlEiwKCGNhdGVnb3J5GAEgASgOMhAuTWVzc2FnZUNhdGVnb3J5UghjYXRlZ29yeRIuCgVzdGF0ZRgCIAEoDjIWLkJsdWV0b290aE1hbmFnZXJTdGF0ZUgAUgVzdGF0ZUIHCgV2YWx1ZQ=='); final $typed_data.Uint8List messageDescriptor = $convert.base64Decode('CgdNZXNzYWdlElEKCGNhdGVnb3J5GAEgASgOMjUuZGV2LnlhbnNob3V3YW5nLmJsdWV0b290aF9sb3dfZW5lcmd5Lk1lc3NhZ2VDYXRlZ29yeVIIY2F0ZWdvcnkSFgoFc3RhdGUYAiABKAhIAFIFc3RhdGUSTwoJZGlzY292ZXJ5GAMgASgLMi8uZGV2LnlhbnNob3V3YW5nLmJsdWV0b290aF9sb3dfZW5lcmd5LkRpc2NvdmVyeUgAUglkaXNjb3ZlcnkSHAoIc2Nhbm5pbmcYBCABKAhIAFIIc2Nhbm5pbmcSXgoOY29ubmVjdGlvbkxvc3QYBSABKAsyNC5kZXYueWFuc2hvdXdhbmcuYmx1ZXRvb3RoX2xvd19lbmVyZ3kuQ29ubmVjdGlvbkxvc3RIAFIOY29ubmVjdGlvbkxvc3QScQoTY2hhcmFjdGVyaXN0aWNWYWx1ZRgGIAEoCzI9LmRldi55YW5zaG91d2FuZy5ibHVldG9vdGhfbG93X2VuZXJneS5HYXR0Q2hhcmFjdGVyaXN0aWNWYWx1ZUgAUhNjaGFyYWN0ZXJpc3RpY1ZhbHVlQgcKBXZhbHVl');
@$core.Deprecated('Use startDiscoveryArgumentsDescriptor instead')
const StartDiscoveryArguments$json = const {
'1': 'StartDiscoveryArguments',
'2': const [
const {'1': 'services', '3': 1, '4': 3, '5': 9, '10': 'services'},
],
};
/// Descriptor for `StartDiscoveryArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List startDiscoveryArgumentsDescriptor = $convert.base64Decode('ChdTdGFydERpc2NvdmVyeUFyZ3VtZW50cxIaCghzZXJ2aWNlcxgBIAMoCVIIc2VydmljZXM=');
@$core.Deprecated('Use discoveryDescriptor instead') @$core.Deprecated('Use discoveryDescriptor instead')
const Discovery$json = const { const Discovery$json = const {
'1': 'Discovery', '1': 'Discovery',
'2': const [ '2': const [
const {'1': 'peripheral', '3': 1, '4': 1, '5': 11, '6': '.Peripheral', '10': 'peripheral'}, const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
const {'1': 'rssi', '3': 2, '4': 1, '5': 17, '10': 'rssi'}, const {'1': 'rssi', '3': 2, '4': 1, '5': 17, '10': 'rssi'},
const {'1': 'advertisements', '3': 3, '4': 3, '5': 11, '6': '.Discovery.AdvertisementsEntry', '10': 'advertisements'}, const {'1': 'advertisements', '3': 3, '4': 1, '5': 12, '10': 'advertisements'},
], ],
'3': const [Discovery_AdvertisementsEntry$json],
};
@$core.Deprecated('Use discoveryDescriptor instead')
const Discovery_AdvertisementsEntry$json = const {
'1': 'AdvertisementsEntry',
'2': const [
const {'1': 'key', '3': 1, '4': 1, '5': 13, '10': 'key'},
const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'},
],
'7': const {'7': true},
}; };
/// Descriptor for `Discovery`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `Discovery`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List discoveryDescriptor = $convert.base64Decode('CglEaXNjb3ZlcnkSKwoKcGVyaXBoZXJhbBgBIAEoCzILLlBlcmlwaGVyYWxSCnBlcmlwaGVyYWwSEgoEcnNzaRgCIAEoEVIEcnNzaRJGCg5hZHZlcnRpc2VtZW50cxgDIAMoCzIeLkRpc2NvdmVyeS5BZHZlcnRpc2VtZW50c0VudHJ5Ug5hZHZlcnRpc2VtZW50cxpBChNBZHZlcnRpc2VtZW50c0VudHJ5EhAKA2tleRgBIAEoDVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAE='); final $typed_data.Uint8List discoveryDescriptor = $convert.base64Decode('CglEaXNjb3ZlcnkSGAoHYWRkcmVzcxgBIAEoCVIHYWRkcmVzcxISCgRyc3NpGAIgASgRUgRyc3NpEiYKDmFkdmVydGlzZW1lbnRzGAMgASgMUg5hZHZlcnRpc2VtZW50cw==');
@$core.Deprecated('Use peripheralDescriptor instead') @$core.Deprecated('Use connectArgumentsDescriptor instead')
const Peripheral$json = const { const ConnectArguments$json = const {
'1': 'Peripheral', '1': 'ConnectArguments',
'2': const [ '2': const [
const {'1': 'address', '3': 1, '4': 1, '5': 12, '10': 'address'}, const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
], ],
}; };
/// Descriptor for `Peripheral`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `ConnectArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List peripheralDescriptor = $convert.base64Decode('CgpQZXJpcGhlcmFsEhgKB2FkZHJlc3MYASABKAxSB2FkZHJlc3M='); final $typed_data.Uint8List connectArgumentsDescriptor = $convert.base64Decode('ChBDb25uZWN0QXJndW1lbnRzEhgKB2FkZHJlc3MYASABKAlSB2FkZHJlc3M=');
@$core.Deprecated('Use gATTDescriptor instead')
const GATT$json = const {
'1': 'GATT',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 5, '10': 'id'},
const {'1': 'mtu', '3': 2, '4': 1, '5': 5, '10': 'mtu'},
const {'1': 'services', '3': 3, '4': 3, '5': 11, '6': '.dev.yanshouwang.bluetooth_low_energy.GattService', '10': 'services'},
],
};
/// Descriptor for `GATT`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gATTDescriptor = $convert.base64Decode('CgRHQVRUEg4KAmlkGAEgASgFUgJpZBIQCgNtdHUYAiABKAVSA210dRJNCghzZXJ2aWNlcxgDIAMoCzIxLmRldi55YW5zaG91d2FuZy5ibHVldG9vdGhfbG93X2VuZXJneS5HYXR0U2VydmljZVIIc2VydmljZXM=');
@$core.Deprecated('Use gattDisconnectArgumentsDescriptor instead')
const GattDisconnectArguments$json = const {
'1': 'GattDisconnectArguments',
'2': const [
const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
const {'1': 'id', '3': 2, '4': 1, '5': 5, '10': 'id'},
],
};
/// Descriptor for `GattDisconnectArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattDisconnectArgumentsDescriptor = $convert.base64Decode('ChdHYXR0RGlzY29ubmVjdEFyZ3VtZW50cxIYCgdhZGRyZXNzGAEgASgJUgdhZGRyZXNzEg4KAmlkGAIgASgFUgJpZA==');
@$core.Deprecated('Use gattServiceDescriptor instead')
const GattService$json = const {
'1': 'GattService',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 5, '10': 'id'},
const {'1': 'uuid', '3': 2, '4': 1, '5': 9, '10': 'uuid'},
const {'1': 'characteristics', '3': 3, '4': 3, '5': 11, '6': '.dev.yanshouwang.bluetooth_low_energy.GattCharacteristic', '10': 'characteristics'},
],
};
/// Descriptor for `GattService`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattServiceDescriptor = $convert.base64Decode('CgtHYXR0U2VydmljZRIOCgJpZBgBIAEoBVICaWQSEgoEdXVpZBgCIAEoCVIEdXVpZBJiCg9jaGFyYWN0ZXJpc3RpY3MYAyADKAsyOC5kZXYueWFuc2hvdXdhbmcuYmx1ZXRvb3RoX2xvd19lbmVyZ3kuR2F0dENoYXJhY3RlcmlzdGljUg9jaGFyYWN0ZXJpc3RpY3M=');
@$core.Deprecated('Use gattCharacteristicDescriptor instead')
const GattCharacteristic$json = const {
'1': 'GattCharacteristic',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 5, '10': 'id'},
const {'1': 'uuid', '3': 2, '4': 1, '5': 9, '10': 'uuid'},
const {'1': 'descriptors', '3': 3, '4': 3, '5': 11, '6': '.dev.yanshouwang.bluetooth_low_energy.GattDescriptor', '10': 'descriptors'},
const {'1': 'canRead', '3': 4, '4': 1, '5': 8, '10': 'canRead'},
const {'1': 'canWrite', '3': 5, '4': 1, '5': 8, '10': 'canWrite'},
const {'1': 'canWriteWithoutResponse', '3': 6, '4': 1, '5': 8, '10': 'canWriteWithoutResponse'},
const {'1': 'canNotify', '3': 7, '4': 1, '5': 8, '10': 'canNotify'},
],
};
/// Descriptor for `GattCharacteristic`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattCharacteristicDescriptor = $convert.base64Decode('ChJHYXR0Q2hhcmFjdGVyaXN0aWMSDgoCaWQYASABKAVSAmlkEhIKBHV1aWQYAiABKAlSBHV1aWQSVgoLZGVzY3JpcHRvcnMYAyADKAsyNC5kZXYueWFuc2hvdXdhbmcuYmx1ZXRvb3RoX2xvd19lbmVyZ3kuR2F0dERlc2NyaXB0b3JSC2Rlc2NyaXB0b3JzEhgKB2NhblJlYWQYBCABKAhSB2NhblJlYWQSGgoIY2FuV3JpdGUYBSABKAhSCGNhbldyaXRlEjgKF2NhbldyaXRlV2l0aG91dFJlc3BvbnNlGAYgASgIUhdjYW5Xcml0ZVdpdGhvdXRSZXNwb25zZRIcCgljYW5Ob3RpZnkYByABKAhSCWNhbk5vdGlmeQ==');
@$core.Deprecated('Use gattDescriptorDescriptor instead')
const GattDescriptor$json = const {
'1': 'GattDescriptor',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 5, '10': 'id'},
const {'1': 'uuid', '3': 2, '4': 1, '5': 9, '10': 'uuid'},
],
};
/// Descriptor for `GattDescriptor`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattDescriptorDescriptor = $convert.base64Decode('Cg5HYXR0RGVzY3JpcHRvchIOCgJpZBgBIAEoBVICaWQSEgoEdXVpZBgCIAEoCVIEdXVpZA==');
@$core.Deprecated('Use connectionLostDescriptor instead')
const ConnectionLost$json = const {
'1': 'ConnectionLost',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 5, '10': 'id'},
const {'1': 'error_code', '3': 2, '4': 1, '5': 5, '10': 'errorCode'},
],
};
/// Descriptor for `ConnectionLost`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List connectionLostDescriptor = $convert.base64Decode('Cg5Db25uZWN0aW9uTG9zdBIOCgJpZBgBIAEoBVICaWQSHQoKZXJyb3JfY29kZRgCIAEoBVIJZXJyb3JDb2Rl');
@$core.Deprecated('Use gattCharacteristicReadArgumentsDescriptor instead')
const GattCharacteristicReadArguments$json = const {
'1': 'GattCharacteristicReadArguments',
'2': const [
const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
const {'1': 'service_uuid', '3': 2, '4': 1, '5': 9, '10': 'serviceUuid'},
const {'1': 'uuid', '3': 3, '4': 1, '5': 9, '10': 'uuid'},
const {'1': 'id', '3': 4, '4': 1, '5': 5, '10': 'id'},
],
};
/// Descriptor for `GattCharacteristicReadArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattCharacteristicReadArgumentsDescriptor = $convert.base64Decode('Ch9HYXR0Q2hhcmFjdGVyaXN0aWNSZWFkQXJndW1lbnRzEhgKB2FkZHJlc3MYASABKAlSB2FkZHJlc3MSIQoMc2VydmljZV91dWlkGAIgASgJUgtzZXJ2aWNlVXVpZBISCgR1dWlkGAMgASgJUgR1dWlkEg4KAmlkGAQgASgFUgJpZA==');
@$core.Deprecated('Use gattCharacteristicWriteArgumentsDescriptor instead')
const GattCharacteristicWriteArguments$json = const {
'1': 'GattCharacteristicWriteArguments',
'2': const [
const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
const {'1': 'service_uuid', '3': 2, '4': 1, '5': 9, '10': 'serviceUuid'},
const {'1': 'uuid', '3': 3, '4': 1, '5': 9, '10': 'uuid'},
const {'1': 'id', '3': 4, '4': 1, '5': 5, '10': 'id'},
const {'1': 'value', '3': 5, '4': 1, '5': 12, '10': 'value'},
const {'1': 'withoutResponse', '3': 6, '4': 1, '5': 8, '10': 'withoutResponse'},
],
};
/// Descriptor for `GattCharacteristicWriteArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattCharacteristicWriteArgumentsDescriptor = $convert.base64Decode('CiBHYXR0Q2hhcmFjdGVyaXN0aWNXcml0ZUFyZ3VtZW50cxIYCgdhZGRyZXNzGAEgASgJUgdhZGRyZXNzEiEKDHNlcnZpY2VfdXVpZBgCIAEoCVILc2VydmljZVV1aWQSEgoEdXVpZBgDIAEoCVIEdXVpZBIOCgJpZBgEIAEoBVICaWQSFAoFdmFsdWUYBSABKAxSBXZhbHVlEigKD3dpdGhvdXRSZXNwb25zZRgGIAEoCFIPd2l0aG91dFJlc3BvbnNl');
@$core.Deprecated('Use gattCharacteristicNotifyArgumentsDescriptor instead')
const GattCharacteristicNotifyArguments$json = const {
'1': 'GattCharacteristicNotifyArguments',
'2': const [
const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
const {'1': 'service_uuid', '3': 2, '4': 1, '5': 9, '10': 'serviceUuid'},
const {'1': 'uuid', '3': 3, '4': 1, '5': 9, '10': 'uuid'},
const {'1': 'id', '3': 4, '4': 1, '5': 5, '10': 'id'},
const {'1': 'state', '3': 5, '4': 1, '5': 8, '10': 'state'},
],
};
/// Descriptor for `GattCharacteristicNotifyArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattCharacteristicNotifyArgumentsDescriptor = $convert.base64Decode('CiFHYXR0Q2hhcmFjdGVyaXN0aWNOb3RpZnlBcmd1bWVudHMSGAoHYWRkcmVzcxgBIAEoCVIHYWRkcmVzcxIhCgxzZXJ2aWNlX3V1aWQYAiABKAlSC3NlcnZpY2VVdWlkEhIKBHV1aWQYAyABKAlSBHV1aWQSDgoCaWQYBCABKAVSAmlkEhQKBXN0YXRlGAUgASgIUgVzdGF0ZQ==');
@$core.Deprecated('Use gattCharacteristicValueDescriptor instead')
const GattCharacteristicValue$json = const {
'1': 'GattCharacteristicValue',
'2': const [
const {'1': 'id', '3': 3, '4': 1, '5': 5, '10': 'id'},
const {'1': 'value', '3': 4, '4': 1, '5': 12, '10': 'value'},
],
};
/// Descriptor for `GattCharacteristicValue`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattCharacteristicValueDescriptor = $convert.base64Decode('ChdHYXR0Q2hhcmFjdGVyaXN0aWNWYWx1ZRIOCgJpZBgDIAEoBVICaWQSFAoFdmFsdWUYBCABKAxSBXZhbHVl');
@$core.Deprecated('Use gattDescriptorReadArgumentsDescriptor instead')
const GattDescriptorReadArguments$json = const {
'1': 'GattDescriptorReadArguments',
'2': const [
const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
const {'1': 'service_uuid', '3': 2, '4': 1, '5': 9, '10': 'serviceUuid'},
const {'1': 'characteristic_uuid', '3': 3, '4': 1, '5': 9, '10': 'characteristicUuid'},
const {'1': 'uuid', '3': 4, '4': 1, '5': 9, '10': 'uuid'},
const {'1': 'id', '3': 5, '4': 1, '5': 5, '10': 'id'},
],
};
/// Descriptor for `GattDescriptorReadArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattDescriptorReadArgumentsDescriptor = $convert.base64Decode('ChtHYXR0RGVzY3JpcHRvclJlYWRBcmd1bWVudHMSGAoHYWRkcmVzcxgBIAEoCVIHYWRkcmVzcxIhCgxzZXJ2aWNlX3V1aWQYAiABKAlSC3NlcnZpY2VVdWlkEi8KE2NoYXJhY3RlcmlzdGljX3V1aWQYAyABKAlSEmNoYXJhY3RlcmlzdGljVXVpZBISCgR1dWlkGAQgASgJUgR1dWlkEg4KAmlkGAUgASgFUgJpZA==');
@$core.Deprecated('Use gattDescriptorWriteArgumentsDescriptor instead')
const GattDescriptorWriteArguments$json = const {
'1': 'GattDescriptorWriteArguments',
'2': const [
const {'1': 'address', '3': 1, '4': 1, '5': 9, '10': 'address'},
const {'1': 'service_uuid', '3': 2, '4': 1, '5': 9, '10': 'serviceUuid'},
const {'1': 'characteristic_uuid', '3': 3, '4': 1, '5': 9, '10': 'characteristicUuid'},
const {'1': 'uuid', '3': 4, '4': 1, '5': 9, '10': 'uuid'},
const {'1': 'id', '3': 5, '4': 1, '5': 5, '10': 'id'},
const {'1': 'value', '3': 6, '4': 1, '5': 12, '10': 'value'},
],
};
/// Descriptor for `GattDescriptorWriteArguments`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gattDescriptorWriteArgumentsDescriptor = $convert.base64Decode('ChxHYXR0RGVzY3JpcHRvcldyaXRlQXJndW1lbnRzEhgKB2FkZHJlc3MYASABKAlSB2FkZHJlc3MSIQoMc2VydmljZV91dWlkGAIgASgJUgtzZXJ2aWNlVXVpZBIvChNjaGFyYWN0ZXJpc3RpY191dWlkGAMgASgJUhJjaGFyYWN0ZXJpc3RpY1V1aWQSEgoEdXVpZBgEIAEoCVIEdXVpZBIOCgJpZBgFIAEoBVICaWQSFAoFdmFsdWUYBiABKAxSBXZhbHVl');

View File

@ -1,6 +1,9 @@
import 'package:collection/collection.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
const namespace = 'yanshouwang.dev/bluetooth_low_energy'; const namespace = 'yanshouwang.dev/bluetooth_low_energy';
const method = MethodChannel('$namespace/method'); const method = MethodChannel('$namespace/method');
const event = EventChannel('$namespace/event'); const event = EventChannel('$namespace/event');
const equality = ListEquality<int>();
final stream = event.receiveBroadcastStream(); final stream = event.receiveBroadcastStream();

View File

@ -1,52 +1,34 @@
import 'package:collection/collection.dart'; part of bluetooth_low_energy;
import 'package:convert/convert.dart';
/// A universally unique identifier, as defined by bluetooth standards. /// A universally unique identifier, as defined by bluetooth standards.
abstract class UUID { abstract class UUID {
/// TO BE DONE.
List<int> get value; List<int> get value;
factory UUID(String s) => _UUID(s); /// TO BE DONE.
String get name;
/// TO BE DONE.
factory UUID(String str) => _UUID(str);
} }
class _UUID implements UUID { class _UUID implements UUID {
final String full;
@override @override
final List<int> value; final List<int> value;
@override @override
final String name;
@override
final int hashCode; final int hashCode;
_UUID(String s) : this.full(s.full); _UUID(String str) : this.name(str.nameOfUUID);
_UUID.full(String full) : this.create(full, full.value); _UUID.name(String name) : this.nameValue(name, name.valueOfUUID);
_UUID.create(this.full, this.value) _UUID.nameValue(this.name, this.value) : hashCode = equality.hash(value);
: hashCode = ListEquality<int>().hash(value);
@override @override
String toString() => full; String toString() => name;
@override @override
bool operator ==(other) => other is UUID && other.hashCode == hashCode; bool operator ==(other) => other is UUID && other.hashCode == hashCode;
} }
extension on String {
String get full {
var source =
r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$';
var regex = RegExp(source, multiLine: true, caseSensitive: false);
if (regex.hasMatch(this)) return this;
source = r'^[0-9a-f]{4}$';
regex = RegExp(source, multiLine: true, caseSensitive: false);
if (regex.hasMatch(this)) {
return '0x0000${this}-0000-1000-8000-00805F9B34FB';
}
throw ArgumentError.value(this);
}
List<int> get value {
final source = r'-';
final regex = RegExp(source);
final encoded = splitMapJoin(regex);
return hex.decode(encoded);
}
}

View File

@ -1,34 +1,126 @@
syntax = "proto3"; syntax = "proto3";
package dev.yanshouwang.bluetooth_low_energy;
message Message { message Message {
MessageCategory category = 1; MessageCategory category = 1;
oneof value { oneof value {
BluetoothManagerState state = 2; bool state = 2;
Discovery discovery = 3;
bool scanning = 4;
ConnectionLost connectionLost = 5;
GattCharacteristicValue characteristicValue = 6;
} }
} }
message Discovery { message StartDiscoveryArguments {
Peripheral peripheral = 1; repeated string services = 1;
sint32 rssi = 2;
map<uint32, bytes> advertisements = 3;
} }
message Peripheral { message Discovery {
bytes address = 1; string address = 1;
sint32 rssi = 2;
bytes advertisements = 3;
}
message ConnectArguments {
string address = 1;
}
message GATT {
int32 id = 1;
int32 mtu = 2;
repeated GattService services = 3;
}
message GattDisconnectArguments{
string address = 1;
int32 id = 2;
}
message GattService {
int32 id = 1;
string uuid = 2;
repeated GattCharacteristic characteristics = 3;
}
message GattCharacteristic {
int32 id = 1;
string uuid = 2;
repeated GattDescriptor descriptors = 3;
bool canRead = 4;
bool canWrite = 5;
bool canWriteWithoutResponse = 6;
bool canNotify = 7;
}
message GattDescriptor {
int32 id = 1;
string uuid = 2;
}
message ConnectionLost {
int32 id = 1;
int32 error_code = 2;
}
message GattCharacteristicReadArguments {
string address = 1;
string service_uuid = 2;
string uuid = 3;
int32 id = 4;
}
message GattCharacteristicWriteArguments {
string address = 1;
string service_uuid = 2;
string uuid = 3;
int32 id = 4;
bytes value = 5;
bool withoutResponse = 6;
}
message GattCharacteristicNotifyArguments{
string address = 1;
string service_uuid = 2;
string uuid = 3;
int32 id = 4;
bool state = 5;
}
message GattCharacteristicValue {
int32 id = 3;
bytes value = 4;
}
message GattDescriptorReadArguments {
string address = 1;
string service_uuid = 2;
string characteristic_uuid = 3;
string uuid = 4;
int32 id = 5;
}
message GattDescriptorWriteArguments {
string address = 1;
string service_uuid = 2;
string characteristic_uuid = 3;
string uuid = 4;
int32 id = 5;
bytes value = 6;
} }
enum MessageCategory { enum MessageCategory {
BLUETOOTH_MANAGER_STATE = 0; BLUETOOTH_AVAILABLE =0;
CENTRAL_MANAGER_START_DISCOVERY = 1; BLUETOOTH_STATE = 1;
CENTRAL_MANAGER_STOP_DISCOVERY = 2; CENTRAL_START_DISCOVERY = 2;
CENTRAL_MANAGER_DISCOVERED = 3; CENTRAL_STOP_DISCOVERY = 3;
} CENTRAL_DISCOVERED = 4;
CENTRAL_CONNECT = 5;
enum BluetoothManagerState { GATT_DISCONNECT = 6;
UNKNOWN = 0; GATT_CONNECTION_LOST = 7;
RESETTING = 1; GATT_CHARACTERISTIC_READ = 8;
UNSUPPORTED = 2; GATT_CHARACTERISTIC_WRITE = 9;
UNAUTHORIZED = 3; GATT_CHARACTERISTIC_NOTIFY = 10;
POWERED_OFF = 4; GATT_DESCRIPTOR_READ = 11;
POWERED_ON = 5; GATT_DESCRIPTOR_WRITE = 12;
} }

View File

@ -1,7 +1,8 @@
name: bluetooth_low_energy name: bluetooth_low_energy
description: A new flutter plugin project. description: A bluetooth low energy plugin for flutter, which can be used for a central role.
version: 0.0.1 version: 0.0.1
homepage: homepage: https://github.com/yanshouwang/camerax
publish_to: https://pub.dev
environment: environment:
sdk: ">=2.12.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"

View File

@ -1,27 +1,76 @@
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart'; import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
import 'package:bluetooth_low_energy/src/channel.dart' as channel; import 'package:bluetooth_low_energy/src/util.dart' as util;
import 'package:bluetooth_low_energy/src/message.pb.dart' as message; import 'package:bluetooth_low_energy/src/message.pb.dart' as proto;
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
final method = MethodChannel('${channel.method.name}'); final method = MethodChannel('${util.method.name}');
final event = MethodChannel('${channel.event.name}'); final event = MethodChannel('${util.event.name}');
final calls = <MethodCall>[]; final calls = <MethodCall>[];
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
setUp(() { setUp(() {
calls.clear(); calls.clear();
method.setMockMethodCallHandler((call) async { method.setMockMethodCallHandler((call) async {
calls.add(call); calls.add(call);
if (call.method == message.MessageCategory.BLUETOOTH_MANAGER_STATE.name) { if (call.method == proto.MessageCategory.BLUETOOTH_AVAILABLE.name) {
return message.BluetoothManagerState.POWERED_OFF.value; return true;
} else if (call.method == proto.MessageCategory.BLUETOOTH_STATE.name) {
return true;
} else if (call.method == } else if (call.method ==
message.MessageCategory.CENTRAL_MANAGER_START_DISCOVERY.name) { proto.MessageCategory.CENTRAL_START_DISCOVERY.name) {
return null; return null;
} else if (call.method == } else if (call.method ==
message.MessageCategory.CENTRAL_MANAGER_STOP_DISCOVERY.name) { proto.MessageCategory.CENTRAL_STOP_DISCOVERY.name) {
return null;
} else if (call.method == proto.MessageCategory.CENTRAL_CONNECT.name) {
final descriptors = [
proto.GattDescriptor(
id: 4000,
uuid: '2900',
),
];
final characteristics = [
proto.GattCharacteristic(
id: 3000,
uuid: '2A00',
descriptors: descriptors,
canRead: true,
canWrite: true,
canWriteWithoutResponse: true,
canNotify: true,
),
];
final services = [
proto.GattService(
id: 2000,
uuid: '1800',
characteristics: characteristics,
),
];
final gatt = proto.GATT(
id: 1000,
mtu: 23,
services: services,
);
return gatt.writeToBuffer();
} else if (call.method == proto.MessageCategory.GATT_DISCONNECT.name) {
return null;
} else if (call.method ==
proto.MessageCategory.GATT_CHARACTERISTIC_READ.name) {
return [0x01, 0x02, 0x03, 0x04, 0x05];
} else if (call.method ==
proto.MessageCategory.GATT_CHARACTERISTIC_WRITE.name) {
return null;
} else if (call.method ==
proto.MessageCategory.GATT_CHARACTERISTIC_NOTIFY.name) {
return null;
} else if (call.method ==
proto.MessageCategory.GATT_DESCRIPTOR_READ.name) {
return [0x05, 0x04, 0x03, 0x02, 0x01];
} else if (call.method ==
proto.MessageCategory.GATT_DESCRIPTOR_WRITE.name) {
return null; return null;
} else { } else {
throw UnimplementedError(); throw UnimplementedError();
@ -30,74 +79,393 @@ void main() {
event.setMockMethodCallHandler((call) async { event.setMockMethodCallHandler((call) async {
switch (call.method) { switch (call.method) {
case 'listen': case 'listen':
final state = message.Message( final state = proto.Message(
category: message.MessageCategory.BLUETOOTH_MANAGER_STATE, category: proto.MessageCategory.BLUETOOTH_STATE,
state: message.BluetoothManagerState.POWERED_ON) state: false,
.writeToBuffer(); ).writeToBuffer();
await ServicesBinding.instance!.defaultBinaryMessenger await ServicesBinding.instance!.defaultBinaryMessenger
.handlePlatformMessage(channel.event.name, .handlePlatformMessage(
channel.event.codec.encodeSuccessEnvelope(state), (data) {}); event.name,
event.codec.encodeSuccessEnvelope(state),
(data) {},
);
final discovery = proto.Message(
category: proto.MessageCategory.CENTRAL_DISCOVERED,
discovery: proto.Discovery(
address: 'aa:bb:cc:dd:ee:ff',
rssi: -50,
advertisements: [0x07, 0xff, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa],
),
).writeToBuffer();
await ServicesBinding.instance!.defaultBinaryMessenger
.handlePlatformMessage(
event.name,
event.codec.encodeSuccessEnvelope(discovery),
(data) {},
);
final connectionLost = proto.Message(
category: proto.MessageCategory.GATT_CONNECTION_LOST,
connectionLost: proto.ConnectionLost(
id: 1000,
errorCode: 19,
),
).writeToBuffer();
await ServicesBinding.instance!.defaultBinaryMessenger
.handlePlatformMessage(
event.name,
event.codec.encodeSuccessEnvelope(connectionLost),
(data) {},
);
final characteristicValue = proto.Message(
category: proto.MessageCategory.GATT_CHARACTERISTIC_NOTIFY,
characteristicValue: proto.GattCharacteristicValue(
id: 3000,
value: [0x0A, 0x0B, 0x0C, 0x0D, 0x0E],
),
).writeToBuffer();
await ServicesBinding.instance!.defaultBinaryMessenger
.handlePlatformMessage(
event.name,
event.codec.encodeSuccessEnvelope(characteristicValue),
(data) {},
);
break; break;
case 'cancel': case 'cancel':
default:
return null; return null;
default:
throw UnimplementedError();
} }
}); });
}); });
tearDown(() { tearDown(() {
method.setMockMethodCallHandler(null); method.setMockMethodCallHandler(null);
event.setMockMethodCallHandler(null); event.setMockMethodCallHandler(null);
}); });
test('${message.MessageCategory.BLUETOOTH_MANAGER_STATE}', () async { test(
final actual = await CentralManager().state; '${proto.MessageCategory.BLUETOOTH_AVAILABLE}',
final matcher = BluetoothManagerState.poweredOff; () async {
expect(actual, matcher); final actual = await central.available;
expect(actual, true);
expect( expect(
calls, calls,
[ [
isMethodCall( isMethodCall(
message.MessageCategory.BLUETOOTH_MANAGER_STATE.name, proto.MessageCategory.BLUETOOTH_AVAILABLE.name,
arguments: null, arguments: null,
), ),
], ],
); );
}); },
);
test('${message.MessageCategory.BLUETOOTH_MANAGER_STATE} EVENT', () async { test(
final actual = await CentralManager().stateChanged.first; '${proto.MessageCategory.BLUETOOTH_STATE}',
final matcher = BluetoothManagerState.poweredOn; () async {
expect(actual, matcher); final actual = await central.state;
}); expect(actual, true);
test('${message.MessageCategory.CENTRAL_MANAGER_START_DISCOVERY}', () async {
final services = [
UUID(""),
UUID(""),
];
await CentralManager().startDiscovery(services: services);
expect( expect(
calls, calls,
[ [
isMethodCall( isMethodCall(
message.MessageCategory.CENTRAL_MANAGER_START_DISCOVERY.name, proto.MessageCategory.BLUETOOTH_STATE.name,
arguments: null, arguments: null,
), ),
], ],
); );
}); },
);
test('${message.MessageCategory.CENTRAL_MANAGER_STOP_DISCOVERY}', () async { test(
await CentralManager().stopDiscovery(); '${proto.MessageCategory.BLUETOOTH_STATE} EVENT',
() async {
final actual = await central.stateChanged.first;
expect(actual, false);
},
);
test(
'${proto.MessageCategory.CENTRAL_START_DISCOVERY}',
() async {
final services = [UUID('1800'), UUID('1801')];
await central.startDiscovery(services: services);
expect( expect(
calls, calls,
[ [
isMethodCall( isMethodCall(
message.MessageCategory.CENTRAL_MANAGER_STOP_DISCOVERY.name, proto.MessageCategory.CENTRAL_START_DISCOVERY.name,
arguments: proto.StartDiscoveryArguments(
services: services.map((uuid) => uuid.name),
).writeToBuffer(),
),
],
);
},
);
test(
'${proto.MessageCategory.CENTRAL_STOP_DISCOVERY}',
() async {
await central.stopDiscovery();
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_STOP_DISCOVERY.name,
arguments: null, arguments: null,
), ),
], ],
); );
}); },
);
test(
'${proto.MessageCategory.CENTRAL_DISCOVERED} EVENT',
() async {
final actual = await central.discovered.first;
final address = MAC('aa:bb:cc:dd:ee:ff');
expect(actual.address, address);
final rssi = -50;
expect(actual.rssi, rssi);
final advertisements = {
0xff: [0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa],
};
expect(actual.advertisements, advertisements);
},
);
test(
'${proto.MessageCategory.CENTRAL_CONNECT}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final actual = await central.connect(address);
expect(actual.mtu, 23);
expect(actual.services.length, 1);
final service = actual.services.values.first;
expect(service.uuid, UUID('1800'));
expect(service.characteristics.length, 1);
final characteristic = service.characteristics.values.first;
expect(characteristic.uuid, UUID('2A00'));
expect(characteristic.descriptors.length, 1);
expect(characteristic.canRead, true);
expect(characteristic.canWrite, true);
expect(characteristic.canWriteWithoutResponse, true);
expect(characteristic.canNotify, true);
final descriptor = characteristic.descriptors.values.first;
expect(descriptor.uuid, UUID('2900'));
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_CONNECT.name,
arguments: proto.ConnectArguments(
address: address.name,
).writeToBuffer(),
),
],
);
},
);
test(
'${proto.MessageCategory.GATT_DISCONNECT}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
await gatt.disconnect();
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_CONNECT.name,
arguments: proto.ConnectArguments(
address: address.name,
).writeToBuffer(),
),
isMethodCall(
proto.MessageCategory.GATT_DISCONNECT.name,
arguments: proto.GattDisconnectArguments(
address: address.name,
id: 1000,
).writeToBuffer(),
),
],
);
},
);
test(
'${proto.MessageCategory.GATT_CONNECTION_LOST}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
final actual = await gatt.connectionLost.first;
expect(actual, 19);
},
);
test(
'${proto.MessageCategory.GATT_CHARACTERISTIC_READ}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
final service = gatt.services.values.first;
final characteristic = service.characteristics.values.first;
final actual = await characteristic.read();
expect(actual, [0x01, 0x02, 0x03, 0x04, 0x05]);
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_CONNECT.name,
arguments: proto.ConnectArguments(
address: address.name,
).writeToBuffer(),
),
isMethodCall(
proto.MessageCategory.GATT_CHARACTERISTIC_READ.name,
arguments: proto.GattCharacteristicReadArguments(
address: address.name,
serviceUuid: service.uuid.name,
uuid: characteristic.uuid.name,
id: 3000,
).writeToBuffer(),
),
],
);
},
);
test(
'${proto.MessageCategory.GATT_CHARACTERISTIC_WRITE}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
final service = gatt.services.values.first;
final characteristic = service.characteristics.values.first;
final value = [0x01, 0x02, 0x03, 0x04, 0x05];
await characteristic.write(value, withoutResponse: true);
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_CONNECT.name,
arguments: proto.ConnectArguments(
address: address.name,
).writeToBuffer(),
),
isMethodCall(
proto.MessageCategory.GATT_CHARACTERISTIC_WRITE.name,
arguments: proto.GattCharacteristicWriteArguments(
address: address.name,
serviceUuid: service.uuid.name,
uuid: characteristic.uuid.name,
id: 3000,
value: value,
withoutResponse: true,
).writeToBuffer(),
),
],
);
},
);
test(
'${proto.MessageCategory.GATT_CHARACTERISTIC_NOTIFY}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
final service = gatt.services.values.first;
final characteristic = service.characteristics.values.first;
await characteristic.notify(true);
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_CONNECT.name,
arguments: proto.ConnectArguments(
address: address.name,
).writeToBuffer(),
),
isMethodCall(
proto.MessageCategory.GATT_CHARACTERISTIC_NOTIFY.name,
arguments: proto.GattCharacteristicNotifyArguments(
address: address.name,
serviceUuid: service.uuid.name,
uuid: characteristic.uuid.name,
id: 3000,
state: true,
).writeToBuffer(),
),
],
);
},
);
test(
'${proto.MessageCategory.GATT_CHARACTERISTIC_NOTIFY} EVENT',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
final service = gatt.services.values.first;
final characteristic = service.characteristics.values.first;
final value = await characteristic.valueChanged.first;
expect(value, [0x0A, 0x0B, 0x0C, 0x0D, 0x0E]);
},
);
test(
'${proto.MessageCategory.GATT_DESCRIPTOR_READ}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
final service = gatt.services.values.first;
final characteristic = service.characteristics.values.first;
final descriptor = characteristic.descriptors.values.first;
final actual = await descriptor.read();
expect(actual, [0x05, 0x04, 0x03, 0x02, 0x01]);
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_CONNECT.name,
arguments: proto.ConnectArguments(
address: address.name,
).writeToBuffer(),
),
isMethodCall(
proto.MessageCategory.GATT_DESCRIPTOR_READ.name,
arguments: proto.GattDescriptorReadArguments(
address: address.name,
serviceUuid: service.uuid.name,
characteristicUuid: characteristic.uuid.name,
uuid: descriptor.uuid.name,
id: 4000,
).writeToBuffer(),
),
],
);
},
);
test(
'${proto.MessageCategory.GATT_DESCRIPTOR_WRITE}',
() async {
final address = MAC('aa:bb:cc:dd:ee:ff');
final gatt = await central.connect(address);
final service = gatt.services.values.first;
final characteristic = service.characteristics.values.first;
final descriptor = characteristic.descriptors.values.first;
final value = [0x01, 0x02, 0x03, 0x04, 0x05];
await descriptor.write(value);
expect(
calls,
[
isMethodCall(
proto.MessageCategory.CENTRAL_CONNECT.name,
arguments: proto.ConnectArguments(
address: address.name,
).writeToBuffer(),
),
isMethodCall(
proto.MessageCategory.GATT_DESCRIPTOR_WRITE.name,
arguments: proto.GattDescriptorWriteArguments(
address: address.name,
serviceUuid: service.uuid.name,
characteristicUuid: characteristic.uuid.name,
uuid: descriptor.uuid.name,
id: 4000,
value: value,
).writeToBuffer(),
),
],
);
},
);
} }