From d1726b52fa088125c8fb67745562bf6089cff424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=E5=89=91=E4=BE=A0=E5=AE=A2?= Date: Thu, 17 Aug 2023 17:49:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E9=A1=B9=E7=9B=AE=20?= =?UTF-8?q?2.0.0=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 重构项目 * feat: 添加 bluez_central_manager * feat: 联合插件 * feat: 拆分项目 * feat: 实现 linux 部分接口 * feat: 重新创建项目 * feat: 定义接口 * feat: 实现接入插件 * feat: 清空接入插件示例代码 * feat: 开发 linux 插件 * feat: 调整接口 * 临时提交 * feat: 实现 Android 接口 * fix: 修复 Android 问题 * fix: 移除多余文件 * feat: 重构项目 (#5) * fix: 移除多余的状态判断 * fix: 外围设备断开时检查是否存在未完成的操作 * feat: 尝试使用 win32 实现接口 * fix: 修复大小写问题 * feat: 实现 macOS 接口 * feat: 实现 macOS 接口 * fix:支持使用16位短字符串生成UUID * fix: 修复未清理已完成操作的问题 * fix: 规范命名 * 添加蓝牙使用描述 * fix: 更新 README.md --- LICENSE | 4 +- README.md | 42 +- analysis_options.yaml | 18 - .../bluetooth_low_energy/pigeon/Messages.java | 809 ------ .../proto/BluetoothState.java | 122 - .../bluetooth_low_energy/proto/Broadcast.java | 2198 ----------------- .../proto/BroadcastOrBuilder.java | 153 -- .../proto/GattCharacteristic.java | 1007 -------- .../proto/GattCharacteristicOrBuilder.java | 60 - .../proto/GattDescriptor.java | 747 ------ .../proto/GattDescriptorOrBuilder.java | 36 - .../proto/GattService.java | 747 ------ .../proto/GattServiceOrBuilder.java | 36 - .../bluetooth_low_energy/proto/Messages.java | 136 - .../proto/Peripheral.java | 747 ------ .../proto/PeripheralOrBuilder.java | 36 - .../proto/ServiceData.java | 677 ----- .../proto/ServiceDataOrBuilder.java | 30 - .../bluetooth_low_energy/proto/UUID.java | 559 ----- .../proto/UUIDOrBuilder.java | 21 - .../BluetoothLowEnergyException.kt | 3 - .../BluetoothLowEnergyPlugin.kt | 185 -- .../MyBluetoothGattCallback.kt | 179 -- .../MyBroadcastReceiver.kt | 20 - .../MyCentralManagerHostApi.kt | 64 - .../MyGattCharacteristicHostApi.kt | 111 - .../MyGattDescriptorHostApi.kt | 42 - .../MyGattServiceHostApi.kt | 47 - .../MyPeripheralHostApi.kt | 63 - .../MyRequestPermissionsResultListener.kt | 21 - .../bluetooth_low_energy/MyScanCallback.kt | 92 - .../bluetooth_low_energy/proto/BroadcastKt.kt | 395 --- .../proto/GattCharacteristicKt.kt | 141 -- .../proto/GattDescriptorKt.kt | 73 - .../proto/GattServiceKt.kt | 73 - .../proto/PeripheralKt.kt | 73 - .../proto/ServiceDataKt.kt | 73 - .../bluetooth_low_energy/proto/UUIDKt.kt | 46 - .gitignore => bluetooth_low_energy/.gitignore | 0 bluetooth_low_energy/.metadata | 42 + .../CHANGELOG.md | 7 +- bluetooth_low_energy/LICENSE | 21 + bluetooth_low_energy/README.md | 47 + bluetooth_low_energy/analysis_options.yaml | 4 + .../example}/.gitignore | 3 - .../example}/README.md | 0 .../example}/analysis_options.yaml | 0 .../example}/android/.gitignore | 0 .../example}/android/app/build.gradle | 7 +- .../android/app/src/debug/AndroidManifest.xml | 3 +- .../android/app/src/main/AndroidManifest.xml | 5 +- .../MainActivity.kt | 0 .../res/drawable-v21/launch_background.xml | 0 .../main/res/drawable/launch_background.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../app/src/main/res/values-night/styles.xml | 0 .../app/src/main/res/values/styles.xml | 0 .../app/src/profile/AndroidManifest.xml | 3 +- .../example}/android/build.gradle | 6 +- .../example}/android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../example}/android/settings.gradle | 0 .../plugin_integration_test.dart | 23 + .../example}/ios/.gitignore | 0 .../ios/Flutter/AppFrameworkInfo.plist | 0 .../example}/ios/Flutter/Debug.xcconfig | 0 .../example}/ios/Flutter/Release.xcconfig | 0 .../example}/ios/Podfile | 3 + bluetooth_low_energy/example/ios/Podfile.lock | 28 + .../ios/Runner.xcodeproj/project.pbxproj | 242 +- .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 11 + .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../example}/ios/Runner/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../Icon-App-1024x1024@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 295 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 406 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 450 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 282 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 462 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 704 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 406 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 586 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 862 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 1674 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 762 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 1226 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 1418 bytes .../LaunchImage.imageset/Contents.json | 0 .../LaunchImage.imageset/LaunchImage.png | Bin .../LaunchImage.imageset/LaunchImage@2x.png | Bin .../LaunchImage.imageset/LaunchImage@3x.png | Bin .../LaunchImage.imageset/README.md | 0 .../Runner/Base.lproj/LaunchScreen.storyboard | 0 .../ios/Runner/Base.lproj/Main.storyboard | 0 .../example}/ios/Runner/Info.plist | 4 +- .../ios/Runner/Runner-Bridging-Header.h | 0 .../example/ios/RunnerTests/RunnerTests.swift | 26 + bluetooth_low_energy/example/lib/main.dart | 652 +++++ bluetooth_low_energy/example/linux/.gitignore | 1 + .../example/linux/CMakeLists.txt | 141 ++ .../example/linux/flutter/CMakeLists.txt | 88 + .../flutter/generated_plugin_registrant.cc | 11 + .../flutter/generated_plugin_registrant.h | 15 + .../linux/flutter/generated_plugins.cmake | 23 + bluetooth_low_energy/example/linux/main.cc | 6 + .../example/linux/my_application.cc | 104 + .../example/linux/my_application.h | 18 + bluetooth_low_energy/example/macos/.gitignore | 7 + .../macos/Flutter/Flutter-Debug.xcconfig | 2 + .../macos/Flutter/Flutter-Release.xcconfig | 2 + .../Flutter/GeneratedPluginRegistrant.swift | 12 + bluetooth_low_energy/example/macos/Podfile | 43 + .../example/macos/Podfile.lock | 22 + .../macos/Runner.xcodeproj/project.pbxproj | 793 ++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 98 + .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../example/macos/Runner/AppDelegate.swift | 9 + .../AppIcon.appiconset/Contents.json | 68 + .../AppIcon.appiconset/app_icon_1024.png | Bin 0 -> 102994 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 0 -> 5680 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 0 -> 520 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 0 -> 14142 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 0 -> 1066 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 0 -> 36406 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 0 -> 2218 bytes .../macos/Runner/Base.lproj/MainMenu.xib | 343 +++ .../macos/Runner/Configs/AppInfo.xcconfig | 14 + .../macos/Runner/Configs/Debug.xcconfig | 2 + .../macos/Runner/Configs/Release.xcconfig | 2 + .../macos/Runner/Configs/Warnings.xcconfig | 13 + .../macos/Runner/DebugProfile.entitlements | 14 + .../example/macos/Runner/Info.plist | 34 + .../macos/Runner/MainFlutterWindow.swift | 15 + .../example/macos/Runner/Release.entitlements | 8 + .../macos/RunnerTests/RunnerTests.swift | 27 + bluetooth_low_energy/example/pubspec.lock | 389 +++ .../example}/pubspec.yaml | 8 +- .../example}/test/widget_test.dart | 0 .../example/windows/.gitignore | 17 + .../example/windows/CMakeLists.txt | 104 + .../example/windows/flutter/CMakeLists.txt | 104 + .../flutter/generated_plugin_registrant.cc | 14 + .../flutter/generated_plugin_registrant.h | 15 + .../windows/flutter/generated_plugins.cmake | 24 + .../example/windows/runner/CMakeLists.txt | 40 + .../example/windows/runner/Runner.rc | 121 + .../example/windows/runner/flutter_window.cpp | 71 + .../example/windows/runner/flutter_window.h | 33 + .../example/windows/runner/main.cpp | 43 + .../example/windows/runner/resource.h | 16 + .../windows/runner/resources/app_icon.ico | Bin 0 -> 33772 bytes .../windows/runner/runner.exe.manifest | 20 + .../example/windows/runner/utils.cpp | 65 + .../example/windows/runner/utils.h | 19 + .../example/windows/runner/win32_window.cpp | 288 +++ .../example/windows/runner/win32_window.h | 102 + {ios => bluetooth_low_energy/ios}/.gitignore | 0 .../ios}/Assets/.gitkeep | 0 .../Classes/BluetoothLowEnergyPlugin.swift | 19 + .../ios}/bluetooth_low_energy.podspec | 3 +- .../lib/bluetooth_low_energy.dart | 1 + bluetooth_low_energy/linux/CMakeLists.txt | 94 + .../linux/bluetooth_low_energy_plugin.cc | 76 + .../bluetooth_low_energy_plugin_private.h | 10 + .../bluetooth_low_energy_plugin.h | 26 + .../test/bluetooth_low_energy_plugin_test.cc | 31 + .../Classes/BluetoothLowEnergyPlugin.swift | 19 + .../macos/bluetooth_low_energy.podspec | 23 + bluetooth_low_energy/pubspec.yaml | 43 + .../test/bluetooth_low_energy_test.dart | 1 + bluetooth_low_energy/windows/.gitignore | 17 + bluetooth_low_energy/windows/CMakeLists.txt | 96 + .../windows/bluetooth_low_energy_plugin.cpp | 59 + .../windows/bluetooth_low_energy_plugin.h | 31 + .../bluetooth_low_energy_plugin_c_api.cpp | 12 + .../bluetooth_low_energy_plugin_c_api.h | 23 + .../test/bluetooth_low_energy_plugin_test.cpp | 43 + bluetooth_low_energy_android/.gitignore | 30 + .../.metadata | 13 +- bluetooth_low_energy_android/CHANGELOG.md | 4 + bluetooth_low_energy_android/LICENSE | 21 + bluetooth_low_energy_android/README.md | 15 + .../analysis_options.yaml | 4 + .../android}/.gitignore | 0 .../android}/build.gradle | 28 +- .../android}/settings.gradle | 0 .../android}/src/main/AndroidManifest.xml | 12 +- .../BluetoothLowEnergyAndroid.kt | 38 + .../bluetooth_low_energy/MyApi.g.kt | 653 +++++ .../MyBluetoothGattCallback.kt | 57 + .../MyBroadcastReceiver.kt | 11 + .../MyCentralController.kt | 685 +++++ .../MyRequestPermissionResultListener.kt | 9 + .../bluetooth_low_energy/MyScanCallback.kt | 14 + .../BluetoothLowEnergyPluginTest.kt | 27 + .../lib/bluetooth_low_energy_android.dart | 9 + .../lib/src/my_api.g.dart | 736 ++++++ .../lib/src/my_central_controller.dart | 356 +++ .../lib/src/my_gatt_characteristic.dart | 42 + .../lib/src/my_gatt_descriptor.dart | 22 + .../lib/src/my_gatt_service.dart | 22 + .../lib/src/my_object.dart | 11 + .../lib/src/my_peripheral.dart | 17 + bluetooth_low_energy_android/my_api.dart | 144 ++ bluetooth_low_energy_android/pubspec.yaml | 29 + bluetooth_low_energy_ios/.gitignore | 30 + bluetooth_low_energy_ios/.metadata | 30 + bluetooth_low_energy_ios/CHANGELOG.md | 4 + bluetooth_low_energy_ios/LICENSE | 21 + bluetooth_low_energy_ios/README.md | 15 + .../analysis_options.yaml | 4 + bluetooth_low_energy_ios/ios/.gitignore | 38 + .../ios/Assets/.gitkeep | 0 .../ios/Classes/BluetoothLowEnergyiOS.swift | 10 + .../ios/Classes/MyApi.g.swift | 594 +++++ .../ios/Classes/MyCentralController.swift | 696 ++++++ .../Classes/MyCentralManagerDelegate.swift | 38 + .../ios/Classes/MyError.swift | 14 + .../ios/Classes/MyPeripheralDelegate.swift | 49 + .../ios/bluetooth_low_energy_ios.podspec | 23 + .../lib/bluetooth_low_energy_ios.dart | 9 + .../lib/src/my_api.g.dart | 736 ++++++ .../lib/src/my_central_controller.dart | 357 +++ .../lib/src/my_gatt_characteristic.dart | 42 + .../lib/src/my_gatt_descriptor.dart | 22 + .../lib/src/my_gatt_service.dart | 22 + .../lib/src/my_object.dart | 11 + .../lib/src/my_peripheral.dart | 17 + bluetooth_low_energy_ios/my_api.dart | 140 ++ bluetooth_low_energy_ios/pubspec.yaml | 27 + bluetooth_low_energy_linux/.gitignore | 30 + bluetooth_low_energy_linux/.metadata | 30 + bluetooth_low_energy_linux/CHANGELOG.md | 4 + bluetooth_low_energy_linux/LICENSE | 21 + bluetooth_low_energy_linux/README.md | 15 + .../analysis_options.yaml | 4 + .../lib/bluetooth_low_energy_linux.dart | 9 + .../lib/src/my_bluez.dart | 81 + .../lib/src/my_central_controller.dart | 426 ++++ .../lib/src/my_gatt_characteristic.dart | 17 + .../lib/src/my_gatt_descriptor.dart | 14 + .../lib/src/my_gatt_service.dart | 14 + .../lib/src/my_object.dart | 11 + .../lib/src/my_peripheral.dart | 14 + bluetooth_low_energy_linux/pubspec.yaml | 27 + bluetooth_low_energy_macos/.gitignore | 30 + bluetooth_low_energy_macos/.metadata | 30 + bluetooth_low_energy_macos/CHANGELOG.md | 4 + bluetooth_low_energy_macos/LICENSE | 21 + bluetooth_low_energy_macos/README.md | 15 + .../analysis_options.yaml | 4 + .../lib/bluetooth_low_energy_macos.dart | 9 + .../lib/src/my_api.g.dart | 736 ++++++ .../lib/src/my_central_controller.dart | 357 +++ .../lib/src/my_gatt_characteristic.dart | 42 + .../lib/src/my_gatt_descriptor.dart | 22 + .../lib/src/my_gatt_service.dart | 22 + .../lib/src/my_object.dart | 11 + .../lib/src/my_peripheral.dart | 17 + .../Classes/BluetoothLowEnergymacOS.swift | 10 + .../macos/Classes/MyApi.g.swift | 594 +++++ .../macos/Classes/MyCentralController.swift | 696 ++++++ .../Classes/MyCentralManagerDelegate.swift | 38 + .../macos/Classes/MyError.swift | 14 + .../macos/Classes/MyPeripheralDelegate.swift | 49 + .../macos/bluetooth_low_energy_macos.podspec | 23 + bluetooth_low_energy_macos/my_api.dart | 140 ++ bluetooth_low_energy_macos/pubspec.yaml | 27 + .../.gitignore | 30 + .../.metadata | 27 + .../CHANGELOG.md | 4 + .../LICENSE | 21 + .../README.md | 26 + .../analysis_options.yaml | 4 + ...uetooth_low_energy_platform_interface.dart | 12 + .../lib/src/advertisement.dart | 17 + .../lib/src/central_controller.dart | 74 + .../lib/src/central_state.dart | 7 + .../lib/src/errors.dart | 10 + .../lib/src/event_args.dart | 36 + .../lib/src/gatt_characteristic.dart | 12 + .../lib/src/gatt_characteristic_property.dart | 7 + .../src/gatt_characteristic_write_type.dart | 8 + .../lib/src/gatt_descriptor.dart | 9 + .../lib/src/gatt_service.dart | 9 + .../lib/src/peripheral.dart | 5 + .../lib/src/uuid.dart | 141 ++ .../pubspec.yaml | 18 + ...th_low_energy_platform_interface_test.dart | 1 + bluetooth_low_energy_windows/.gitignore | 30 + bluetooth_low_energy_windows/.metadata | 30 + bluetooth_low_energy_windows/CHANGELOG.md | 4 + bluetooth_low_energy_windows/LICENSE | 21 + bluetooth_low_energy_windows/README.md | 15 + .../analysis_options.yaml | 4 + .../lib/bluetooth_low_energy_windows.dart | 9 + .../lib/src/my_central_controller.dart | 120 + bluetooth_low_energy_windows/pubspec.yaml | 28 + .../windows/.gitignore | 17 + .../windows/CMakeLists.txt | 53 + .../bluetooth_low_energy_windows_plugin.cpp | 59 + .../bluetooth_low_energy_windows_plugin.h | 32 + ...etooth_low_energy_windows_plugin_c_api.cpp | 12 + ...luetooth_low_energy_windows_plugin_c_api.h | 23 + example/ios/Podfile.lock | 29 - .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes example/lib/main.dart | 698 ------ example/pubspec.lock | 294 --- ios/Classes/BluetoothLowEnergyPlugin.h | 4 - ios/Classes/BluetoothLowEnergyPlugin.m | 15 - ios/Classes/MyCentralManagerDelegate.swift | 112 - ios/Classes/MyCentralManagerHostApi.swift | 39 - ios/Classes/MyGattCharacteristicHostApi.swift | 49 - ios/Classes/MyGattDescriptorHostApi.swift | 32 - ios/Classes/MyGattServiceHostApi.swift | 23 - ios/Classes/MyPeripheralDelegate.swift | 211 -- ios/Classes/MyPeripheralHostApi.swift | 44 - .../SwiftBluetoothLowEnergyPlugin.swift | 112 - ios/Classes/pigeon/Messages.h | 94 - ios/Classes/pigeon/Messages.m | 760 ------ ios/Classes/proto/messages.pb.swift | 642 ----- lib/bluetooth_low_energy.dart | 8 - lib/src/api.dart | 137 - lib/src/bluetooth_state.dart | 5 - lib/src/broadcast.dart | 17 - lib/src/central_manager.dart | 17 - lib/src/gatt_characteristic.dart | 18 - lib/src/gatt_descriptor.dart | 10 - lib/src/gatt_service.dart | 8 - lib/src/impl.dart | 532 ---- lib/src/peripheral.dart | 13 - lib/src/pigeon.dart | 1 - lib/src/pigeon/messages.g.dart | 643 ----- lib/src/proto.dart | 3 - lib/src/proto/messages.pb.dart | 588 ----- lib/src/proto/messages.pbenum.dart | 28 - lib/src/proto/messages.pbjson.dart | 115 - lib/src/proto/messages.pbserver.dart | 9 - lib/src/uuid.dart | 9 - pigeon/messages.dart | 109 - proto/messages.proto | 57 - pubspec.yaml | 76 - scripts/run_pigeon.sh | 35 +- scripts/run_protoc.sh | 53 - test/pigeon/test_messages.g.dart | 382 --- 371 files changed, 15666 insertions(+), 15993 deletions(-) delete mode 100644 analysis_options.yaml delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/pigeon/Messages.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BluetoothState.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Broadcast.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastOrBuilder.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristic.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicOrBuilder.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptor.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorOrBuilder.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattService.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceOrBuilder.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Messages.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Peripheral.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralOrBuilder.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceData.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataOrBuilder.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUID.java delete mode 100644 android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUIDOrBuilder.java delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyException.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPlugin.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralManagerHostApi.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattCharacteristicHostApi.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattDescriptorHostApi.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattServiceHostApi.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyPeripheralHostApi.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionsResultListener.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastKt.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicKt.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorKt.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceKt.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralKt.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataKt.kt delete mode 100644 android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/UUIDKt.kt rename .gitignore => bluetooth_low_energy/.gitignore (100%) create mode 100644 bluetooth_low_energy/.metadata rename CHANGELOG.md => bluetooth_low_energy/CHANGELOG.md (85%) create mode 100644 bluetooth_low_energy/LICENSE create mode 100644 bluetooth_low_energy/README.md create mode 100644 bluetooth_low_energy/analysis_options.yaml rename {example => bluetooth_low_energy/example}/.gitignore (93%) rename {example => bluetooth_low_energy/example}/README.md (100%) rename {example => bluetooth_low_energy/example}/analysis_options.yaml (100%) rename {example => bluetooth_low_energy/example}/android/.gitignore (100%) rename {example => bluetooth_low_energy/example}/android/app/build.gradle (88%) rename {example => bluetooth_low_energy/example}/android/app/src/debug/AndroidManifest.xml (85%) rename {example => bluetooth_low_energy/example}/android/app/src/main/AndroidManifest.xml (95%) rename {example => bluetooth_low_energy/example}/android/app/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_example/MainActivity.kt (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/drawable-v21/launch_background.xml (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/drawable/launch_background.xml (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/values-night/styles.xml (100%) rename {example => bluetooth_low_energy/example}/android/app/src/main/res/values/styles.xml (100%) rename {example => bluetooth_low_energy/example}/android/app/src/profile/AndroidManifest.xml (85%) rename {example => bluetooth_low_energy/example}/android/build.gradle (79%) rename {example => bluetooth_low_energy/example}/android/gradle.properties (100%) rename {example => bluetooth_low_energy/example}/android/gradle/wrapper/gradle-wrapper.properties (80%) rename {example => bluetooth_low_energy/example}/android/settings.gradle (100%) create mode 100644 bluetooth_low_energy/example/integration_test/plugin_integration_test.dart rename {example => bluetooth_low_energy/example}/ios/.gitignore (100%) rename {example => bluetooth_low_energy/example}/ios/Flutter/AppFrameworkInfo.plist (100%) rename {example => bluetooth_low_energy/example}/ios/Flutter/Debug.xcconfig (100%) rename {example => bluetooth_low_energy/example}/ios/Flutter/Release.xcconfig (100%) rename {example => bluetooth_low_energy/example}/ios/Podfile (95%) create mode 100644 bluetooth_low_energy/example/ios/Podfile.lock rename {example => bluetooth_low_energy/example}/ios/Runner.xcodeproj/project.pbxproj (69%) rename {example => bluetooth_low_energy/example}/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename {example => bluetooth_low_energy/example}/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {example => bluetooth_low_energy/example}/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename {example => bluetooth_low_energy/example}/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (87%) rename {example => bluetooth_low_energy/example}/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename {example => bluetooth_low_energy/example}/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename {example => bluetooth_low_energy/example}/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/AppDelegate.swift (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png (100%) create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 bluetooth_low_energy/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename {example => bluetooth_low_energy/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Base.lproj/Main.storyboard (100%) rename {example => bluetooth_low_energy/example}/ios/Runner/Info.plist (94%) rename {example => bluetooth_low_energy/example}/ios/Runner/Runner-Bridging-Header.h (100%) create mode 100644 bluetooth_low_energy/example/ios/RunnerTests/RunnerTests.swift create mode 100644 bluetooth_low_energy/example/lib/main.dart create mode 100644 bluetooth_low_energy/example/linux/.gitignore create mode 100644 bluetooth_low_energy/example/linux/CMakeLists.txt create mode 100644 bluetooth_low_energy/example/linux/flutter/CMakeLists.txt create mode 100644 bluetooth_low_energy/example/linux/flutter/generated_plugin_registrant.cc create mode 100644 bluetooth_low_energy/example/linux/flutter/generated_plugin_registrant.h create mode 100644 bluetooth_low_energy/example/linux/flutter/generated_plugins.cmake create mode 100644 bluetooth_low_energy/example/linux/main.cc create mode 100644 bluetooth_low_energy/example/linux/my_application.cc create mode 100644 bluetooth_low_energy/example/linux/my_application.h create mode 100644 bluetooth_low_energy/example/macos/.gitignore create mode 100644 bluetooth_low_energy/example/macos/Flutter/Flutter-Debug.xcconfig create mode 100644 bluetooth_low_energy/example/macos/Flutter/Flutter-Release.xcconfig create mode 100644 bluetooth_low_energy/example/macos/Flutter/GeneratedPluginRegistrant.swift create mode 100644 bluetooth_low_energy/example/macos/Podfile create mode 100644 bluetooth_low_energy/example/macos/Podfile.lock create mode 100644 bluetooth_low_energy/example/macos/Runner.xcodeproj/project.pbxproj create mode 100644 bluetooth_low_energy/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 bluetooth_low_energy/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 bluetooth_low_energy/example/macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 bluetooth_low_energy/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 bluetooth_low_energy/example/macos/Runner/AppDelegate.swift create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png create mode 100644 bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png create mode 100644 bluetooth_low_energy/example/macos/Runner/Base.lproj/MainMenu.xib create mode 100644 bluetooth_low_energy/example/macos/Runner/Configs/AppInfo.xcconfig create mode 100644 bluetooth_low_energy/example/macos/Runner/Configs/Debug.xcconfig create mode 100644 bluetooth_low_energy/example/macos/Runner/Configs/Release.xcconfig create mode 100644 bluetooth_low_energy/example/macos/Runner/Configs/Warnings.xcconfig create mode 100644 bluetooth_low_energy/example/macos/Runner/DebugProfile.entitlements create mode 100644 bluetooth_low_energy/example/macos/Runner/Info.plist create mode 100644 bluetooth_low_energy/example/macos/Runner/MainFlutterWindow.swift create mode 100644 bluetooth_low_energy/example/macos/Runner/Release.entitlements create mode 100644 bluetooth_low_energy/example/macos/RunnerTests/RunnerTests.swift create mode 100644 bluetooth_low_energy/example/pubspec.lock rename {example => bluetooth_low_energy/example}/pubspec.yaml (97%) rename {example => bluetooth_low_energy/example}/test/widget_test.dart (100%) create mode 100644 bluetooth_low_energy/example/windows/.gitignore create mode 100644 bluetooth_low_energy/example/windows/CMakeLists.txt create mode 100644 bluetooth_low_energy/example/windows/flutter/CMakeLists.txt create mode 100644 bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.cc create mode 100644 bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.h create mode 100644 bluetooth_low_energy/example/windows/flutter/generated_plugins.cmake create mode 100644 bluetooth_low_energy/example/windows/runner/CMakeLists.txt create mode 100644 bluetooth_low_energy/example/windows/runner/Runner.rc create mode 100644 bluetooth_low_energy/example/windows/runner/flutter_window.cpp create mode 100644 bluetooth_low_energy/example/windows/runner/flutter_window.h create mode 100644 bluetooth_low_energy/example/windows/runner/main.cpp create mode 100644 bluetooth_low_energy/example/windows/runner/resource.h create mode 100644 bluetooth_low_energy/example/windows/runner/resources/app_icon.ico create mode 100644 bluetooth_low_energy/example/windows/runner/runner.exe.manifest create mode 100644 bluetooth_low_energy/example/windows/runner/utils.cpp create mode 100644 bluetooth_low_energy/example/windows/runner/utils.h create mode 100644 bluetooth_low_energy/example/windows/runner/win32_window.cpp create mode 100644 bluetooth_low_energy/example/windows/runner/win32_window.h rename {ios => bluetooth_low_energy/ios}/.gitignore (100%) rename {ios => bluetooth_low_energy/ios}/Assets/.gitkeep (100%) create mode 100644 bluetooth_low_energy/ios/Classes/BluetoothLowEnergyPlugin.swift rename {ios => bluetooth_low_energy/ios}/bluetooth_low_energy.podspec (92%) create mode 100644 bluetooth_low_energy/lib/bluetooth_low_energy.dart create mode 100644 bluetooth_low_energy/linux/CMakeLists.txt create mode 100644 bluetooth_low_energy/linux/bluetooth_low_energy_plugin.cc create mode 100644 bluetooth_low_energy/linux/bluetooth_low_energy_plugin_private.h create mode 100644 bluetooth_low_energy/linux/include/bluetooth_low_energy/bluetooth_low_energy_plugin.h create mode 100644 bluetooth_low_energy/linux/test/bluetooth_low_energy_plugin_test.cc create mode 100644 bluetooth_low_energy/macos/Classes/BluetoothLowEnergyPlugin.swift create mode 100644 bluetooth_low_energy/macos/bluetooth_low_energy.podspec create mode 100644 bluetooth_low_energy/pubspec.yaml create mode 100644 bluetooth_low_energy/test/bluetooth_low_energy_test.dart create mode 100644 bluetooth_low_energy/windows/.gitignore create mode 100644 bluetooth_low_energy/windows/CMakeLists.txt create mode 100644 bluetooth_low_energy/windows/bluetooth_low_energy_plugin.cpp create mode 100644 bluetooth_low_energy/windows/bluetooth_low_energy_plugin.h create mode 100644 bluetooth_low_energy/windows/bluetooth_low_energy_plugin_c_api.cpp create mode 100644 bluetooth_low_energy/windows/include/bluetooth_low_energy/bluetooth_low_energy_plugin_c_api.h create mode 100644 bluetooth_low_energy/windows/test/bluetooth_low_energy_plugin_test.cpp create mode 100644 bluetooth_low_energy_android/.gitignore rename .metadata => bluetooth_low_energy_android/.metadata (58%) create mode 100644 bluetooth_low_energy_android/CHANGELOG.md create mode 100644 bluetooth_low_energy_android/LICENSE create mode 100644 bluetooth_low_energy_android/README.md create mode 100644 bluetooth_low_energy_android/analysis_options.yaml rename {android => bluetooth_low_energy_android/android}/.gitignore (100%) rename {android => bluetooth_low_energy_android/android}/build.gradle (55%) rename {android => bluetooth_low_energy_android/android}/settings.gradle (100%) rename {android => bluetooth_low_energy_android/android}/src/main/AndroidManifest.xml (68%) create mode 100644 bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyAndroid.kt create mode 100644 bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyApi.g.kt create mode 100644 bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt create mode 100644 bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt create mode 100644 bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralController.kt create mode 100644 bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionResultListener.kt create mode 100644 bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt create mode 100644 bluetooth_low_energy_android/android/src/test/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPluginTest.kt create mode 100644 bluetooth_low_energy_android/lib/bluetooth_low_energy_android.dart create mode 100644 bluetooth_low_energy_android/lib/src/my_api.g.dart create mode 100644 bluetooth_low_energy_android/lib/src/my_central_controller.dart create mode 100644 bluetooth_low_energy_android/lib/src/my_gatt_characteristic.dart create mode 100644 bluetooth_low_energy_android/lib/src/my_gatt_descriptor.dart create mode 100644 bluetooth_low_energy_android/lib/src/my_gatt_service.dart create mode 100644 bluetooth_low_energy_android/lib/src/my_object.dart create mode 100644 bluetooth_low_energy_android/lib/src/my_peripheral.dart create mode 100644 bluetooth_low_energy_android/my_api.dart create mode 100644 bluetooth_low_energy_android/pubspec.yaml create mode 100644 bluetooth_low_energy_ios/.gitignore create mode 100644 bluetooth_low_energy_ios/.metadata create mode 100644 bluetooth_low_energy_ios/CHANGELOG.md create mode 100644 bluetooth_low_energy_ios/LICENSE create mode 100644 bluetooth_low_energy_ios/README.md create mode 100644 bluetooth_low_energy_ios/analysis_options.yaml create mode 100644 bluetooth_low_energy_ios/ios/.gitignore rename android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/MessagesKt.kt => bluetooth_low_energy_ios/ios/Assets/.gitkeep (100%) create mode 100644 bluetooth_low_energy_ios/ios/Classes/BluetoothLowEnergyiOS.swift create mode 100644 bluetooth_low_energy_ios/ios/Classes/MyApi.g.swift create mode 100644 bluetooth_low_energy_ios/ios/Classes/MyCentralController.swift create mode 100644 bluetooth_low_energy_ios/ios/Classes/MyCentralManagerDelegate.swift create mode 100644 bluetooth_low_energy_ios/ios/Classes/MyError.swift create mode 100644 bluetooth_low_energy_ios/ios/Classes/MyPeripheralDelegate.swift create mode 100644 bluetooth_low_energy_ios/ios/bluetooth_low_energy_ios.podspec create mode 100644 bluetooth_low_energy_ios/lib/bluetooth_low_energy_ios.dart create mode 100644 bluetooth_low_energy_ios/lib/src/my_api.g.dart create mode 100644 bluetooth_low_energy_ios/lib/src/my_central_controller.dart create mode 100644 bluetooth_low_energy_ios/lib/src/my_gatt_characteristic.dart create mode 100644 bluetooth_low_energy_ios/lib/src/my_gatt_descriptor.dart create mode 100644 bluetooth_low_energy_ios/lib/src/my_gatt_service.dart create mode 100644 bluetooth_low_energy_ios/lib/src/my_object.dart create mode 100644 bluetooth_low_energy_ios/lib/src/my_peripheral.dart create mode 100644 bluetooth_low_energy_ios/my_api.dart create mode 100644 bluetooth_low_energy_ios/pubspec.yaml create mode 100644 bluetooth_low_energy_linux/.gitignore create mode 100644 bluetooth_low_energy_linux/.metadata create mode 100644 bluetooth_low_energy_linux/CHANGELOG.md create mode 100644 bluetooth_low_energy_linux/LICENSE create mode 100644 bluetooth_low_energy_linux/README.md create mode 100644 bluetooth_low_energy_linux/analysis_options.yaml create mode 100644 bluetooth_low_energy_linux/lib/bluetooth_low_energy_linux.dart create mode 100644 bluetooth_low_energy_linux/lib/src/my_bluez.dart create mode 100644 bluetooth_low_energy_linux/lib/src/my_central_controller.dart create mode 100644 bluetooth_low_energy_linux/lib/src/my_gatt_characteristic.dart create mode 100644 bluetooth_low_energy_linux/lib/src/my_gatt_descriptor.dart create mode 100644 bluetooth_low_energy_linux/lib/src/my_gatt_service.dart create mode 100644 bluetooth_low_energy_linux/lib/src/my_object.dart create mode 100644 bluetooth_low_energy_linux/lib/src/my_peripheral.dart create mode 100644 bluetooth_low_energy_linux/pubspec.yaml create mode 100644 bluetooth_low_energy_macos/.gitignore create mode 100644 bluetooth_low_energy_macos/.metadata create mode 100644 bluetooth_low_energy_macos/CHANGELOG.md create mode 100644 bluetooth_low_energy_macos/LICENSE create mode 100644 bluetooth_low_energy_macos/README.md create mode 100644 bluetooth_low_energy_macos/analysis_options.yaml create mode 100644 bluetooth_low_energy_macos/lib/bluetooth_low_energy_macos.dart create mode 100644 bluetooth_low_energy_macos/lib/src/my_api.g.dart create mode 100644 bluetooth_low_energy_macos/lib/src/my_central_controller.dart create mode 100644 bluetooth_low_energy_macos/lib/src/my_gatt_characteristic.dart create mode 100644 bluetooth_low_energy_macos/lib/src/my_gatt_descriptor.dart create mode 100644 bluetooth_low_energy_macos/lib/src/my_gatt_service.dart create mode 100644 bluetooth_low_energy_macos/lib/src/my_object.dart create mode 100644 bluetooth_low_energy_macos/lib/src/my_peripheral.dart create mode 100644 bluetooth_low_energy_macos/macos/Classes/BluetoothLowEnergymacOS.swift create mode 100644 bluetooth_low_energy_macos/macos/Classes/MyApi.g.swift create mode 100644 bluetooth_low_energy_macos/macos/Classes/MyCentralController.swift create mode 100644 bluetooth_low_energy_macos/macos/Classes/MyCentralManagerDelegate.swift create mode 100644 bluetooth_low_energy_macos/macos/Classes/MyError.swift create mode 100644 bluetooth_low_energy_macos/macos/Classes/MyPeripheralDelegate.swift create mode 100644 bluetooth_low_energy_macos/macos/bluetooth_low_energy_macos.podspec create mode 100644 bluetooth_low_energy_macos/my_api.dart create mode 100644 bluetooth_low_energy_macos/pubspec.yaml create mode 100644 bluetooth_low_energy_platform_interface/.gitignore create mode 100644 bluetooth_low_energy_platform_interface/.metadata create mode 100644 bluetooth_low_energy_platform_interface/CHANGELOG.md create mode 100644 bluetooth_low_energy_platform_interface/LICENSE create mode 100644 bluetooth_low_energy_platform_interface/README.md create mode 100644 bluetooth_low_energy_platform_interface/analysis_options.yaml create mode 100644 bluetooth_low_energy_platform_interface/lib/bluetooth_low_energy_platform_interface.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/advertisement.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/central_controller.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/central_state.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/errors.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/event_args.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_property.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_write_type.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/gatt_service.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/peripheral.dart create mode 100644 bluetooth_low_energy_platform_interface/lib/src/uuid.dart create mode 100644 bluetooth_low_energy_platform_interface/pubspec.yaml create mode 100644 bluetooth_low_energy_platform_interface/test/bluetooth_low_energy_platform_interface_test.dart create mode 100644 bluetooth_low_energy_windows/.gitignore create mode 100644 bluetooth_low_energy_windows/.metadata create mode 100644 bluetooth_low_energy_windows/CHANGELOG.md create mode 100644 bluetooth_low_energy_windows/LICENSE create mode 100644 bluetooth_low_energy_windows/README.md create mode 100644 bluetooth_low_energy_windows/analysis_options.yaml create mode 100644 bluetooth_low_energy_windows/lib/bluetooth_low_energy_windows.dart create mode 100644 bluetooth_low_energy_windows/lib/src/my_central_controller.dart create mode 100644 bluetooth_low_energy_windows/pubspec.yaml create mode 100644 bluetooth_low_energy_windows/windows/.gitignore create mode 100644 bluetooth_low_energy_windows/windows/CMakeLists.txt create mode 100644 bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.cpp create mode 100644 bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.h create mode 100644 bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin_c_api.cpp create mode 100644 bluetooth_low_energy_windows/windows/include/bluetooth_low_energy_windows/bluetooth_low_energy_windows_plugin_c_api.h delete mode 100644 example/ios/Podfile.lock delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 example/lib/main.dart delete mode 100644 example/pubspec.lock delete mode 100644 ios/Classes/BluetoothLowEnergyPlugin.h delete mode 100644 ios/Classes/BluetoothLowEnergyPlugin.m delete mode 100644 ios/Classes/MyCentralManagerDelegate.swift delete mode 100644 ios/Classes/MyCentralManagerHostApi.swift delete mode 100644 ios/Classes/MyGattCharacteristicHostApi.swift delete mode 100644 ios/Classes/MyGattDescriptorHostApi.swift delete mode 100644 ios/Classes/MyGattServiceHostApi.swift delete mode 100644 ios/Classes/MyPeripheralDelegate.swift delete mode 100644 ios/Classes/MyPeripheralHostApi.swift delete mode 100644 ios/Classes/SwiftBluetoothLowEnergyPlugin.swift delete mode 100644 ios/Classes/pigeon/Messages.h delete mode 100644 ios/Classes/pigeon/Messages.m delete mode 100644 ios/Classes/proto/messages.pb.swift delete mode 100644 lib/bluetooth_low_energy.dart delete mode 100644 lib/src/api.dart delete mode 100644 lib/src/bluetooth_state.dart delete mode 100644 lib/src/broadcast.dart delete mode 100644 lib/src/central_manager.dart delete mode 100644 lib/src/gatt_characteristic.dart delete mode 100644 lib/src/gatt_descriptor.dart delete mode 100644 lib/src/gatt_service.dart delete mode 100644 lib/src/impl.dart delete mode 100644 lib/src/peripheral.dart delete mode 100644 lib/src/pigeon.dart delete mode 100644 lib/src/pigeon/messages.g.dart delete mode 100644 lib/src/proto.dart delete mode 100644 lib/src/proto/messages.pb.dart delete mode 100644 lib/src/proto/messages.pbenum.dart delete mode 100644 lib/src/proto/messages.pbjson.dart delete mode 100644 lib/src/proto/messages.pbserver.dart delete mode 100644 lib/src/uuid.dart delete mode 100644 pigeon/messages.dart delete mode 100644 proto/messages.proto delete mode 100644 pubspec.yaml delete mode 100644 scripts/run_protoc.sh delete mode 100644 test/pigeon/test_messages.g.dart diff --git a/LICENSE b/LICENSE index 436615a..515ed4b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 yanshouwang +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 @@ -18,4 +18,4 @@ 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. +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index cfaf442..897ff13 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,5 @@ # bluetooth_low_energy -A bluetooth low energy plugin for flutter, which can be used to develope central role apps. +This repo contains the source code for the [`bluetooth_low_energy`][1] federated plugins. -## Features - -### Central APIs -- [x] Scan advertisements. -- [x] Connect/Disconnect to peripherals. -- [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 - -Add `bluetooth_low_energy` as a [dependency in your pubspec.yaml file](https://flutter.dev/using-packages/). - -``` -dependencies: - bluetooth_low_energy: ^ -``` - -*Note*: Bluetooth Low Energy doesn't work on Android emulators, so use physical devices which has bluetooth features for development. - -### Android - -Make sure you have a `miniSdkVersion` with 21 or higher in your `android/app/build.gradle` file. - -### iOS - -Make sure you have a minimum deployment target of 9.0 or above, you can uncomment the first line `platform :ios, '9.0'` in your iOS project's `Podfile`. - -*Note*: According to Apple's [documents](https://developer.apple.com/documentation/corebluetooth/), you must include the [`NSBluetoothAlwaysUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothalwaysusagedescription) on or after iOS 13, and include the [`NSBluetoothPeripheralUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothperipheralusagedescription) key before iOS 13. - -## Issues - -- Peripheral APIs are not implemented yet. +[1]: https://pub.dev/packages/bluetooth_low_energy \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml deleted file mode 100644 index 6d17812..0000000 --- a/analysis_options.yaml +++ /dev/null @@ -1,18 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options - -analyzer: - exclude: - - "**/*.g.dart" - - "**/*.mocks.dart" - - "**/*.pb.dart" - - "**/*.pbenum.dart" - - "**/*.pbjson.dart" - - "**/*.pbserver.dart" - -linter: - rules: - prefer_single_quotes: true - require_trailing_commas: true \ No newline at end of file diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/pigeon/Messages.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/pigeon/Messages.java deleted file mode 100644 index 1c3d941..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/pigeon/Messages.java +++ /dev/null @@ -1,809 +0,0 @@ -// Autogenerated from Pigeon (v4.2.0), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -package dev.yanshouwang.bluetooth_low_energy.pigeon; - -import android.util.Log; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import io.flutter.plugin.common.BasicMessageChannel; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MessageCodec; -import io.flutter.plugin.common.StandardMessageCodec; -import java.io.ByteArrayOutputStream; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.HashMap; - -/**Generated class from Pigeon. */ -@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"}) -public class Messages { - - public interface Result { - void success(T result); - void error(Throwable error); - } - private static class CentralManagerHostApiCodec extends StandardMessageCodec { - public static final CentralManagerHostApiCodec INSTANCE = new CentralManagerHostApiCodec(); - private CentralManagerHostApiCodec() {} - } - - /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ - public interface CentralManagerHostApi { - void authorize(Result result); - @NonNull Long getState(); - void startScan(@Nullable List uuidBuffers, Result result); - void stopScan(); - - /** The codec used by CentralManagerHostApi. */ - static MessageCodec getCodec() { - return CentralManagerHostApiCodec.INSTANCE; - } - - /**Sets up an instance of `CentralManagerHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, CentralManagerHostApi api) { - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.CentralManagerHostApi.authorize", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - Result resultCallback = new Result() { - public void success(Boolean result) { - wrapped.put("result", result); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.authorize(resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.CentralManagerHostApi.getState", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - Long output = api.getState(); - wrapped.put("result", output); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - } - reply.reply(wrapped); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.CentralManagerHostApi.startScan", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - List uuidBuffersArg = (List)args.get(0); - Result resultCallback = new Result() { - public void success(Void result) { - wrapped.put("result", null); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.startScan(uuidBuffersArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.CentralManagerHostApi.stopScan", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - api.stopScan(); - wrapped.put("result", null); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - } - reply.reply(wrapped); - }); - } else { - channel.setMessageHandler(null); - } - } - } - } - private static class CentralManagerFlutterApiCodec extends StandardMessageCodec { - public static final CentralManagerFlutterApiCodec INSTANCE = new CentralManagerFlutterApiCodec(); - private CentralManagerFlutterApiCodec() {} - } - - /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ - public static class CentralManagerFlutterApi { - private final BinaryMessenger binaryMessenger; - public CentralManagerFlutterApi(BinaryMessenger argBinaryMessenger){ - this.binaryMessenger = argBinaryMessenger; - } - public interface Reply { - void reply(T reply); - } - static MessageCodec getCodec() { - return CentralManagerFlutterApiCodec.INSTANCE; - } - - public void onStateChanged(@NonNull Long stateNumberArg, Reply callback) { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.CentralManagerFlutterApi.onStateChanged", getCodec()); - channel.send(new ArrayList(Arrays.asList(stateNumberArg)), channelReply -> { - callback.reply(null); - }); - } - public void onScanned(@NonNull byte[] broadcastBufferArg, Reply callback) { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.CentralManagerFlutterApi.onScanned", getCodec()); - channel.send(new ArrayList(Arrays.asList(broadcastBufferArg)), channelReply -> { - callback.reply(null); - }); - } - } - private static class PeripheralHostApiCodec extends StandardMessageCodec { - public static final PeripheralHostApiCodec INSTANCE = new PeripheralHostApiCodec(); - private PeripheralHostApiCodec() {} - } - - /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ - public interface PeripheralHostApi { - void free(@NonNull String id); - void connect(@NonNull String id, Result result); - void disconnect(@NonNull String id, Result result); - void requestMtu(@NonNull String id, Result result); - void discoverServices(@NonNull String id, Result> result); - - /** The codec used by PeripheralHostApi. */ - static MessageCodec getCodec() { - return PeripheralHostApiCodec.INSTANCE; - } - - /**Sets up an instance of `PeripheralHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, PeripheralHostApi api) { - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.PeripheralHostApi.free", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - api.free(idArg); - wrapped.put("result", null); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - } - reply.reply(wrapped); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.PeripheralHostApi.connect", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(Void result) { - wrapped.put("result", null); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.connect(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.PeripheralHostApi.disconnect", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(Void result) { - wrapped.put("result", null); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.disconnect(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.PeripheralHostApi.requestMtu", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(Long result) { - wrapped.put("result", result); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.requestMtu(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.PeripheralHostApi.discoverServices", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result> resultCallback = new Result>() { - public void success(List result) { - wrapped.put("result", result); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.discoverServices(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - } - } - private static class PeripheralFlutterApiCodec extends StandardMessageCodec { - public static final PeripheralFlutterApiCodec INSTANCE = new PeripheralFlutterApiCodec(); - private PeripheralFlutterApiCodec() {} - } - - /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ - public static class PeripheralFlutterApi { - private final BinaryMessenger binaryMessenger; - public PeripheralFlutterApi(BinaryMessenger argBinaryMessenger){ - this.binaryMessenger = argBinaryMessenger; - } - public interface Reply { - void reply(T reply); - } - static MessageCodec getCodec() { - return PeripheralFlutterApiCodec.INSTANCE; - } - - public void onConnectionLost(@NonNull String idArg, @NonNull String errorMessageArg, Reply callback) { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.PeripheralFlutterApi.onConnectionLost", getCodec()); - channel.send(new ArrayList(Arrays.asList(idArg, errorMessageArg)), channelReply -> { - callback.reply(null); - }); - } - } - private static class GattServiceHostApiCodec extends StandardMessageCodec { - public static final GattServiceHostApiCodec INSTANCE = new GattServiceHostApiCodec(); - private GattServiceHostApiCodec() {} - } - - /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ - public interface GattServiceHostApi { - void free(@NonNull String id); - void discoverCharacteristics(@NonNull String id, Result> result); - - /** The codec used by GattServiceHostApi. */ - static MessageCodec getCodec() { - return GattServiceHostApiCodec.INSTANCE; - } - - /**Sets up an instance of `GattServiceHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, GattServiceHostApi api) { - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattServiceHostApi.free", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - api.free(idArg); - wrapped.put("result", null); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - } - reply.reply(wrapped); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattServiceHostApi.discoverCharacteristics", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result> resultCallback = new Result>() { - public void success(List result) { - wrapped.put("result", result); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.discoverCharacteristics(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - } - } - private static class GattCharacteristicHostApiCodec extends StandardMessageCodec { - public static final GattCharacteristicHostApiCodec INSTANCE = new GattCharacteristicHostApiCodec(); - private GattCharacteristicHostApiCodec() {} - } - - /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ - public interface GattCharacteristicHostApi { - void free(@NonNull String id); - void discoverDescriptors(@NonNull String id, Result> result); - void read(@NonNull String id, Result result); - void write(@NonNull String id, @NonNull byte[] value, @NonNull Boolean withoutResponse, Result result); - void setNotify(@NonNull String id, @NonNull Boolean value, Result result); - - /** The codec used by GattCharacteristicHostApi. */ - static MessageCodec getCodec() { - return GattCharacteristicHostApiCodec.INSTANCE; - } - - /**Sets up an instance of `GattCharacteristicHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, GattCharacteristicHostApi api) { - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattCharacteristicHostApi.free", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - api.free(idArg); - wrapped.put("result", null); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - } - reply.reply(wrapped); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattCharacteristicHostApi.discoverDescriptors", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result> resultCallback = new Result>() { - public void success(List result) { - wrapped.put("result", result); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.discoverDescriptors(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattCharacteristicHostApi.read", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(byte[] result) { - wrapped.put("result", result); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.read(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattCharacteristicHostApi.write", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - byte[] valueArg = (byte[])args.get(1); - if (valueArg == null) { - throw new NullPointerException("valueArg unexpectedly null."); - } - Boolean withoutResponseArg = (Boolean)args.get(2); - if (withoutResponseArg == null) { - throw new NullPointerException("withoutResponseArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(Void result) { - wrapped.put("result", null); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.write(idArg, valueArg, withoutResponseArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattCharacteristicHostApi.setNotify", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Boolean valueArg = (Boolean)args.get(1); - if (valueArg == null) { - throw new NullPointerException("valueArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(Void result) { - wrapped.put("result", null); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.setNotify(idArg, valueArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - } - } - private static class GattCharacteristicFlutterApiCodec extends StandardMessageCodec { - public static final GattCharacteristicFlutterApiCodec INSTANCE = new GattCharacteristicFlutterApiCodec(); - private GattCharacteristicFlutterApiCodec() {} - } - - /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ - public static class GattCharacteristicFlutterApi { - private final BinaryMessenger binaryMessenger; - public GattCharacteristicFlutterApi(BinaryMessenger argBinaryMessenger){ - this.binaryMessenger = argBinaryMessenger; - } - public interface Reply { - void reply(T reply); - } - static MessageCodec getCodec() { - return GattCharacteristicFlutterApiCodec.INSTANCE; - } - - public void onValueChanged(@NonNull String idArg, @NonNull byte[] valueArg, Reply callback) { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattCharacteristicFlutterApi.onValueChanged", getCodec()); - channel.send(new ArrayList(Arrays.asList(idArg, valueArg)), channelReply -> { - callback.reply(null); - }); - } - } - private static class GattDescriptorHostApiCodec extends StandardMessageCodec { - public static final GattDescriptorHostApiCodec INSTANCE = new GattDescriptorHostApiCodec(); - private GattDescriptorHostApiCodec() {} - } - - /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ - public interface GattDescriptorHostApi { - void free(@NonNull String id); - void read(@NonNull String id, Result result); - void write(@NonNull String id, @NonNull byte[] value, Result result); - - /** The codec used by GattDescriptorHostApi. */ - static MessageCodec getCodec() { - return GattDescriptorHostApiCodec.INSTANCE; - } - - /**Sets up an instance of `GattDescriptorHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, GattDescriptorHostApi api) { - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattDescriptorHostApi.free", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - api.free(idArg); - wrapped.put("result", null); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - } - reply.reply(wrapped); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattDescriptorHostApi.read", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(byte[] result) { - wrapped.put("result", result); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.read(idArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>(binaryMessenger, "dev.flutter.pigeon.GattDescriptorHostApi.write", getCodec()); - if (api != null) { - channel.setMessageHandler((message, reply) -> { - Map wrapped = new HashMap<>(); - try { - ArrayList args = (ArrayList)message; - String idArg = (String)args.get(0); - if (idArg == null) { - throw new NullPointerException("idArg unexpectedly null."); - } - byte[] valueArg = (byte[])args.get(1); - if (valueArg == null) { - throw new NullPointerException("valueArg unexpectedly null."); - } - Result resultCallback = new Result() { - public void success(Void result) { - wrapped.put("result", null); - reply.reply(wrapped); - } - public void error(Throwable error) { - wrapped.put("error", wrapError(error)); - reply.reply(wrapped); - } - }; - - api.write(idArg, valueArg, resultCallback); - } - catch (Error | RuntimeException exception) { - wrapped.put("error", wrapError(exception)); - reply.reply(wrapped); - } - }); - } else { - channel.setMessageHandler(null); - } - } - } - } - @NonNull private static Map wrapError(@NonNull Throwable exception) { - Map errorMap = new HashMap<>(); - errorMap.put("message", exception.toString()); - errorMap.put("code", exception.getClass().getSimpleName()); - errorMap.put("details", "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); - return errorMap; - } -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BluetoothState.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BluetoothState.java deleted file mode 100644 index 171ec39..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BluetoothState.java +++ /dev/null @@ -1,122 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf enum {@code proto.BluetoothState} - */ -public enum BluetoothState - implements com.google.protobuf.ProtocolMessageEnum { - /** - * BLUETOOTH_STATE_UNSUPPORTED = 0; - */ - BLUETOOTH_STATE_UNSUPPORTED(0), - /** - * BLUETOOTH_STATE_POWERED_OFF = 1; - */ - BLUETOOTH_STATE_POWERED_OFF(1), - /** - * BLUETOOTH_STATE_POWERED_ON = 2; - */ - BLUETOOTH_STATE_POWERED_ON(2), - UNRECOGNIZED(-1), - ; - - /** - * BLUETOOTH_STATE_UNSUPPORTED = 0; - */ - public static final int BLUETOOTH_STATE_UNSUPPORTED_VALUE = 0; - /** - * BLUETOOTH_STATE_POWERED_OFF = 1; - */ - public static final int BLUETOOTH_STATE_POWERED_OFF_VALUE = 1; - /** - * BLUETOOTH_STATE_POWERED_ON = 2; - */ - public static final int BLUETOOTH_STATE_POWERED_ON_VALUE = 2; - - - public final int getNumber() { - if (this == UNRECOGNIZED) { - throw new java.lang.IllegalArgumentException( - "Can't get the number of an unknown enum value."); - } - return value; - } - - /** - * @param value The numeric wire value of the corresponding enum entry. - * @return The enum associated with the given numeric wire value. - * @deprecated Use {@link #forNumber(int)} instead. - */ - @java.lang.Deprecated - public static BluetoothState valueOf(int value) { - return forNumber(value); - } - - /** - * @param value The numeric wire value of the corresponding enum entry. - * @return The enum associated with the given numeric wire value. - */ - public static BluetoothState forNumber(int value) { - switch (value) { - case 0: return BLUETOOTH_STATE_UNSUPPORTED; - case 1: return BLUETOOTH_STATE_POWERED_OFF; - case 2: return BLUETOOTH_STATE_POWERED_ON; - default: return null; - } - } - - public static com.google.protobuf.Internal.EnumLiteMap - internalGetValueMap() { - return internalValueMap; - } - private static final com.google.protobuf.Internal.EnumLiteMap< - BluetoothState> internalValueMap = - new com.google.protobuf.Internal.EnumLiteMap() { - public BluetoothState findValueByNumber(int number) { - return BluetoothState.forNumber(number); - } - }; - - public final com.google.protobuf.Descriptors.EnumValueDescriptor - getValueDescriptor() { - if (this == UNRECOGNIZED) { - throw new java.lang.IllegalStateException( - "Can't get the descriptor of an unrecognized enum value."); - } - return getDescriptor().getValues().get(ordinal()); - } - public final com.google.protobuf.Descriptors.EnumDescriptor - getDescriptorForType() { - return getDescriptor(); - } - public static final com.google.protobuf.Descriptors.EnumDescriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.getDescriptor().getEnumTypes().get(0); - } - - private static final BluetoothState[] VALUES = values(); - - public static BluetoothState valueOf( - com.google.protobuf.Descriptors.EnumValueDescriptor desc) { - if (desc.getType() != getDescriptor()) { - throw new java.lang.IllegalArgumentException( - "EnumValueDescriptor is not for this type."); - } - if (desc.getIndex() == -1) { - return UNRECOGNIZED; - } - return VALUES[desc.getIndex()]; - } - - private final int value; - - private BluetoothState(int value) { - this.value = value; - } - - // @@protoc_insertion_point(enum_scope:proto.BluetoothState) -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Broadcast.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Broadcast.java deleted file mode 100644 index 41236d3..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Broadcast.java +++ /dev/null @@ -1,2198 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf type {@code proto.Broadcast} - */ -public final class Broadcast extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:proto.Broadcast) - BroadcastOrBuilder { -private static final long serialVersionUID = 0L; - // Use Broadcast.newBuilder() to construct. - private Broadcast(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private Broadcast() { - data_ = com.google.protobuf.ByteString.EMPTY; - localName_ = ""; - manufacturerSpecificData_ = com.google.protobuf.ByteString.EMPTY; - serviceDatas_ = java.util.Collections.emptyList(); - serviceUuids_ = java.util.Collections.emptyList(); - solicitedServiceUuids_ = java.util.Collections.emptyList(); - } - - @java.lang.Override - @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new Broadcast(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Broadcast( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder subBuilder = null; - if (peripheral_ != null) { - subBuilder = peripheral_.toBuilder(); - } - peripheral_ = input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(peripheral_); - peripheral_ = subBuilder.buildPartial(); - } - - break; - } - case 16: { - - rssi_ = input.readInt32(); - break; - } - case 24: { - bitField0_ |= 0x00000001; - connectable_ = input.readBool(); - break; - } - case 34: { - - data_ = input.readBytes(); - break; - } - case 42: { - java.lang.String s = input.readStringRequireUtf8(); - bitField0_ |= 0x00000002; - localName_ = s; - break; - } - case 50: { - - manufacturerSpecificData_ = input.readBytes(); - break; - } - case 58: { - if (!((mutable_bitField0_ & 0x00000004) != 0)) { - serviceDatas_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000004; - } - serviceDatas_.add( - input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.parser(), extensionRegistry)); - break; - } - case 66: { - if (!((mutable_bitField0_ & 0x00000008) != 0)) { - serviceUuids_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000008; - } - serviceUuids_.add( - input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.UUID.parser(), extensionRegistry)); - break; - } - case 74: { - if (!((mutable_bitField0_ & 0x00000010) != 0)) { - solicitedServiceUuids_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000010; - } - solicitedServiceUuids_.add( - input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.UUID.parser(), extensionRegistry)); - break; - } - case 80: { - bitField0_ |= 0x00000004; - txPowerLevel_ = input.readInt32(); - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - if (((mutable_bitField0_ & 0x00000004) != 0)) { - serviceDatas_ = java.util.Collections.unmodifiableList(serviceDatas_); - } - if (((mutable_bitField0_ & 0x00000008) != 0)) { - serviceUuids_ = java.util.Collections.unmodifiableList(serviceUuids_); - } - if (((mutable_bitField0_ & 0x00000010) != 0)) { - solicitedServiceUuids_ = java.util.Collections.unmodifiableList(solicitedServiceUuids_); - } - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Broadcast_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Broadcast_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.class, dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.Builder.class); - } - - private int bitField0_; - public static final int PERIPHERAL_FIELD_NUMBER = 1; - private dev.yanshouwang.bluetooth_low_energy.proto.Peripheral peripheral_; - /** - * .proto.Peripheral peripheral = 1; - * @return Whether the peripheral field is set. - */ - @java.lang.Override - public boolean hasPeripheral() { - return peripheral_ != null; - } - /** - * .proto.Peripheral peripheral = 1; - * @return The peripheral. - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Peripheral getPeripheral() { - return peripheral_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.getDefaultInstance() : peripheral_; - } - /** - * .proto.Peripheral peripheral = 1; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder getPeripheralOrBuilder() { - return getPeripheral(); - } - - public static final int RSSI_FIELD_NUMBER = 2; - private int rssi_; - /** - * int32 rssi = 2; - * @return The rssi. - */ - @java.lang.Override - public int getRssi() { - return rssi_; - } - - public static final int CONNECTABLE_FIELD_NUMBER = 3; - private boolean connectable_; - /** - * optional bool connectable = 3; - * @return Whether the connectable field is set. - */ - @java.lang.Override - public boolean hasConnectable() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * optional bool connectable = 3; - * @return The connectable. - */ - @java.lang.Override - public boolean getConnectable() { - return connectable_; - } - - public static final int DATA_FIELD_NUMBER = 4; - private com.google.protobuf.ByteString data_; - /** - * bytes data = 4; - * @return The data. - */ - @java.lang.Override - public com.google.protobuf.ByteString getData() { - return data_; - } - - public static final int LOCAL_NAME_FIELD_NUMBER = 5; - private volatile java.lang.Object localName_; - /** - * optional string local_name = 5; - * @return Whether the localName field is set. - */ - @java.lang.Override - public boolean hasLocalName() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * optional string local_name = 5; - * @return The localName. - */ - @java.lang.Override - public java.lang.String getLocalName() { - java.lang.Object ref = localName_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - localName_ = s; - return s; - } - } - /** - * optional string local_name = 5; - * @return The bytes for localName. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getLocalNameBytes() { - java.lang.Object ref = localName_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - localName_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int MANUFACTURER_SPECIFIC_DATA_FIELD_NUMBER = 6; - private com.google.protobuf.ByteString manufacturerSpecificData_; - /** - * bytes manufacturer_specific_data = 6; - * @return The manufacturerSpecificData. - */ - @java.lang.Override - public com.google.protobuf.ByteString getManufacturerSpecificData() { - return manufacturerSpecificData_; - } - - public static final int SERVICE_DATAS_FIELD_NUMBER = 7; - private java.util.List serviceDatas_; - /** - * repeated .proto.ServiceData service_datas = 7; - */ - @java.lang.Override - public java.util.List getServiceDatasList() { - return serviceDatas_; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - @java.lang.Override - public java.util.List - getServiceDatasOrBuilderList() { - return serviceDatas_; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - @java.lang.Override - public int getServiceDatasCount() { - return serviceDatas_.size(); - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData getServiceDatas(int index) { - return serviceDatas_.get(index); - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder getServiceDatasOrBuilder( - int index) { - return serviceDatas_.get(index); - } - - public static final int SERVICE_UUIDS_FIELD_NUMBER = 8; - private java.util.List serviceUuids_; - /** - * repeated .proto.UUID service_uuids = 8; - */ - @java.lang.Override - public java.util.List getServiceUuidsList() { - return serviceUuids_; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - @java.lang.Override - public java.util.List - getServiceUuidsOrBuilderList() { - return serviceUuids_; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - @java.lang.Override - public int getServiceUuidsCount() { - return serviceUuids_.size(); - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getServiceUuids(int index) { - return serviceUuids_.get(index); - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getServiceUuidsOrBuilder( - int index) { - return serviceUuids_.get(index); - } - - public static final int SOLICITED_SERVICE_UUIDS_FIELD_NUMBER = 9; - private java.util.List solicitedServiceUuids_; - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - @java.lang.Override - public java.util.List getSolicitedServiceUuidsList() { - return solicitedServiceUuids_; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - @java.lang.Override - public java.util.List - getSolicitedServiceUuidsOrBuilderList() { - return solicitedServiceUuids_; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - @java.lang.Override - public int getSolicitedServiceUuidsCount() { - return solicitedServiceUuids_.size(); - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getSolicitedServiceUuids(int index) { - return solicitedServiceUuids_.get(index); - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getSolicitedServiceUuidsOrBuilder( - int index) { - return solicitedServiceUuids_.get(index); - } - - public static final int TX_POWER_LEVEL_FIELD_NUMBER = 10; - private int txPowerLevel_; - /** - * optional int32 tx_power_level = 10; - * @return Whether the txPowerLevel field is set. - */ - @java.lang.Override - public boolean hasTxPowerLevel() { - return ((bitField0_ & 0x00000004) != 0); - } - /** - * optional int32 tx_power_level = 10; - * @return The txPowerLevel. - */ - @java.lang.Override - public int getTxPowerLevel() { - return txPowerLevel_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (peripheral_ != null) { - output.writeMessage(1, getPeripheral()); - } - if (rssi_ != 0) { - output.writeInt32(2, rssi_); - } - if (((bitField0_ & 0x00000001) != 0)) { - output.writeBool(3, connectable_); - } - if (!data_.isEmpty()) { - output.writeBytes(4, data_); - } - if (((bitField0_ & 0x00000002) != 0)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 5, localName_); - } - if (!manufacturerSpecificData_.isEmpty()) { - output.writeBytes(6, manufacturerSpecificData_); - } - for (int i = 0; i < serviceDatas_.size(); i++) { - output.writeMessage(7, serviceDatas_.get(i)); - } - for (int i = 0; i < serviceUuids_.size(); i++) { - output.writeMessage(8, serviceUuids_.get(i)); - } - for (int i = 0; i < solicitedServiceUuids_.size(); i++) { - output.writeMessage(9, solicitedServiceUuids_.get(i)); - } - if (((bitField0_ & 0x00000004) != 0)) { - output.writeInt32(10, txPowerLevel_); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (peripheral_ != null) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getPeripheral()); - } - if (rssi_ != 0) { - size += com.google.protobuf.CodedOutputStream - .computeInt32Size(2, rssi_); - } - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(3, connectable_); - } - if (!data_.isEmpty()) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(4, data_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, localName_); - } - if (!manufacturerSpecificData_.isEmpty()) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(6, manufacturerSpecificData_); - } - for (int i = 0; i < serviceDatas_.size(); i++) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(7, serviceDatas_.get(i)); - } - for (int i = 0; i < serviceUuids_.size(); i++) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(8, serviceUuids_.get(i)); - } - for (int i = 0; i < solicitedServiceUuids_.size(); i++) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(9, solicitedServiceUuids_.get(i)); - } - if (((bitField0_ & 0x00000004) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeInt32Size(10, txPowerLevel_); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof dev.yanshouwang.bluetooth_low_energy.proto.Broadcast)) { - return super.equals(obj); - } - dev.yanshouwang.bluetooth_low_energy.proto.Broadcast other = (dev.yanshouwang.bluetooth_low_energy.proto.Broadcast) obj; - - if (hasPeripheral() != other.hasPeripheral()) return false; - if (hasPeripheral()) { - if (!getPeripheral() - .equals(other.getPeripheral())) return false; - } - if (getRssi() - != other.getRssi()) return false; - if (hasConnectable() != other.hasConnectable()) return false; - if (hasConnectable()) { - if (getConnectable() - != other.getConnectable()) return false; - } - if (!getData() - .equals(other.getData())) return false; - if (hasLocalName() != other.hasLocalName()) return false; - if (hasLocalName()) { - if (!getLocalName() - .equals(other.getLocalName())) return false; - } - if (!getManufacturerSpecificData() - .equals(other.getManufacturerSpecificData())) return false; - if (!getServiceDatasList() - .equals(other.getServiceDatasList())) return false; - if (!getServiceUuidsList() - .equals(other.getServiceUuidsList())) return false; - if (!getSolicitedServiceUuidsList() - .equals(other.getSolicitedServiceUuidsList())) return false; - if (hasTxPowerLevel() != other.hasTxPowerLevel()) return false; - if (hasTxPowerLevel()) { - if (getTxPowerLevel() - != other.getTxPowerLevel()) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (hasPeripheral()) { - hash = (37 * hash) + PERIPHERAL_FIELD_NUMBER; - hash = (53 * hash) + getPeripheral().hashCode(); - } - hash = (37 * hash) + RSSI_FIELD_NUMBER; - hash = (53 * hash) + getRssi(); - if (hasConnectable()) { - hash = (37 * hash) + CONNECTABLE_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( - getConnectable()); - } - hash = (37 * hash) + DATA_FIELD_NUMBER; - hash = (53 * hash) + getData().hashCode(); - if (hasLocalName()) { - hash = (37 * hash) + LOCAL_NAME_FIELD_NUMBER; - hash = (53 * hash) + getLocalName().hashCode(); - } - hash = (37 * hash) + MANUFACTURER_SPECIFIC_DATA_FIELD_NUMBER; - hash = (53 * hash) + getManufacturerSpecificData().hashCode(); - if (getServiceDatasCount() > 0) { - hash = (37 * hash) + SERVICE_DATAS_FIELD_NUMBER; - hash = (53 * hash) + getServiceDatasList().hashCode(); - } - if (getServiceUuidsCount() > 0) { - hash = (37 * hash) + SERVICE_UUIDS_FIELD_NUMBER; - hash = (53 * hash) + getServiceUuidsList().hashCode(); - } - if (getSolicitedServiceUuidsCount() > 0) { - hash = (37 * hash) + SOLICITED_SERVICE_UUIDS_FIELD_NUMBER; - hash = (53 * hash) + getSolicitedServiceUuidsList().hashCode(); - } - if (hasTxPowerLevel()) { - hash = (37 * hash) + TX_POWER_LEVEL_FIELD_NUMBER; - hash = (53 * hash) + getTxPowerLevel(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(dev.yanshouwang.bluetooth_low_energy.proto.Broadcast prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code proto.Broadcast} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:proto.Broadcast) - dev.yanshouwang.bluetooth_low_energy.proto.BroadcastOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Broadcast_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Broadcast_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.class, dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.Builder.class); - } - - // Construct using dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - getServiceDatasFieldBuilder(); - getServiceUuidsFieldBuilder(); - getSolicitedServiceUuidsFieldBuilder(); - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - if (peripheralBuilder_ == null) { - peripheral_ = null; - } else { - peripheral_ = null; - peripheralBuilder_ = null; - } - rssi_ = 0; - - connectable_ = false; - bitField0_ = (bitField0_ & ~0x00000001); - data_ = com.google.protobuf.ByteString.EMPTY; - - localName_ = ""; - bitField0_ = (bitField0_ & ~0x00000002); - manufacturerSpecificData_ = com.google.protobuf.ByteString.EMPTY; - - if (serviceDatasBuilder_ == null) { - serviceDatas_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000004); - } else { - serviceDatasBuilder_.clear(); - } - if (serviceUuidsBuilder_ == null) { - serviceUuids_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000008); - } else { - serviceUuidsBuilder_.clear(); - } - if (solicitedServiceUuidsBuilder_ == null) { - solicitedServiceUuids_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000010); - } else { - solicitedServiceUuidsBuilder_.clear(); - } - txPowerLevel_ = 0; - bitField0_ = (bitField0_ & ~0x00000020); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Broadcast_descriptor; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Broadcast getDefaultInstanceForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.getDefaultInstance(); - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Broadcast build() { - dev.yanshouwang.bluetooth_low_energy.proto.Broadcast result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Broadcast buildPartial() { - dev.yanshouwang.bluetooth_low_energy.proto.Broadcast result = new dev.yanshouwang.bluetooth_low_energy.proto.Broadcast(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (peripheralBuilder_ == null) { - result.peripheral_ = peripheral_; - } else { - result.peripheral_ = peripheralBuilder_.build(); - } - result.rssi_ = rssi_; - if (((from_bitField0_ & 0x00000001) != 0)) { - result.connectable_ = connectable_; - to_bitField0_ |= 0x00000001; - } - result.data_ = data_; - if (((from_bitField0_ & 0x00000002) != 0)) { - to_bitField0_ |= 0x00000002; - } - result.localName_ = localName_; - result.manufacturerSpecificData_ = manufacturerSpecificData_; - if (serviceDatasBuilder_ == null) { - if (((bitField0_ & 0x00000004) != 0)) { - serviceDatas_ = java.util.Collections.unmodifiableList(serviceDatas_); - bitField0_ = (bitField0_ & ~0x00000004); - } - result.serviceDatas_ = serviceDatas_; - } else { - result.serviceDatas_ = serviceDatasBuilder_.build(); - } - if (serviceUuidsBuilder_ == null) { - if (((bitField0_ & 0x00000008) != 0)) { - serviceUuids_ = java.util.Collections.unmodifiableList(serviceUuids_); - bitField0_ = (bitField0_ & ~0x00000008); - } - result.serviceUuids_ = serviceUuids_; - } else { - result.serviceUuids_ = serviceUuidsBuilder_.build(); - } - if (solicitedServiceUuidsBuilder_ == null) { - if (((bitField0_ & 0x00000010) != 0)) { - solicitedServiceUuids_ = java.util.Collections.unmodifiableList(solicitedServiceUuids_); - bitField0_ = (bitField0_ & ~0x00000010); - } - result.solicitedServiceUuids_ = solicitedServiceUuids_; - } else { - result.solicitedServiceUuids_ = solicitedServiceUuidsBuilder_.build(); - } - if (((from_bitField0_ & 0x00000020) != 0)) { - result.txPowerLevel_ = txPowerLevel_; - to_bitField0_ |= 0x00000004; - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof dev.yanshouwang.bluetooth_low_energy.proto.Broadcast) { - return mergeFrom((dev.yanshouwang.bluetooth_low_energy.proto.Broadcast)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(dev.yanshouwang.bluetooth_low_energy.proto.Broadcast other) { - if (other == dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.getDefaultInstance()) return this; - if (other.hasPeripheral()) { - mergePeripheral(other.getPeripheral()); - } - if (other.getRssi() != 0) { - setRssi(other.getRssi()); - } - if (other.hasConnectable()) { - setConnectable(other.getConnectable()); - } - if (other.getData() != com.google.protobuf.ByteString.EMPTY) { - setData(other.getData()); - } - if (other.hasLocalName()) { - bitField0_ |= 0x00000002; - localName_ = other.localName_; - onChanged(); - } - if (other.getManufacturerSpecificData() != com.google.protobuf.ByteString.EMPTY) { - setManufacturerSpecificData(other.getManufacturerSpecificData()); - } - if (serviceDatasBuilder_ == null) { - if (!other.serviceDatas_.isEmpty()) { - if (serviceDatas_.isEmpty()) { - serviceDatas_ = other.serviceDatas_; - bitField0_ = (bitField0_ & ~0x00000004); - } else { - ensureServiceDatasIsMutable(); - serviceDatas_.addAll(other.serviceDatas_); - } - onChanged(); - } - } else { - if (!other.serviceDatas_.isEmpty()) { - if (serviceDatasBuilder_.isEmpty()) { - serviceDatasBuilder_.dispose(); - serviceDatasBuilder_ = null; - serviceDatas_ = other.serviceDatas_; - bitField0_ = (bitField0_ & ~0x00000004); - serviceDatasBuilder_ = - com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? - getServiceDatasFieldBuilder() : null; - } else { - serviceDatasBuilder_.addAllMessages(other.serviceDatas_); - } - } - } - if (serviceUuidsBuilder_ == null) { - if (!other.serviceUuids_.isEmpty()) { - if (serviceUuids_.isEmpty()) { - serviceUuids_ = other.serviceUuids_; - bitField0_ = (bitField0_ & ~0x00000008); - } else { - ensureServiceUuidsIsMutable(); - serviceUuids_.addAll(other.serviceUuids_); - } - onChanged(); - } - } else { - if (!other.serviceUuids_.isEmpty()) { - if (serviceUuidsBuilder_.isEmpty()) { - serviceUuidsBuilder_.dispose(); - serviceUuidsBuilder_ = null; - serviceUuids_ = other.serviceUuids_; - bitField0_ = (bitField0_ & ~0x00000008); - serviceUuidsBuilder_ = - com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? - getServiceUuidsFieldBuilder() : null; - } else { - serviceUuidsBuilder_.addAllMessages(other.serviceUuids_); - } - } - } - if (solicitedServiceUuidsBuilder_ == null) { - if (!other.solicitedServiceUuids_.isEmpty()) { - if (solicitedServiceUuids_.isEmpty()) { - solicitedServiceUuids_ = other.solicitedServiceUuids_; - bitField0_ = (bitField0_ & ~0x00000010); - } else { - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.addAll(other.solicitedServiceUuids_); - } - onChanged(); - } - } else { - if (!other.solicitedServiceUuids_.isEmpty()) { - if (solicitedServiceUuidsBuilder_.isEmpty()) { - solicitedServiceUuidsBuilder_.dispose(); - solicitedServiceUuidsBuilder_ = null; - solicitedServiceUuids_ = other.solicitedServiceUuids_; - bitField0_ = (bitField0_ & ~0x00000010); - solicitedServiceUuidsBuilder_ = - com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? - getSolicitedServiceUuidsFieldBuilder() : null; - } else { - solicitedServiceUuidsBuilder_.addAllMessages(other.solicitedServiceUuids_); - } - } - } - if (other.hasTxPowerLevel()) { - setTxPowerLevel(other.getTxPowerLevel()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - dev.yanshouwang.bluetooth_low_energy.proto.Broadcast parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (dev.yanshouwang.bluetooth_low_energy.proto.Broadcast) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private dev.yanshouwang.bluetooth_low_energy.proto.Peripheral peripheral_; - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral, dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder, dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder> peripheralBuilder_; - /** - * .proto.Peripheral peripheral = 1; - * @return Whether the peripheral field is set. - */ - public boolean hasPeripheral() { - return peripheralBuilder_ != null || peripheral_ != null; - } - /** - * .proto.Peripheral peripheral = 1; - * @return The peripheral. - */ - public dev.yanshouwang.bluetooth_low_energy.proto.Peripheral getPeripheral() { - if (peripheralBuilder_ == null) { - return peripheral_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.getDefaultInstance() : peripheral_; - } else { - return peripheralBuilder_.getMessage(); - } - } - /** - * .proto.Peripheral peripheral = 1; - */ - public Builder setPeripheral(dev.yanshouwang.bluetooth_low_energy.proto.Peripheral value) { - if (peripheralBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - peripheral_ = value; - onChanged(); - } else { - peripheralBuilder_.setMessage(value); - } - - return this; - } - /** - * .proto.Peripheral peripheral = 1; - */ - public Builder setPeripheral( - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder builderForValue) { - if (peripheralBuilder_ == null) { - peripheral_ = builderForValue.build(); - onChanged(); - } else { - peripheralBuilder_.setMessage(builderForValue.build()); - } - - return this; - } - /** - * .proto.Peripheral peripheral = 1; - */ - public Builder mergePeripheral(dev.yanshouwang.bluetooth_low_energy.proto.Peripheral value) { - if (peripheralBuilder_ == null) { - if (peripheral_ != null) { - peripheral_ = - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.newBuilder(peripheral_).mergeFrom(value).buildPartial(); - } else { - peripheral_ = value; - } - onChanged(); - } else { - peripheralBuilder_.mergeFrom(value); - } - - return this; - } - /** - * .proto.Peripheral peripheral = 1; - */ - public Builder clearPeripheral() { - if (peripheralBuilder_ == null) { - peripheral_ = null; - onChanged(); - } else { - peripheral_ = null; - peripheralBuilder_ = null; - } - - return this; - } - /** - * .proto.Peripheral peripheral = 1; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder getPeripheralBuilder() { - - onChanged(); - return getPeripheralFieldBuilder().getBuilder(); - } - /** - * .proto.Peripheral peripheral = 1; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder getPeripheralOrBuilder() { - if (peripheralBuilder_ != null) { - return peripheralBuilder_.getMessageOrBuilder(); - } else { - return peripheral_ == null ? - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.getDefaultInstance() : peripheral_; - } - } - /** - * .proto.Peripheral peripheral = 1; - */ - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral, dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder, dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder> - getPeripheralFieldBuilder() { - if (peripheralBuilder_ == null) { - peripheralBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral, dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder, dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder>( - getPeripheral(), - getParentForChildren(), - isClean()); - peripheral_ = null; - } - return peripheralBuilder_; - } - - private int rssi_ ; - /** - * int32 rssi = 2; - * @return The rssi. - */ - @java.lang.Override - public int getRssi() { - return rssi_; - } - /** - * int32 rssi = 2; - * @param value The rssi to set. - * @return This builder for chaining. - */ - public Builder setRssi(int value) { - - rssi_ = value; - onChanged(); - return this; - } - /** - * int32 rssi = 2; - * @return This builder for chaining. - */ - public Builder clearRssi() { - - rssi_ = 0; - onChanged(); - return this; - } - - private boolean connectable_ ; - /** - * optional bool connectable = 3; - * @return Whether the connectable field is set. - */ - @java.lang.Override - public boolean hasConnectable() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * optional bool connectable = 3; - * @return The connectable. - */ - @java.lang.Override - public boolean getConnectable() { - return connectable_; - } - /** - * optional bool connectable = 3; - * @param value The connectable to set. - * @return This builder for chaining. - */ - public Builder setConnectable(boolean value) { - bitField0_ |= 0x00000001; - connectable_ = value; - onChanged(); - return this; - } - /** - * optional bool connectable = 3; - * @return This builder for chaining. - */ - public Builder clearConnectable() { - bitField0_ = (bitField0_ & ~0x00000001); - connectable_ = false; - onChanged(); - return this; - } - - private com.google.protobuf.ByteString data_ = com.google.protobuf.ByteString.EMPTY; - /** - * bytes data = 4; - * @return The data. - */ - @java.lang.Override - public com.google.protobuf.ByteString getData() { - return data_; - } - /** - * bytes data = 4; - * @param value The data to set. - * @return This builder for chaining. - */ - public Builder setData(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - - data_ = value; - onChanged(); - return this; - } - /** - * bytes data = 4; - * @return This builder for chaining. - */ - public Builder clearData() { - - data_ = getDefaultInstance().getData(); - onChanged(); - return this; - } - - private java.lang.Object localName_ = ""; - /** - * optional string local_name = 5; - * @return Whether the localName field is set. - */ - public boolean hasLocalName() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * optional string local_name = 5; - * @return The localName. - */ - public java.lang.String getLocalName() { - java.lang.Object ref = localName_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - localName_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string local_name = 5; - * @return The bytes for localName. - */ - public com.google.protobuf.ByteString - getLocalNameBytes() { - java.lang.Object ref = localName_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - localName_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string local_name = 5; - * @param value The localName to set. - * @return This builder for chaining. - */ - public Builder setLocalName( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - localName_ = value; - onChanged(); - return this; - } - /** - * optional string local_name = 5; - * @return This builder for chaining. - */ - public Builder clearLocalName() { - bitField0_ = (bitField0_ & ~0x00000002); - localName_ = getDefaultInstance().getLocalName(); - onChanged(); - return this; - } - /** - * optional string local_name = 5; - * @param value The bytes for localName to set. - * @return This builder for chaining. - */ - public Builder setLocalNameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - bitField0_ |= 0x00000002; - localName_ = value; - onChanged(); - return this; - } - - private com.google.protobuf.ByteString manufacturerSpecificData_ = com.google.protobuf.ByteString.EMPTY; - /** - * bytes manufacturer_specific_data = 6; - * @return The manufacturerSpecificData. - */ - @java.lang.Override - public com.google.protobuf.ByteString getManufacturerSpecificData() { - return manufacturerSpecificData_; - } - /** - * bytes manufacturer_specific_data = 6; - * @param value The manufacturerSpecificData to set. - * @return This builder for chaining. - */ - public Builder setManufacturerSpecificData(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - - manufacturerSpecificData_ = value; - onChanged(); - return this; - } - /** - * bytes manufacturer_specific_data = 6; - * @return This builder for chaining. - */ - public Builder clearManufacturerSpecificData() { - - manufacturerSpecificData_ = getDefaultInstance().getManufacturerSpecificData(); - onChanged(); - return this; - } - - private java.util.List serviceDatas_ = - java.util.Collections.emptyList(); - private void ensureServiceDatasIsMutable() { - if (!((bitField0_ & 0x00000004) != 0)) { - serviceDatas_ = new java.util.ArrayList(serviceDatas_); - bitField0_ |= 0x00000004; - } - } - - private com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder, dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder> serviceDatasBuilder_; - - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public java.util.List getServiceDatasList() { - if (serviceDatasBuilder_ == null) { - return java.util.Collections.unmodifiableList(serviceDatas_); - } else { - return serviceDatasBuilder_.getMessageList(); - } - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public int getServiceDatasCount() { - if (serviceDatasBuilder_ == null) { - return serviceDatas_.size(); - } else { - return serviceDatasBuilder_.getCount(); - } - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData getServiceDatas(int index) { - if (serviceDatasBuilder_ == null) { - return serviceDatas_.get(index); - } else { - return serviceDatasBuilder_.getMessage(index); - } - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder setServiceDatas( - int index, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData value) { - if (serviceDatasBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureServiceDatasIsMutable(); - serviceDatas_.set(index, value); - onChanged(); - } else { - serviceDatasBuilder_.setMessage(index, value); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder setServiceDatas( - int index, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder builderForValue) { - if (serviceDatasBuilder_ == null) { - ensureServiceDatasIsMutable(); - serviceDatas_.set(index, builderForValue.build()); - onChanged(); - } else { - serviceDatasBuilder_.setMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder addServiceDatas(dev.yanshouwang.bluetooth_low_energy.proto.ServiceData value) { - if (serviceDatasBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureServiceDatasIsMutable(); - serviceDatas_.add(value); - onChanged(); - } else { - serviceDatasBuilder_.addMessage(value); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder addServiceDatas( - int index, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData value) { - if (serviceDatasBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureServiceDatasIsMutable(); - serviceDatas_.add(index, value); - onChanged(); - } else { - serviceDatasBuilder_.addMessage(index, value); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder addServiceDatas( - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder builderForValue) { - if (serviceDatasBuilder_ == null) { - ensureServiceDatasIsMutable(); - serviceDatas_.add(builderForValue.build()); - onChanged(); - } else { - serviceDatasBuilder_.addMessage(builderForValue.build()); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder addServiceDatas( - int index, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder builderForValue) { - if (serviceDatasBuilder_ == null) { - ensureServiceDatasIsMutable(); - serviceDatas_.add(index, builderForValue.build()); - onChanged(); - } else { - serviceDatasBuilder_.addMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder addAllServiceDatas( - java.lang.Iterable values) { - if (serviceDatasBuilder_ == null) { - ensureServiceDatasIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, serviceDatas_); - onChanged(); - } else { - serviceDatasBuilder_.addAllMessages(values); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder clearServiceDatas() { - if (serviceDatasBuilder_ == null) { - serviceDatas_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000004); - onChanged(); - } else { - serviceDatasBuilder_.clear(); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public Builder removeServiceDatas(int index) { - if (serviceDatasBuilder_ == null) { - ensureServiceDatasIsMutable(); - serviceDatas_.remove(index); - onChanged(); - } else { - serviceDatasBuilder_.remove(index); - } - return this; - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder getServiceDatasBuilder( - int index) { - return getServiceDatasFieldBuilder().getBuilder(index); - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder getServiceDatasOrBuilder( - int index) { - if (serviceDatasBuilder_ == null) { - return serviceDatas_.get(index); } else { - return serviceDatasBuilder_.getMessageOrBuilder(index); - } - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public java.util.List - getServiceDatasOrBuilderList() { - if (serviceDatasBuilder_ != null) { - return serviceDatasBuilder_.getMessageOrBuilderList(); - } else { - return java.util.Collections.unmodifiableList(serviceDatas_); - } - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder addServiceDatasBuilder() { - return getServiceDatasFieldBuilder().addBuilder( - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.getDefaultInstance()); - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder addServiceDatasBuilder( - int index) { - return getServiceDatasFieldBuilder().addBuilder( - index, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.getDefaultInstance()); - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - public java.util.List - getServiceDatasBuilderList() { - return getServiceDatasFieldBuilder().getBuilderList(); - } - private com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder, dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder> - getServiceDatasFieldBuilder() { - if (serviceDatasBuilder_ == null) { - serviceDatasBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder, dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder>( - serviceDatas_, - ((bitField0_ & 0x00000004) != 0), - getParentForChildren(), - isClean()); - serviceDatas_ = null; - } - return serviceDatasBuilder_; - } - - private java.util.List serviceUuids_ = - java.util.Collections.emptyList(); - private void ensureServiceUuidsIsMutable() { - if (!((bitField0_ & 0x00000008) != 0)) { - serviceUuids_ = new java.util.ArrayList(serviceUuids_); - bitField0_ |= 0x00000008; - } - } - - private com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> serviceUuidsBuilder_; - - /** - * repeated .proto.UUID service_uuids = 8; - */ - public java.util.List getServiceUuidsList() { - if (serviceUuidsBuilder_ == null) { - return java.util.Collections.unmodifiableList(serviceUuids_); - } else { - return serviceUuidsBuilder_.getMessageList(); - } - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public int getServiceUuidsCount() { - if (serviceUuidsBuilder_ == null) { - return serviceUuids_.size(); - } else { - return serviceUuidsBuilder_.getCount(); - } - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getServiceUuids(int index) { - if (serviceUuidsBuilder_ == null) { - return serviceUuids_.get(index); - } else { - return serviceUuidsBuilder_.getMessage(index); - } - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder setServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (serviceUuidsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureServiceUuidsIsMutable(); - serviceUuids_.set(index, value); - onChanged(); - } else { - serviceUuidsBuilder_.setMessage(index, value); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder setServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (serviceUuidsBuilder_ == null) { - ensureServiceUuidsIsMutable(); - serviceUuids_.set(index, builderForValue.build()); - onChanged(); - } else { - serviceUuidsBuilder_.setMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder addServiceUuids(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (serviceUuidsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureServiceUuidsIsMutable(); - serviceUuids_.add(value); - onChanged(); - } else { - serviceUuidsBuilder_.addMessage(value); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder addServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (serviceUuidsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureServiceUuidsIsMutable(); - serviceUuids_.add(index, value); - onChanged(); - } else { - serviceUuidsBuilder_.addMessage(index, value); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder addServiceUuids( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (serviceUuidsBuilder_ == null) { - ensureServiceUuidsIsMutable(); - serviceUuids_.add(builderForValue.build()); - onChanged(); - } else { - serviceUuidsBuilder_.addMessage(builderForValue.build()); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder addServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (serviceUuidsBuilder_ == null) { - ensureServiceUuidsIsMutable(); - serviceUuids_.add(index, builderForValue.build()); - onChanged(); - } else { - serviceUuidsBuilder_.addMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder addAllServiceUuids( - java.lang.Iterable values) { - if (serviceUuidsBuilder_ == null) { - ensureServiceUuidsIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, serviceUuids_); - onChanged(); - } else { - serviceUuidsBuilder_.addAllMessages(values); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder clearServiceUuids() { - if (serviceUuidsBuilder_ == null) { - serviceUuids_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000008); - onChanged(); - } else { - serviceUuidsBuilder_.clear(); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public Builder removeServiceUuids(int index) { - if (serviceUuidsBuilder_ == null) { - ensureServiceUuidsIsMutable(); - serviceUuids_.remove(index); - onChanged(); - } else { - serviceUuidsBuilder_.remove(index); - } - return this; - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder getServiceUuidsBuilder( - int index) { - return getServiceUuidsFieldBuilder().getBuilder(index); - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getServiceUuidsOrBuilder( - int index) { - if (serviceUuidsBuilder_ == null) { - return serviceUuids_.get(index); } else { - return serviceUuidsBuilder_.getMessageOrBuilder(index); - } - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public java.util.List - getServiceUuidsOrBuilderList() { - if (serviceUuidsBuilder_ != null) { - return serviceUuidsBuilder_.getMessageOrBuilderList(); - } else { - return java.util.Collections.unmodifiableList(serviceUuids_); - } - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder addServiceUuidsBuilder() { - return getServiceUuidsFieldBuilder().addBuilder( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance()); - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder addServiceUuidsBuilder( - int index) { - return getServiceUuidsFieldBuilder().addBuilder( - index, dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance()); - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - public java.util.List - getServiceUuidsBuilderList() { - return getServiceUuidsFieldBuilder().getBuilderList(); - } - private com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> - getServiceUuidsFieldBuilder() { - if (serviceUuidsBuilder_ == null) { - serviceUuidsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder>( - serviceUuids_, - ((bitField0_ & 0x00000008) != 0), - getParentForChildren(), - isClean()); - serviceUuids_ = null; - } - return serviceUuidsBuilder_; - } - - private java.util.List solicitedServiceUuids_ = - java.util.Collections.emptyList(); - private void ensureSolicitedServiceUuidsIsMutable() { - if (!((bitField0_ & 0x00000010) != 0)) { - solicitedServiceUuids_ = new java.util.ArrayList(solicitedServiceUuids_); - bitField0_ |= 0x00000010; - } - } - - private com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> solicitedServiceUuidsBuilder_; - - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public java.util.List getSolicitedServiceUuidsList() { - if (solicitedServiceUuidsBuilder_ == null) { - return java.util.Collections.unmodifiableList(solicitedServiceUuids_); - } else { - return solicitedServiceUuidsBuilder_.getMessageList(); - } - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public int getSolicitedServiceUuidsCount() { - if (solicitedServiceUuidsBuilder_ == null) { - return solicitedServiceUuids_.size(); - } else { - return solicitedServiceUuidsBuilder_.getCount(); - } - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getSolicitedServiceUuids(int index) { - if (solicitedServiceUuidsBuilder_ == null) { - return solicitedServiceUuids_.get(index); - } else { - return solicitedServiceUuidsBuilder_.getMessage(index); - } - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder setSolicitedServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (solicitedServiceUuidsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.set(index, value); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.setMessage(index, value); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder setSolicitedServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (solicitedServiceUuidsBuilder_ == null) { - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.set(index, builderForValue.build()); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.setMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder addSolicitedServiceUuids(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (solicitedServiceUuidsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.add(value); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.addMessage(value); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder addSolicitedServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (solicitedServiceUuidsBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.add(index, value); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.addMessage(index, value); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder addSolicitedServiceUuids( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (solicitedServiceUuidsBuilder_ == null) { - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.add(builderForValue.build()); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.addMessage(builderForValue.build()); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder addSolicitedServiceUuids( - int index, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (solicitedServiceUuidsBuilder_ == null) { - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.add(index, builderForValue.build()); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.addMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder addAllSolicitedServiceUuids( - java.lang.Iterable values) { - if (solicitedServiceUuidsBuilder_ == null) { - ensureSolicitedServiceUuidsIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, solicitedServiceUuids_); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.addAllMessages(values); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder clearSolicitedServiceUuids() { - if (solicitedServiceUuidsBuilder_ == null) { - solicitedServiceUuids_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000010); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.clear(); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public Builder removeSolicitedServiceUuids(int index) { - if (solicitedServiceUuidsBuilder_ == null) { - ensureSolicitedServiceUuidsIsMutable(); - solicitedServiceUuids_.remove(index); - onChanged(); - } else { - solicitedServiceUuidsBuilder_.remove(index); - } - return this; - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder getSolicitedServiceUuidsBuilder( - int index) { - return getSolicitedServiceUuidsFieldBuilder().getBuilder(index); - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getSolicitedServiceUuidsOrBuilder( - int index) { - if (solicitedServiceUuidsBuilder_ == null) { - return solicitedServiceUuids_.get(index); } else { - return solicitedServiceUuidsBuilder_.getMessageOrBuilder(index); - } - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public java.util.List - getSolicitedServiceUuidsOrBuilderList() { - if (solicitedServiceUuidsBuilder_ != null) { - return solicitedServiceUuidsBuilder_.getMessageOrBuilderList(); - } else { - return java.util.Collections.unmodifiableList(solicitedServiceUuids_); - } - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder addSolicitedServiceUuidsBuilder() { - return getSolicitedServiceUuidsFieldBuilder().addBuilder( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance()); - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder addSolicitedServiceUuidsBuilder( - int index) { - return getSolicitedServiceUuidsFieldBuilder().addBuilder( - index, dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance()); - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - public java.util.List - getSolicitedServiceUuidsBuilderList() { - return getSolicitedServiceUuidsFieldBuilder().getBuilderList(); - } - private com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> - getSolicitedServiceUuidsFieldBuilder() { - if (solicitedServiceUuidsBuilder_ == null) { - solicitedServiceUuidsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder>( - solicitedServiceUuids_, - ((bitField0_ & 0x00000010) != 0), - getParentForChildren(), - isClean()); - solicitedServiceUuids_ = null; - } - return solicitedServiceUuidsBuilder_; - } - - private int txPowerLevel_ ; - /** - * optional int32 tx_power_level = 10; - * @return Whether the txPowerLevel field is set. - */ - @java.lang.Override - public boolean hasTxPowerLevel() { - return ((bitField0_ & 0x00000020) != 0); - } - /** - * optional int32 tx_power_level = 10; - * @return The txPowerLevel. - */ - @java.lang.Override - public int getTxPowerLevel() { - return txPowerLevel_; - } - /** - * optional int32 tx_power_level = 10; - * @param value The txPowerLevel to set. - * @return This builder for chaining. - */ - public Builder setTxPowerLevel(int value) { - bitField0_ |= 0x00000020; - txPowerLevel_ = value; - onChanged(); - return this; - } - /** - * optional int32 tx_power_level = 10; - * @return This builder for chaining. - */ - public Builder clearTxPowerLevel() { - bitField0_ = (bitField0_ & ~0x00000020); - txPowerLevel_ = 0; - onChanged(); - return this; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:proto.Broadcast) - } - - // @@protoc_insertion_point(class_scope:proto.Broadcast) - private static final dev.yanshouwang.bluetooth_low_energy.proto.Broadcast DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new dev.yanshouwang.bluetooth_low_energy.proto.Broadcast(); - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.Broadcast getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Broadcast parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Broadcast(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Broadcast getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastOrBuilder.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastOrBuilder.java deleted file mode 100644 index 771f6cf..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastOrBuilder.java +++ /dev/null @@ -1,153 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public interface BroadcastOrBuilder extends - // @@protoc_insertion_point(interface_extends:proto.Broadcast) - com.google.protobuf.MessageOrBuilder { - - /** - * .proto.Peripheral peripheral = 1; - * @return Whether the peripheral field is set. - */ - boolean hasPeripheral(); - /** - * .proto.Peripheral peripheral = 1; - * @return The peripheral. - */ - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral getPeripheral(); - /** - * .proto.Peripheral peripheral = 1; - */ - dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder getPeripheralOrBuilder(); - - /** - * int32 rssi = 2; - * @return The rssi. - */ - int getRssi(); - - /** - * optional bool connectable = 3; - * @return Whether the connectable field is set. - */ - boolean hasConnectable(); - /** - * optional bool connectable = 3; - * @return The connectable. - */ - boolean getConnectable(); - - /** - * bytes data = 4; - * @return The data. - */ - com.google.protobuf.ByteString getData(); - - /** - * optional string local_name = 5; - * @return Whether the localName field is set. - */ - boolean hasLocalName(); - /** - * optional string local_name = 5; - * @return The localName. - */ - java.lang.String getLocalName(); - /** - * optional string local_name = 5; - * @return The bytes for localName. - */ - com.google.protobuf.ByteString - getLocalNameBytes(); - - /** - * bytes manufacturer_specific_data = 6; - * @return The manufacturerSpecificData. - */ - com.google.protobuf.ByteString getManufacturerSpecificData(); - - /** - * repeated .proto.ServiceData service_datas = 7; - */ - java.util.List - getServiceDatasList(); - /** - * repeated .proto.ServiceData service_datas = 7; - */ - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData getServiceDatas(int index); - /** - * repeated .proto.ServiceData service_datas = 7; - */ - int getServiceDatasCount(); - /** - * repeated .proto.ServiceData service_datas = 7; - */ - java.util.List - getServiceDatasOrBuilderList(); - /** - * repeated .proto.ServiceData service_datas = 7; - */ - dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder getServiceDatasOrBuilder( - int index); - - /** - * repeated .proto.UUID service_uuids = 8; - */ - java.util.List - getServiceUuidsList(); - /** - * repeated .proto.UUID service_uuids = 8; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUID getServiceUuids(int index); - /** - * repeated .proto.UUID service_uuids = 8; - */ - int getServiceUuidsCount(); - /** - * repeated .proto.UUID service_uuids = 8; - */ - java.util.List - getServiceUuidsOrBuilderList(); - /** - * repeated .proto.UUID service_uuids = 8; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getServiceUuidsOrBuilder( - int index); - - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - java.util.List - getSolicitedServiceUuidsList(); - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUID getSolicitedServiceUuids(int index); - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - int getSolicitedServiceUuidsCount(); - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - java.util.List - getSolicitedServiceUuidsOrBuilderList(); - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getSolicitedServiceUuidsOrBuilder( - int index); - - /** - * optional int32 tx_power_level = 10; - * @return Whether the txPowerLevel field is set. - */ - boolean hasTxPowerLevel(); - /** - * optional int32 tx_power_level = 10; - * @return The txPowerLevel. - */ - int getTxPowerLevel(); -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristic.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristic.java deleted file mode 100644 index ceb6561..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristic.java +++ /dev/null @@ -1,1007 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf type {@code proto.GattCharacteristic} - */ -public final class GattCharacteristic extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:proto.GattCharacteristic) - GattCharacteristicOrBuilder { -private static final long serialVersionUID = 0L; - // Use GattCharacteristic.newBuilder() to construct. - private GattCharacteristic(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private GattCharacteristic() { - id_ = ""; - } - - @java.lang.Override - @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new GattCharacteristic(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private GattCharacteristic( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - java.lang.String s = input.readStringRequireUtf8(); - - id_ = s; - break; - } - case 18: { - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder subBuilder = null; - if (uuid_ != null) { - subBuilder = uuid_.toBuilder(); - } - uuid_ = input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.UUID.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(uuid_); - uuid_ = subBuilder.buildPartial(); - } - - break; - } - case 24: { - - canRead_ = input.readBool(); - break; - } - case 32: { - - canWrite_ = input.readBool(); - break; - } - case 40: { - - canWriteWithoutResponse_ = input.readBool(); - break; - } - case 48: { - - canNotify_ = input.readBool(); - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattCharacteristic_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattCharacteristic_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.class, dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.Builder.class); - } - - public static final int ID_FIELD_NUMBER = 1; - private volatile java.lang.Object id_; - /** - * string id = 1; - * @return The id. - */ - @java.lang.Override - public java.lang.String getId() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int UUID_FIELD_NUMBER = 2; - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - @java.lang.Override - public boolean hasUuid() { - return uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - /** - * .proto.UUID uuid = 2; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - return getUuid(); - } - - public static final int CAN_READ_FIELD_NUMBER = 3; - private boolean canRead_; - /** - * bool can_read = 3; - * @return The canRead. - */ - @java.lang.Override - public boolean getCanRead() { - return canRead_; - } - - public static final int CAN_WRITE_FIELD_NUMBER = 4; - private boolean canWrite_; - /** - * bool can_write = 4; - * @return The canWrite. - */ - @java.lang.Override - public boolean getCanWrite() { - return canWrite_; - } - - public static final int CAN_WRITE_WITHOUT_RESPONSE_FIELD_NUMBER = 5; - private boolean canWriteWithoutResponse_; - /** - * bool can_write_without_response = 5; - * @return The canWriteWithoutResponse. - */ - @java.lang.Override - public boolean getCanWriteWithoutResponse() { - return canWriteWithoutResponse_; - } - - public static final int CAN_NOTIFY_FIELD_NUMBER = 6; - private boolean canNotify_; - /** - * bool can_notify = 6; - * @return The canNotify. - */ - @java.lang.Override - public boolean getCanNotify() { - return canNotify_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (uuid_ != null) { - output.writeMessage(2, getUuid()); - } - if (canRead_ != false) { - output.writeBool(3, canRead_); - } - if (canWrite_ != false) { - output.writeBool(4, canWrite_); - } - if (canWriteWithoutResponse_ != false) { - output.writeBool(5, canWriteWithoutResponse_); - } - if (canNotify_ != false) { - output.writeBool(6, canNotify_); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (uuid_ != null) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getUuid()); - } - if (canRead_ != false) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(3, canRead_); - } - if (canWrite_ != false) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(4, canWrite_); - } - if (canWriteWithoutResponse_ != false) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(5, canWriteWithoutResponse_); - } - if (canNotify_ != false) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(6, canNotify_); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic)) { - return super.equals(obj); - } - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic other = (dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic) obj; - - if (!getId() - .equals(other.getId())) return false; - if (hasUuid() != other.hasUuid()) return false; - if (hasUuid()) { - if (!getUuid() - .equals(other.getUuid())) return false; - } - if (getCanRead() - != other.getCanRead()) return false; - if (getCanWrite() - != other.getCanWrite()) return false; - if (getCanWriteWithoutResponse() - != other.getCanWriteWithoutResponse()) return false; - if (getCanNotify() - != other.getCanNotify()) return false; - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - if (hasUuid()) { - hash = (37 * hash) + UUID_FIELD_NUMBER; - hash = (53 * hash) + getUuid().hashCode(); - } - hash = (37 * hash) + CAN_READ_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( - getCanRead()); - hash = (37 * hash) + CAN_WRITE_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( - getCanWrite()); - hash = (37 * hash) + CAN_WRITE_WITHOUT_RESPONSE_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( - getCanWriteWithoutResponse()); - hash = (37 * hash) + CAN_NOTIFY_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( - getCanNotify()); - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code proto.GattCharacteristic} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:proto.GattCharacteristic) - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristicOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattCharacteristic_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattCharacteristic_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.class, dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.Builder.class); - } - - // Construct using dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - id_ = ""; - - if (uuidBuilder_ == null) { - uuid_ = null; - } else { - uuid_ = null; - uuidBuilder_ = null; - } - canRead_ = false; - - canWrite_ = false; - - canWriteWithoutResponse_ = false; - - canNotify_ = false; - - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattCharacteristic_descriptor; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic getDefaultInstanceForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.getDefaultInstance(); - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic build() { - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic buildPartial() { - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic result = new dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic(this); - result.id_ = id_; - if (uuidBuilder_ == null) { - result.uuid_ = uuid_; - } else { - result.uuid_ = uuidBuilder_.build(); - } - result.canRead_ = canRead_; - result.canWrite_ = canWrite_; - result.canWriteWithoutResponse_ = canWriteWithoutResponse_; - result.canNotify_ = canNotify_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic) { - return mergeFrom((dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic other) { - if (other == dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.getDefaultInstance()) return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - onChanged(); - } - if (other.hasUuid()) { - mergeUuid(other.getUuid()); - } - if (other.getCanRead() != false) { - setCanRead(other.getCanRead()); - } - if (other.getCanWrite() != false) { - setCanWrite(other.getCanWrite()); - } - if (other.getCanWriteWithoutResponse() != false) { - setCanWriteWithoutResponse(other.getCanWriteWithoutResponse()); - } - if (other.getCanNotify() != false) { - setCanNotify(other.getCanNotify()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object id_ = ""; - /** - * string id = 1; - * @return The id. - */ - public java.lang.String getId() { - java.lang.Object ref = id_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string id = 1; - * @param value The id to set. - * @return This builder for chaining. - */ - public Builder setId( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - id_ = value; - onChanged(); - return this; - } - /** - * string id = 1; - * @return This builder for chaining. - */ - public Builder clearId() { - - id_ = getDefaultInstance().getId(); - onChanged(); - return this; - } - /** - * string id = 1; - * @param value The bytes for id to set. - * @return This builder for chaining. - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - id_ = value; - onChanged(); - return this; - } - - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> uuidBuilder_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - public boolean hasUuid() { - return uuidBuilder_ != null || uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - if (uuidBuilder_ == null) { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } else { - return uuidBuilder_.getMessage(); - } - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - uuid_ = value; - onChanged(); - } else { - uuidBuilder_.setMessage(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (uuidBuilder_ == null) { - uuid_ = builderForValue.build(); - onChanged(); - } else { - uuidBuilder_.setMessage(builderForValue.build()); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder mergeUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (uuid_ != null) { - uuid_ = - dev.yanshouwang.bluetooth_low_energy.proto.UUID.newBuilder(uuid_).mergeFrom(value).buildPartial(); - } else { - uuid_ = value; - } - onChanged(); - } else { - uuidBuilder_.mergeFrom(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder clearUuid() { - if (uuidBuilder_ == null) { - uuid_ = null; - onChanged(); - } else { - uuid_ = null; - uuidBuilder_ = null; - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder getUuidBuilder() { - - onChanged(); - return getUuidFieldBuilder().getBuilder(); - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - if (uuidBuilder_ != null) { - return uuidBuilder_.getMessageOrBuilder(); - } else { - return uuid_ == null ? - dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - } - /** - * .proto.UUID uuid = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> - getUuidFieldBuilder() { - if (uuidBuilder_ == null) { - uuidBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder>( - getUuid(), - getParentForChildren(), - isClean()); - uuid_ = null; - } - return uuidBuilder_; - } - - private boolean canRead_ ; - /** - * bool can_read = 3; - * @return The canRead. - */ - @java.lang.Override - public boolean getCanRead() { - return canRead_; - } - /** - * bool can_read = 3; - * @param value The canRead to set. - * @return This builder for chaining. - */ - public Builder setCanRead(boolean value) { - - canRead_ = value; - onChanged(); - return this; - } - /** - * bool can_read = 3; - * @return This builder for chaining. - */ - public Builder clearCanRead() { - - canRead_ = false; - onChanged(); - return this; - } - - private boolean canWrite_ ; - /** - * bool can_write = 4; - * @return The canWrite. - */ - @java.lang.Override - public boolean getCanWrite() { - return canWrite_; - } - /** - * bool can_write = 4; - * @param value The canWrite to set. - * @return This builder for chaining. - */ - public Builder setCanWrite(boolean value) { - - canWrite_ = value; - onChanged(); - return this; - } - /** - * bool can_write = 4; - * @return This builder for chaining. - */ - public Builder clearCanWrite() { - - canWrite_ = false; - onChanged(); - return this; - } - - private boolean canWriteWithoutResponse_ ; - /** - * bool can_write_without_response = 5; - * @return The canWriteWithoutResponse. - */ - @java.lang.Override - public boolean getCanWriteWithoutResponse() { - return canWriteWithoutResponse_; - } - /** - * bool can_write_without_response = 5; - * @param value The canWriteWithoutResponse to set. - * @return This builder for chaining. - */ - public Builder setCanWriteWithoutResponse(boolean value) { - - canWriteWithoutResponse_ = value; - onChanged(); - return this; - } - /** - * bool can_write_without_response = 5; - * @return This builder for chaining. - */ - public Builder clearCanWriteWithoutResponse() { - - canWriteWithoutResponse_ = false; - onChanged(); - return this; - } - - private boolean canNotify_ ; - /** - * bool can_notify = 6; - * @return The canNotify. - */ - @java.lang.Override - public boolean getCanNotify() { - return canNotify_; - } - /** - * bool can_notify = 6; - * @param value The canNotify to set. - * @return This builder for chaining. - */ - public Builder setCanNotify(boolean value) { - - canNotify_ = value; - onChanged(); - return this; - } - /** - * bool can_notify = 6; - * @return This builder for chaining. - */ - public Builder clearCanNotify() { - - canNotify_ = false; - onChanged(); - return this; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:proto.GattCharacteristic) - } - - // @@protoc_insertion_point(class_scope:proto.GattCharacteristic) - private static final dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic(); - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public GattCharacteristic parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new GattCharacteristic(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicOrBuilder.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicOrBuilder.java deleted file mode 100644 index 2b74a06..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicOrBuilder.java +++ /dev/null @@ -1,60 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public interface GattCharacteristicOrBuilder extends - // @@protoc_insertion_point(interface_extends:proto.GattCharacteristic) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - * @return The id. - */ - java.lang.String getId(); - /** - * string id = 1; - * @return The bytes for id. - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - boolean hasUuid(); - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid(); - /** - * .proto.UUID uuid = 2; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder(); - - /** - * bool can_read = 3; - * @return The canRead. - */ - boolean getCanRead(); - - /** - * bool can_write = 4; - * @return The canWrite. - */ - boolean getCanWrite(); - - /** - * bool can_write_without_response = 5; - * @return The canWriteWithoutResponse. - */ - boolean getCanWriteWithoutResponse(); - - /** - * bool can_notify = 6; - * @return The canNotify. - */ - boolean getCanNotify(); -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptor.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptor.java deleted file mode 100644 index 333194f..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptor.java +++ /dev/null @@ -1,747 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf type {@code proto.GattDescriptor} - */ -public final class GattDescriptor extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:proto.GattDescriptor) - GattDescriptorOrBuilder { -private static final long serialVersionUID = 0L; - // Use GattDescriptor.newBuilder() to construct. - private GattDescriptor(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private GattDescriptor() { - id_ = ""; - } - - @java.lang.Override - @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new GattDescriptor(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private GattDescriptor( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - java.lang.String s = input.readStringRequireUtf8(); - - id_ = s; - break; - } - case 18: { - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder subBuilder = null; - if (uuid_ != null) { - subBuilder = uuid_.toBuilder(); - } - uuid_ = input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.UUID.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(uuid_); - uuid_ = subBuilder.buildPartial(); - } - - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattDescriptor_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattDescriptor_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.class, dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.Builder.class); - } - - public static final int ID_FIELD_NUMBER = 1; - private volatile java.lang.Object id_; - /** - * string id = 1; - * @return The id. - */ - @java.lang.Override - public java.lang.String getId() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int UUID_FIELD_NUMBER = 2; - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - @java.lang.Override - public boolean hasUuid() { - return uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - /** - * .proto.UUID uuid = 2; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - return getUuid(); - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (uuid_ != null) { - output.writeMessage(2, getUuid()); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (uuid_ != null) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getUuid()); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor)) { - return super.equals(obj); - } - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor other = (dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor) obj; - - if (!getId() - .equals(other.getId())) return false; - if (hasUuid() != other.hasUuid()) return false; - if (hasUuid()) { - if (!getUuid() - .equals(other.getUuid())) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - if (hasUuid()) { - hash = (37 * hash) + UUID_FIELD_NUMBER; - hash = (53 * hash) + getUuid().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code proto.GattDescriptor} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:proto.GattDescriptor) - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptorOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattDescriptor_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattDescriptor_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.class, dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.Builder.class); - } - - // Construct using dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - id_ = ""; - - if (uuidBuilder_ == null) { - uuid_ = null; - } else { - uuid_ = null; - uuidBuilder_ = null; - } - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattDescriptor_descriptor; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor getDefaultInstanceForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.getDefaultInstance(); - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor build() { - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor buildPartial() { - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor result = new dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor(this); - result.id_ = id_; - if (uuidBuilder_ == null) { - result.uuid_ = uuid_; - } else { - result.uuid_ = uuidBuilder_.build(); - } - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor) { - return mergeFrom((dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor other) { - if (other == dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.getDefaultInstance()) return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - onChanged(); - } - if (other.hasUuid()) { - mergeUuid(other.getUuid()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object id_ = ""; - /** - * string id = 1; - * @return The id. - */ - public java.lang.String getId() { - java.lang.Object ref = id_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string id = 1; - * @param value The id to set. - * @return This builder for chaining. - */ - public Builder setId( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - id_ = value; - onChanged(); - return this; - } - /** - * string id = 1; - * @return This builder for chaining. - */ - public Builder clearId() { - - id_ = getDefaultInstance().getId(); - onChanged(); - return this; - } - /** - * string id = 1; - * @param value The bytes for id to set. - * @return This builder for chaining. - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - id_ = value; - onChanged(); - return this; - } - - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> uuidBuilder_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - public boolean hasUuid() { - return uuidBuilder_ != null || uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - if (uuidBuilder_ == null) { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } else { - return uuidBuilder_.getMessage(); - } - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - uuid_ = value; - onChanged(); - } else { - uuidBuilder_.setMessage(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (uuidBuilder_ == null) { - uuid_ = builderForValue.build(); - onChanged(); - } else { - uuidBuilder_.setMessage(builderForValue.build()); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder mergeUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (uuid_ != null) { - uuid_ = - dev.yanshouwang.bluetooth_low_energy.proto.UUID.newBuilder(uuid_).mergeFrom(value).buildPartial(); - } else { - uuid_ = value; - } - onChanged(); - } else { - uuidBuilder_.mergeFrom(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder clearUuid() { - if (uuidBuilder_ == null) { - uuid_ = null; - onChanged(); - } else { - uuid_ = null; - uuidBuilder_ = null; - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder getUuidBuilder() { - - onChanged(); - return getUuidFieldBuilder().getBuilder(); - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - if (uuidBuilder_ != null) { - return uuidBuilder_.getMessageOrBuilder(); - } else { - return uuid_ == null ? - dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - } - /** - * .proto.UUID uuid = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> - getUuidFieldBuilder() { - if (uuidBuilder_ == null) { - uuidBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder>( - getUuid(), - getParentForChildren(), - isClean()); - uuid_ = null; - } - return uuidBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:proto.GattDescriptor) - } - - // @@protoc_insertion_point(class_scope:proto.GattDescriptor) - private static final dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor(); - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public GattDescriptor parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new GattDescriptor(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorOrBuilder.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorOrBuilder.java deleted file mode 100644 index c8ccfd8..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorOrBuilder.java +++ /dev/null @@ -1,36 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public interface GattDescriptorOrBuilder extends - // @@protoc_insertion_point(interface_extends:proto.GattDescriptor) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - * @return The id. - */ - java.lang.String getId(); - /** - * string id = 1; - * @return The bytes for id. - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - boolean hasUuid(); - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid(); - /** - * .proto.UUID uuid = 2; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder(); -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattService.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattService.java deleted file mode 100644 index dbb29c9..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattService.java +++ /dev/null @@ -1,747 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf type {@code proto.GattService} - */ -public final class GattService extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:proto.GattService) - GattServiceOrBuilder { -private static final long serialVersionUID = 0L; - // Use GattService.newBuilder() to construct. - private GattService(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private GattService() { - id_ = ""; - } - - @java.lang.Override - @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new GattService(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private GattService( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - java.lang.String s = input.readStringRequireUtf8(); - - id_ = s; - break; - } - case 18: { - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder subBuilder = null; - if (uuid_ != null) { - subBuilder = uuid_.toBuilder(); - } - uuid_ = input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.UUID.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(uuid_); - uuid_ = subBuilder.buildPartial(); - } - - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattService_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattService_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.GattService.class, dev.yanshouwang.bluetooth_low_energy.proto.GattService.Builder.class); - } - - public static final int ID_FIELD_NUMBER = 1; - private volatile java.lang.Object id_; - /** - * string id = 1; - * @return The id. - */ - @java.lang.Override - public java.lang.String getId() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int UUID_FIELD_NUMBER = 2; - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - @java.lang.Override - public boolean hasUuid() { - return uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - /** - * .proto.UUID uuid = 2; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - return getUuid(); - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (uuid_ != null) { - output.writeMessage(2, getUuid()); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (uuid_ != null) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getUuid()); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof dev.yanshouwang.bluetooth_low_energy.proto.GattService)) { - return super.equals(obj); - } - dev.yanshouwang.bluetooth_low_energy.proto.GattService other = (dev.yanshouwang.bluetooth_low_energy.proto.GattService) obj; - - if (!getId() - .equals(other.getId())) return false; - if (hasUuid() != other.hasUuid()) return false; - if (hasUuid()) { - if (!getUuid() - .equals(other.getUuid())) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - if (hasUuid()) { - hash = (37 * hash) + UUID_FIELD_NUMBER; - hash = (53 * hash) + getUuid().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(dev.yanshouwang.bluetooth_low_energy.proto.GattService prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code proto.GattService} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:proto.GattService) - dev.yanshouwang.bluetooth_low_energy.proto.GattServiceOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattService_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattService_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.GattService.class, dev.yanshouwang.bluetooth_low_energy.proto.GattService.Builder.class); - } - - // Construct using dev.yanshouwang.bluetooth_low_energy.proto.GattService.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - id_ = ""; - - if (uuidBuilder_ == null) { - uuid_ = null; - } else { - uuid_ = null; - uuidBuilder_ = null; - } - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_GattService_descriptor; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattService getDefaultInstanceForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.GattService.getDefaultInstance(); - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattService build() { - dev.yanshouwang.bluetooth_low_energy.proto.GattService result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattService buildPartial() { - dev.yanshouwang.bluetooth_low_energy.proto.GattService result = new dev.yanshouwang.bluetooth_low_energy.proto.GattService(this); - result.id_ = id_; - if (uuidBuilder_ == null) { - result.uuid_ = uuid_; - } else { - result.uuid_ = uuidBuilder_.build(); - } - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof dev.yanshouwang.bluetooth_low_energy.proto.GattService) { - return mergeFrom((dev.yanshouwang.bluetooth_low_energy.proto.GattService)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(dev.yanshouwang.bluetooth_low_energy.proto.GattService other) { - if (other == dev.yanshouwang.bluetooth_low_energy.proto.GattService.getDefaultInstance()) return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - onChanged(); - } - if (other.hasUuid()) { - mergeUuid(other.getUuid()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - dev.yanshouwang.bluetooth_low_energy.proto.GattService parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (dev.yanshouwang.bluetooth_low_energy.proto.GattService) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object id_ = ""; - /** - * string id = 1; - * @return The id. - */ - public java.lang.String getId() { - java.lang.Object ref = id_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string id = 1; - * @param value The id to set. - * @return This builder for chaining. - */ - public Builder setId( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - id_ = value; - onChanged(); - return this; - } - /** - * string id = 1; - * @return This builder for chaining. - */ - public Builder clearId() { - - id_ = getDefaultInstance().getId(); - onChanged(); - return this; - } - /** - * string id = 1; - * @param value The bytes for id to set. - * @return This builder for chaining. - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - id_ = value; - onChanged(); - return this; - } - - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> uuidBuilder_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - public boolean hasUuid() { - return uuidBuilder_ != null || uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - if (uuidBuilder_ == null) { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } else { - return uuidBuilder_.getMessage(); - } - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - uuid_ = value; - onChanged(); - } else { - uuidBuilder_.setMessage(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (uuidBuilder_ == null) { - uuid_ = builderForValue.build(); - onChanged(); - } else { - uuidBuilder_.setMessage(builderForValue.build()); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder mergeUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (uuid_ != null) { - uuid_ = - dev.yanshouwang.bluetooth_low_energy.proto.UUID.newBuilder(uuid_).mergeFrom(value).buildPartial(); - } else { - uuid_ = value; - } - onChanged(); - } else { - uuidBuilder_.mergeFrom(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder clearUuid() { - if (uuidBuilder_ == null) { - uuid_ = null; - onChanged(); - } else { - uuid_ = null; - uuidBuilder_ = null; - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder getUuidBuilder() { - - onChanged(); - return getUuidFieldBuilder().getBuilder(); - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - if (uuidBuilder_ != null) { - return uuidBuilder_.getMessageOrBuilder(); - } else { - return uuid_ == null ? - dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - } - /** - * .proto.UUID uuid = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> - getUuidFieldBuilder() { - if (uuidBuilder_ == null) { - uuidBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder>( - getUuid(), - getParentForChildren(), - isClean()); - uuid_ = null; - } - return uuidBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:proto.GattService) - } - - // @@protoc_insertion_point(class_scope:proto.GattService) - private static final dev.yanshouwang.bluetooth_low_energy.proto.GattService DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new dev.yanshouwang.bluetooth_low_energy.proto.GattService(); - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.GattService getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public GattService parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new GattService(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.GattService getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceOrBuilder.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceOrBuilder.java deleted file mode 100644 index 931f0f5..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceOrBuilder.java +++ /dev/null @@ -1,36 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public interface GattServiceOrBuilder extends - // @@protoc_insertion_point(interface_extends:proto.GattService) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - * @return The id. - */ - java.lang.String getId(); - /** - * string id = 1; - * @return The bytes for id. - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - boolean hasUuid(); - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid(); - /** - * .proto.UUID uuid = 2; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder(); -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Messages.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Messages.java deleted file mode 100644 index a049bd1..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Messages.java +++ /dev/null @@ -1,136 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public final class Messages { - private Messages() {} - public static void registerAllExtensions( - com.google.protobuf.ExtensionRegistryLite registry) { - } - - public static void registerAllExtensions( - com.google.protobuf.ExtensionRegistry registry) { - registerAllExtensions( - (com.google.protobuf.ExtensionRegistryLite) registry); - } - static final com.google.protobuf.Descriptors.Descriptor - internal_static_proto_Broadcast_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_proto_Broadcast_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_proto_Peripheral_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_proto_Peripheral_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_proto_GattService_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_proto_GattService_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_proto_GattCharacteristic_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_proto_GattCharacteristic_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_proto_GattDescriptor_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_proto_GattDescriptor_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_proto_UUID_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_proto_UUID_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_proto_ServiceData_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_proto_ServiceData_fieldAccessorTable; - - public static com.google.protobuf.Descriptors.FileDescriptor - getDescriptor() { - return descriptor; - } - private static com.google.protobuf.Descriptors.FileDescriptor - descriptor; - static { - java.lang.String[] descriptorData = { - "\n\024proto/messages.proto\022\005proto\"\361\002\n\tBroadc" + - "ast\022%\n\nperipheral\030\001 \001(\0132\021.proto.Peripher" + - "al\022\014\n\004rssi\030\002 \001(\005\022\030\n\013connectable\030\003 \001(\010H\000\210" + - "\001\001\022\014\n\004data\030\004 \001(\014\022\027\n\nlocal_name\030\005 \001(\tH\001\210\001" + - "\001\022\"\n\032manufacturer_specific_data\030\006 \001(\014\022)\n" + - "\rservice_datas\030\007 \003(\0132\022.proto.ServiceData" + - "\022\"\n\rservice_uuids\030\010 \003(\0132\013.proto.UUID\022,\n\027" + - "solicited_service_uuids\030\t \003(\0132\013.proto.UU" + - "ID\022\033\n\016tx_power_level\030\n \001(\005H\002\210\001\001B\016\n\014_conn" + - "ectableB\r\n\013_local_nameB\021\n\017_tx_power_leve" + - "l\"3\n\nPeripheral\022\n\n\002id\030\001 \001(\t\022\031\n\004uuid\030\002 \001(" + - "\0132\013.proto.UUID\"4\n\013GattService\022\n\n\002id\030\001 \001(" + - "\t\022\031\n\004uuid\030\002 \001(\0132\013.proto.UUID\"\230\001\n\022GattCha" + - "racteristic\022\n\n\002id\030\001 \001(\t\022\031\n\004uuid\030\002 \001(\0132\013." + - "proto.UUID\022\020\n\010can_read\030\003 \001(\010\022\021\n\tcan_writ" + - "e\030\004 \001(\010\022\"\n\032can_write_without_response\030\005 " + - "\001(\010\022\022\n\ncan_notify\030\006 \001(\010\"7\n\016GattDescripto" + - "r\022\n\n\002id\030\001 \001(\t\022\031\n\004uuid\030\002 \001(\0132\013.proto.UUID" + - "\"\025\n\004UUID\022\r\n\005value\030\001 \001(\t\"6\n\013ServiceData\022\031" + - "\n\004uuid\030\001 \001(\0132\013.proto.UUID\022\014\n\004data\030\002 \001(\014*" + - "r\n\016BluetoothState\022\037\n\033BLUETOOTH_STATE_UNS" + - "UPPORTED\020\000\022\037\n\033BLUETOOTH_STATE_POWERED_OF" + - "F\020\001\022\036\n\032BLUETOOTH_STATE_POWERED_ON\020\002B.\n*d" + - "ev.yanshouwang.bluetooth_low_energy.prot" + - "oP\001b\006proto3" - }; - descriptor = com.google.protobuf.Descriptors.FileDescriptor - .internalBuildGeneratedFileFrom(descriptorData, - new com.google.protobuf.Descriptors.FileDescriptor[] { - }); - internal_static_proto_Broadcast_descriptor = - getDescriptor().getMessageTypes().get(0); - internal_static_proto_Broadcast_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_proto_Broadcast_descriptor, - new java.lang.String[] { "Peripheral", "Rssi", "Connectable", "Data", "LocalName", "ManufacturerSpecificData", "ServiceDatas", "ServiceUuids", "SolicitedServiceUuids", "TxPowerLevel", "Connectable", "LocalName", "TxPowerLevel", }); - internal_static_proto_Peripheral_descriptor = - getDescriptor().getMessageTypes().get(1); - internal_static_proto_Peripheral_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_proto_Peripheral_descriptor, - new java.lang.String[] { "Id", "Uuid", }); - internal_static_proto_GattService_descriptor = - getDescriptor().getMessageTypes().get(2); - internal_static_proto_GattService_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_proto_GattService_descriptor, - new java.lang.String[] { "Id", "Uuid", }); - internal_static_proto_GattCharacteristic_descriptor = - getDescriptor().getMessageTypes().get(3); - internal_static_proto_GattCharacteristic_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_proto_GattCharacteristic_descriptor, - new java.lang.String[] { "Id", "Uuid", "CanRead", "CanWrite", "CanWriteWithoutResponse", "CanNotify", }); - internal_static_proto_GattDescriptor_descriptor = - getDescriptor().getMessageTypes().get(4); - internal_static_proto_GattDescriptor_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_proto_GattDescriptor_descriptor, - new java.lang.String[] { "Id", "Uuid", }); - internal_static_proto_UUID_descriptor = - getDescriptor().getMessageTypes().get(5); - internal_static_proto_UUID_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_proto_UUID_descriptor, - new java.lang.String[] { "Value", }); - internal_static_proto_ServiceData_descriptor = - getDescriptor().getMessageTypes().get(6); - internal_static_proto_ServiceData_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_proto_ServiceData_descriptor, - new java.lang.String[] { "Uuid", "Data", }); - } - - // @@protoc_insertion_point(outer_class_scope) -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Peripheral.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Peripheral.java deleted file mode 100644 index 5f9d5c3..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/Peripheral.java +++ /dev/null @@ -1,747 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf type {@code proto.Peripheral} - */ -public final class Peripheral extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:proto.Peripheral) - PeripheralOrBuilder { -private static final long serialVersionUID = 0L; - // Use Peripheral.newBuilder() to construct. - private Peripheral(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private Peripheral() { - id_ = ""; - } - - @java.lang.Override - @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new Peripheral(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Peripheral( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - java.lang.String s = input.readStringRequireUtf8(); - - id_ = s; - break; - } - case 18: { - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder subBuilder = null; - if (uuid_ != null) { - subBuilder = uuid_.toBuilder(); - } - uuid_ = input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.UUID.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(uuid_); - uuid_ = subBuilder.buildPartial(); - } - - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Peripheral_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Peripheral_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.class, dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder.class); - } - - public static final int ID_FIELD_NUMBER = 1; - private volatile java.lang.Object id_; - /** - * string id = 1; - * @return The id. - */ - @java.lang.Override - public java.lang.String getId() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int UUID_FIELD_NUMBER = 2; - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - @java.lang.Override - public boolean hasUuid() { - return uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - /** - * .proto.UUID uuid = 2; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - return getUuid(); - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (uuid_ != null) { - output.writeMessage(2, getUuid()); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (uuid_ != null) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getUuid()); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof dev.yanshouwang.bluetooth_low_energy.proto.Peripheral)) { - return super.equals(obj); - } - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral other = (dev.yanshouwang.bluetooth_low_energy.proto.Peripheral) obj; - - if (!getId() - .equals(other.getId())) return false; - if (hasUuid() != other.hasUuid()) return false; - if (hasUuid()) { - if (!getUuid() - .equals(other.getUuid())) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - if (hasUuid()) { - hash = (37 * hash) + UUID_FIELD_NUMBER; - hash = (53 * hash) + getUuid().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(dev.yanshouwang.bluetooth_low_energy.proto.Peripheral prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code proto.Peripheral} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:proto.Peripheral) - dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Peripheral_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Peripheral_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.class, dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder.class); - } - - // Construct using dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - id_ = ""; - - if (uuidBuilder_ == null) { - uuid_ = null; - } else { - uuid_ = null; - uuidBuilder_ = null; - } - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_Peripheral_descriptor; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Peripheral getDefaultInstanceForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.getDefaultInstance(); - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Peripheral build() { - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Peripheral buildPartial() { - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral result = new dev.yanshouwang.bluetooth_low_energy.proto.Peripheral(this); - result.id_ = id_; - if (uuidBuilder_ == null) { - result.uuid_ = uuid_; - } else { - result.uuid_ = uuidBuilder_.build(); - } - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof dev.yanshouwang.bluetooth_low_energy.proto.Peripheral) { - return mergeFrom((dev.yanshouwang.bluetooth_low_energy.proto.Peripheral)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(dev.yanshouwang.bluetooth_low_energy.proto.Peripheral other) { - if (other == dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.getDefaultInstance()) return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - onChanged(); - } - if (other.hasUuid()) { - mergeUuid(other.getUuid()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - dev.yanshouwang.bluetooth_low_energy.proto.Peripheral parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (dev.yanshouwang.bluetooth_low_energy.proto.Peripheral) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object id_ = ""; - /** - * string id = 1; - * @return The id. - */ - public java.lang.String getId() { - java.lang.Object ref = id_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * string id = 1; - * @return The bytes for id. - */ - public com.google.protobuf.ByteString - getIdBytes() { - java.lang.Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string id = 1; - * @param value The id to set. - * @return This builder for chaining. - */ - public Builder setId( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - id_ = value; - onChanged(); - return this; - } - /** - * string id = 1; - * @return This builder for chaining. - */ - public Builder clearId() { - - id_ = getDefaultInstance().getId(); - onChanged(); - return this; - } - /** - * string id = 1; - * @param value The bytes for id to set. - * @return This builder for chaining. - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - id_ = value; - onChanged(); - return this; - } - - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> uuidBuilder_; - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - public boolean hasUuid() { - return uuidBuilder_ != null || uuid_ != null; - } - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - if (uuidBuilder_ == null) { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } else { - return uuidBuilder_.getMessage(); - } - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - uuid_ = value; - onChanged(); - } else { - uuidBuilder_.setMessage(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder setUuid( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (uuidBuilder_ == null) { - uuid_ = builderForValue.build(); - onChanged(); - } else { - uuidBuilder_.setMessage(builderForValue.build()); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder mergeUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (uuid_ != null) { - uuid_ = - dev.yanshouwang.bluetooth_low_energy.proto.UUID.newBuilder(uuid_).mergeFrom(value).buildPartial(); - } else { - uuid_ = value; - } - onChanged(); - } else { - uuidBuilder_.mergeFrom(value); - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public Builder clearUuid() { - if (uuidBuilder_ == null) { - uuid_ = null; - onChanged(); - } else { - uuid_ = null; - uuidBuilder_ = null; - } - - return this; - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder getUuidBuilder() { - - onChanged(); - return getUuidFieldBuilder().getBuilder(); - } - /** - * .proto.UUID uuid = 2; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - if (uuidBuilder_ != null) { - return uuidBuilder_.getMessageOrBuilder(); - } else { - return uuid_ == null ? - dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - } - /** - * .proto.UUID uuid = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> - getUuidFieldBuilder() { - if (uuidBuilder_ == null) { - uuidBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder>( - getUuid(), - getParentForChildren(), - isClean()); - uuid_ = null; - } - return uuidBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:proto.Peripheral) - } - - // @@protoc_insertion_point(class_scope:proto.Peripheral) - private static final dev.yanshouwang.bluetooth_low_energy.proto.Peripheral DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new dev.yanshouwang.bluetooth_low_energy.proto.Peripheral(); - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.Peripheral getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Peripheral parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Peripheral(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.Peripheral getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralOrBuilder.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralOrBuilder.java deleted file mode 100644 index 9e31a90..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralOrBuilder.java +++ /dev/null @@ -1,36 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public interface PeripheralOrBuilder extends - // @@protoc_insertion_point(interface_extends:proto.Peripheral) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - * @return The id. - */ - java.lang.String getId(); - /** - * string id = 1; - * @return The bytes for id. - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - boolean hasUuid(); - /** - * .proto.UUID uuid = 2; - * @return The uuid. - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid(); - /** - * .proto.UUID uuid = 2; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder(); -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceData.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceData.java deleted file mode 100644 index b73e088..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceData.java +++ /dev/null @@ -1,677 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf type {@code proto.ServiceData} - */ -public final class ServiceData extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:proto.ServiceData) - ServiceDataOrBuilder { -private static final long serialVersionUID = 0L; - // Use ServiceData.newBuilder() to construct. - private ServiceData(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private ServiceData() { - data_ = com.google.protobuf.ByteString.EMPTY; - } - - @java.lang.Override - @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new ServiceData(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private ServiceData( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder subBuilder = null; - if (uuid_ != null) { - subBuilder = uuid_.toBuilder(); - } - uuid_ = input.readMessage(dev.yanshouwang.bluetooth_low_energy.proto.UUID.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(uuid_); - uuid_ = subBuilder.buildPartial(); - } - - break; - } - case 18: { - - data_ = input.readBytes(); - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_ServiceData_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_ServiceData_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.class, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder.class); - } - - public static final int UUID_FIELD_NUMBER = 1; - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - /** - * .proto.UUID uuid = 1; - * @return Whether the uuid field is set. - */ - @java.lang.Override - public boolean hasUuid() { - return uuid_ != null; - } - /** - * .proto.UUID uuid = 1; - * @return The uuid. - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - /** - * .proto.UUID uuid = 1; - */ - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - return getUuid(); - } - - public static final int DATA_FIELD_NUMBER = 2; - private com.google.protobuf.ByteString data_; - /** - * bytes data = 2; - * @return The data. - */ - @java.lang.Override - public com.google.protobuf.ByteString getData() { - return data_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (uuid_ != null) { - output.writeMessage(1, getUuid()); - } - if (!data_.isEmpty()) { - output.writeBytes(2, data_); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (uuid_ != null) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getUuid()); - } - if (!data_.isEmpty()) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, data_); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof dev.yanshouwang.bluetooth_low_energy.proto.ServiceData)) { - return super.equals(obj); - } - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData other = (dev.yanshouwang.bluetooth_low_energy.proto.ServiceData) obj; - - if (hasUuid() != other.hasUuid()) return false; - if (hasUuid()) { - if (!getUuid() - .equals(other.getUuid())) return false; - } - if (!getData() - .equals(other.getData())) return false; - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (hasUuid()) { - hash = (37 * hash) + UUID_FIELD_NUMBER; - hash = (53 * hash) + getUuid().hashCode(); - } - hash = (37 * hash) + DATA_FIELD_NUMBER; - hash = (53 * hash) + getData().hashCode(); - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(dev.yanshouwang.bluetooth_low_energy.proto.ServiceData prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code proto.ServiceData} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:proto.ServiceData) - dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_ServiceData_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_ServiceData_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.class, dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder.class); - } - - // Construct using dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - if (uuidBuilder_ == null) { - uuid_ = null; - } else { - uuid_ = null; - uuidBuilder_ = null; - } - data_ = com.google.protobuf.ByteString.EMPTY; - - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_ServiceData_descriptor; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData getDefaultInstanceForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.getDefaultInstance(); - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData build() { - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData buildPartial() { - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData result = new dev.yanshouwang.bluetooth_low_energy.proto.ServiceData(this); - if (uuidBuilder_ == null) { - result.uuid_ = uuid_; - } else { - result.uuid_ = uuidBuilder_.build(); - } - result.data_ = data_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof dev.yanshouwang.bluetooth_low_energy.proto.ServiceData) { - return mergeFrom((dev.yanshouwang.bluetooth_low_energy.proto.ServiceData)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(dev.yanshouwang.bluetooth_low_energy.proto.ServiceData other) { - if (other == dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.getDefaultInstance()) return this; - if (other.hasUuid()) { - mergeUuid(other.getUuid()); - } - if (other.getData() != com.google.protobuf.ByteString.EMPTY) { - setData(other.getData()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - dev.yanshouwang.bluetooth_low_energy.proto.ServiceData parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (dev.yanshouwang.bluetooth_low_energy.proto.ServiceData) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private dev.yanshouwang.bluetooth_low_energy.proto.UUID uuid_; - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> uuidBuilder_; - /** - * .proto.UUID uuid = 1; - * @return Whether the uuid field is set. - */ - public boolean hasUuid() { - return uuidBuilder_ != null || uuid_ != null; - } - /** - * .proto.UUID uuid = 1; - * @return The uuid. - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid() { - if (uuidBuilder_ == null) { - return uuid_ == null ? dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } else { - return uuidBuilder_.getMessage(); - } - } - /** - * .proto.UUID uuid = 1; - */ - public Builder setUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - uuid_ = value; - onChanged(); - } else { - uuidBuilder_.setMessage(value); - } - - return this; - } - /** - * .proto.UUID uuid = 1; - */ - public Builder setUuid( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder builderForValue) { - if (uuidBuilder_ == null) { - uuid_ = builderForValue.build(); - onChanged(); - } else { - uuidBuilder_.setMessage(builderForValue.build()); - } - - return this; - } - /** - * .proto.UUID uuid = 1; - */ - public Builder mergeUuid(dev.yanshouwang.bluetooth_low_energy.proto.UUID value) { - if (uuidBuilder_ == null) { - if (uuid_ != null) { - uuid_ = - dev.yanshouwang.bluetooth_low_energy.proto.UUID.newBuilder(uuid_).mergeFrom(value).buildPartial(); - } else { - uuid_ = value; - } - onChanged(); - } else { - uuidBuilder_.mergeFrom(value); - } - - return this; - } - /** - * .proto.UUID uuid = 1; - */ - public Builder clearUuid() { - if (uuidBuilder_ == null) { - uuid_ = null; - onChanged(); - } else { - uuid_ = null; - uuidBuilder_ = null; - } - - return this; - } - /** - * .proto.UUID uuid = 1; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder getUuidBuilder() { - - onChanged(); - return getUuidFieldBuilder().getBuilder(); - } - /** - * .proto.UUID uuid = 1; - */ - public dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder() { - if (uuidBuilder_ != null) { - return uuidBuilder_.getMessageOrBuilder(); - } else { - return uuid_ == null ? - dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance() : uuid_; - } - } - /** - * .proto.UUID uuid = 1; - */ - private com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder> - getUuidFieldBuilder() { - if (uuidBuilder_ == null) { - uuidBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - dev.yanshouwang.bluetooth_low_energy.proto.UUID, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder, dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder>( - getUuid(), - getParentForChildren(), - isClean()); - uuid_ = null; - } - return uuidBuilder_; - } - - private com.google.protobuf.ByteString data_ = com.google.protobuf.ByteString.EMPTY; - /** - * bytes data = 2; - * @return The data. - */ - @java.lang.Override - public com.google.protobuf.ByteString getData() { - return data_; - } - /** - * bytes data = 2; - * @param value The data to set. - * @return This builder for chaining. - */ - public Builder setData(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - - data_ = value; - onChanged(); - return this; - } - /** - * bytes data = 2; - * @return This builder for chaining. - */ - public Builder clearData() { - - data_ = getDefaultInstance().getData(); - onChanged(); - return this; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:proto.ServiceData) - } - - // @@protoc_insertion_point(class_scope:proto.ServiceData) - private static final dev.yanshouwang.bluetooth_low_energy.proto.ServiceData DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new dev.yanshouwang.bluetooth_low_energy.proto.ServiceData(); - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.ServiceData getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public ServiceData parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new ServiceData(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.ServiceData getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataOrBuilder.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataOrBuilder.java deleted file mode 100644 index af6b7e4..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataOrBuilder.java +++ /dev/null @@ -1,30 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public interface ServiceDataOrBuilder extends - // @@protoc_insertion_point(interface_extends:proto.ServiceData) - com.google.protobuf.MessageOrBuilder { - - /** - * .proto.UUID uuid = 1; - * @return Whether the uuid field is set. - */ - boolean hasUuid(); - /** - * .proto.UUID uuid = 1; - * @return The uuid. - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUID getUuid(); - /** - * .proto.UUID uuid = 1; - */ - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder getUuidOrBuilder(); - - /** - * bytes data = 2; - * @return The data. - */ - com.google.protobuf.ByteString getData(); -} diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUID.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUID.java deleted file mode 100644 index 07eb7e1..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUID.java +++ /dev/null @@ -1,559 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -/** - * Protobuf type {@code proto.UUID} - */ -public final class UUID extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:proto.UUID) - UUIDOrBuilder { -private static final long serialVersionUID = 0L; - // Use UUID.newBuilder() to construct. - private UUID(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private UUID() { - value_ = ""; - } - - @java.lang.Override - @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( - UnusedPrivateParameter unused) { - return new UUID(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private UUID( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - java.lang.String s = input.readStringRequireUtf8(); - - value_ = s; - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (com.google.protobuf.UninitializedMessageException e) { - throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_UUID_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_UUID_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.class, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder.class); - } - - public static final int VALUE_FIELD_NUMBER = 1; - private volatile java.lang.Object value_; - /** - * string value = 1; - * @return The value. - */ - @java.lang.Override - public java.lang.String getValue() { - java.lang.Object ref = value_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - value_ = s; - return s; - } - } - /** - * string value = 1; - * @return The bytes for value. - */ - @java.lang.Override - public com.google.protobuf.ByteString - getValueBytes() { - java.lang.Object ref = value_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - value_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(value_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, value_); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(value_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, value_); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof dev.yanshouwang.bluetooth_low_energy.proto.UUID)) { - return super.equals(obj); - } - dev.yanshouwang.bluetooth_low_energy.proto.UUID other = (dev.yanshouwang.bluetooth_low_energy.proto.UUID) obj; - - if (!getValue() - .equals(other.getValue())) return false; - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + VALUE_FIELD_NUMBER; - hash = (53 * hash) + getValue().hashCode(); - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(dev.yanshouwang.bluetooth_low_energy.proto.UUID prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code proto.UUID} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:proto.UUID) - dev.yanshouwang.bluetooth_low_energy.proto.UUIDOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_UUID_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_UUID_fieldAccessorTable - .ensureFieldAccessorsInitialized( - dev.yanshouwang.bluetooth_low_energy.proto.UUID.class, dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder.class); - } - - // Construct using dev.yanshouwang.bluetooth_low_energy.proto.UUID.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - value_ = ""; - - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.Messages.internal_static_proto_UUID_descriptor; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getDefaultInstanceForType() { - return dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance(); - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID build() { - dev.yanshouwang.bluetooth_low_energy.proto.UUID result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID buildPartial() { - dev.yanshouwang.bluetooth_low_energy.proto.UUID result = new dev.yanshouwang.bluetooth_low_energy.proto.UUID(this); - result.value_ = value_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof dev.yanshouwang.bluetooth_low_energy.proto.UUID) { - return mergeFrom((dev.yanshouwang.bluetooth_low_energy.proto.UUID)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(dev.yanshouwang.bluetooth_low_energy.proto.UUID other) { - if (other == dev.yanshouwang.bluetooth_low_energy.proto.UUID.getDefaultInstance()) return this; - if (!other.getValue().isEmpty()) { - value_ = other.value_; - onChanged(); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - dev.yanshouwang.bluetooth_low_energy.proto.UUID parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (dev.yanshouwang.bluetooth_low_energy.proto.UUID) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - - private java.lang.Object value_ = ""; - /** - * string value = 1; - * @return The value. - */ - public java.lang.String getValue() { - java.lang.Object ref = value_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - value_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * string value = 1; - * @return The bytes for value. - */ - public com.google.protobuf.ByteString - getValueBytes() { - java.lang.Object ref = value_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - value_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string value = 1; - * @param value The value to set. - * @return This builder for chaining. - */ - public Builder setValue( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - - value_ = value; - onChanged(); - return this; - } - /** - * string value = 1; - * @return This builder for chaining. - */ - public Builder clearValue() { - - value_ = getDefaultInstance().getValue(); - onChanged(); - return this; - } - /** - * string value = 1; - * @param value The bytes for value to set. - * @return This builder for chaining. - */ - public Builder setValueBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - value_ = value; - onChanged(); - return this; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:proto.UUID) - } - - // @@protoc_insertion_point(class_scope:proto.UUID) - private static final dev.yanshouwang.bluetooth_low_energy.proto.UUID DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new dev.yanshouwang.bluetooth_low_energy.proto.UUID(); - } - - public static dev.yanshouwang.bluetooth_low_energy.proto.UUID getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public UUID parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new UUID(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public dev.yanshouwang.bluetooth_low_energy.proto.UUID getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUIDOrBuilder.java b/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUIDOrBuilder.java deleted file mode 100644 index 3fe873b..0000000 --- a/android/src/main/java/dev/yanshouwang/bluetooth_low_energy/proto/UUIDOrBuilder.java +++ /dev/null @@ -1,21 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -public interface UUIDOrBuilder extends - // @@protoc_insertion_point(interface_extends:proto.UUID) - com.google.protobuf.MessageOrBuilder { - - /** - * string value = 1; - * @return The value. - */ - java.lang.String getValue(); - /** - * string value = 1; - * @return The bytes for value. - */ - com.google.protobuf.ByteString - getValueBytes(); -} diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyException.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyException.kt deleted file mode 100644 index 35e1a42..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyException.kt +++ /dev/null @@ -1,3 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -class BluetoothLowEnergyException(message: String) : Exception(message) \ No newline at end of file diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPlugin.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPlugin.kt deleted file mode 100644 index ddf1332..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPlugin.kt +++ /dev/null @@ -1,185 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.BluetoothAdapter -import android.bluetooth.BluetoothDevice -import android.bluetooth.BluetoothManager -import android.bluetooth.le.ScanRecord -import android.content.Context -import android.content.IntentFilter -import android.content.pm.PackageManager -import android.os.Handler -import android.util.Log -import androidx.core.content.ContextCompat -import dev.yanshouwang.bluetooth_low_energy.proto.BluetoothState -import dev.yanshouwang.bluetooth_low_energy.proto.UUID -import dev.yanshouwang.bluetooth_low_energy.proto.uUID -import io.flutter.embedding.engine.plugins.FlutterPlugin -import io.flutter.embedding.engine.plugins.activity.ActivityAware -import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding -import java.util.concurrent.Executor -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon - -/** BluetoothLowEnergyPlugin */ -class BluetoothLowEnergyPlugin : FlutterPlugin, ActivityAware { - override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { - val binaryMessenger = binding.binaryMessenger - - instances[KEY_CENTRAL_MANAGER_FLUTTER_API] = Pigeon.CentralManagerFlutterApi(binaryMessenger) - instances[KEY_PERIPHERAL_FLUTTER_API] = Pigeon.PeripheralFlutterApi(binaryMessenger) - instances[KEY_GATT_CHARACTERISTIC_FLUTTER_API] = Pigeon.GattCharacteristicFlutterApi(binaryMessenger) - - Pigeon.CentralManagerHostApi.setup(binaryMessenger, MyCentralManagerHostApi) - Pigeon.PeripheralHostApi.setup(binaryMessenger, MyPeripheralHostApi) - Pigeon.GattServiceHostApi.setup(binaryMessenger, MyGattServiceHostApi) - Pigeon.GattCharacteristicHostApi.setup(binaryMessenger, MyGattCharacteristicHostApi) - Pigeon.GattDescriptorHostApi.setup(binaryMessenger, MyGattDescriptorHostApi) - } - - override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { - val binaryMessenger = binding.binaryMessenger - - instances.remove(KEY_CENTRAL_MANAGER_FLUTTER_API) - instances.remove(KEY_PERIPHERAL_FLUTTER_API) - instances.remove(KEY_GATT_CHARACTERISTIC_FLUTTER_API) - - Pigeon.CentralManagerHostApi.setup(binaryMessenger, null) - Pigeon.PeripheralHostApi.setup(binaryMessenger, null) - Pigeon.GattServiceHostApi.setup(binaryMessenger, null) - Pigeon.GattCharacteristicHostApi.setup(binaryMessenger, null) - Pigeon.GattDescriptorHostApi.setup(binaryMessenger, null) - } - - override fun onAttachedToActivity(binding: ActivityPluginBinding) { - instances[KEY_ACTIVITY_PLUGIN_BINDING] = binding - binding.addRequestPermissionsResultListener(MyRequestPermissionsResultListener) - // Register the central manager state changed receiver. - val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) - activity.registerReceiver(MyBroadcastReceiver, filter) - } - - override fun onDetachedFromActivityForConfigChanges() { - onDetachedFromActivity() - } - - override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { - onAttachedToActivity(binding) - } - - override fun onDetachedFromActivity() { - // Unregister the central manager state changed receiver. - activity.unregisterReceiver(MyBroadcastReceiver) - - val binding = instances.remove(KEY_ACTIVITY_PLUGIN_BINDING) as ActivityPluginBinding - binding.removeRequestPermissionsResultListener(MyRequestPermissionsResultListener) - } -} - -const val KEY_CENTRAL_MANAGER_FLUTTER_API = "KEY_CENTRAL_MANAGER_FLUTTER_API" -const val KEY_PERIPHERAL_FLUTTER_API = "KEY_PERIPHERAL_FLUTTER_API" -const val KEY_GATT_CHARACTERISTIC_FLUTTER_API = "KEY_GATT_CHARACTERISTIC_FLUTTER_API" -const val KEY_ACTIVITY_PLUGIN_BINDING = "KEY_ACTIVITY_PLUGIN_BINDING" -const val KEY_COUNT = "KEY_COUNT" -const val KEY_DEVICE = "KEY_DEVICE" -const val KEY_GATT = "KEY_GATT" -const val KEY_SERVICE = "KEY_SERVICE" -const val KEY_CHARACTERISTIC = "KEY_CHARACTERISTIC" -const val KEY_DESCRIPTOR = "KEY_DESCRIPTOR" -const val KEY_AUTHORIZE_RESULT = "KEY_AUTHORIZE_RESULT" -const val KEY_START_SCAN_ERROR = "KEY_START_SCAN_ERROR" -const val KEY_CONNECT_RESULT = "KEY_CONNECT_RESULT" -const val KEY_DISCONNECT_RESULT = "KEY_DISCONNECT_RESULT" -const val KEY_REQUEST_MTU_RESULT = "KEY_REQUEST_MTU_RESULT" -const val KEY_DISCOVER_SERVICES_RESULT = "KEY_DISCOVER_SERVICES_RESULT" -const val KEY_READ_RESULT = "KEY_READ_RESULT" -const val KEY_WRITE_RESULT = "KEY_WRITE_RESULT" - -val instances = mutableMapOf() - -val activity get() = (instances[KEY_ACTIVITY_PLUGIN_BINDING] as ActivityPluginBinding).activity -val centralFlutterApi get() = instances[KEY_CENTRAL_MANAGER_FLUTTER_API] as Pigeon.CentralManagerFlutterApi -val peripheralFlutterApi get() = instances[KEY_PERIPHERAL_FLUTTER_API] as Pigeon.PeripheralFlutterApi -val characteristicFlutterApi get() = instances[KEY_GATT_CHARACTERISTIC_FLUTTER_API] as Pigeon.GattCharacteristicFlutterApi - -val bluetoothManager get() = activity.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager -val bluetoothAdapter get() = bluetoothManager.adapter as BluetoothAdapter -val bluetoothAvailable get() = activity.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) -val mainHandler get() = Handler(activity.mainLooper) -val mainExecutor: Executor get() = ContextCompat.getMainExecutor(activity) - -fun register(id: String): MutableMap { - var items = instances[id] as MutableMap? - if (items == null) { - items = mutableMapOf() - instances[id] = items - Log.d(BluetoothLowEnergyPlugin::class.java.simpleName, "register: $id") - } - var count = items[KEY_COUNT] as Int? ?: 0 - count += 1 - items[KEY_COUNT] = count - return items -} - -fun unregister(id: String): MutableMap { - val items = instances[id] as MutableMap - var count = items[KEY_COUNT] as Int - count -= 1 - items[KEY_COUNT] = count - if (count < 1) { - instances.remove(id) - Log.d(BluetoothLowEnergyPlugin::class.java.simpleName, "unregister: $id") - } - return items -} - -val Any.TAG: String get() = this::class.java.simpleName - -val Int.stateNumber: Long - get() { - val state = when (this) { - BluetoothAdapter.STATE_OFF -> BluetoothState.BLUETOOTH_STATE_POWERED_OFF - BluetoothAdapter.STATE_TURNING_ON -> BluetoothState.BLUETOOTH_STATE_POWERED_OFF - BluetoothAdapter.STATE_ON -> BluetoothState.BLUETOOTH_STATE_POWERED_ON - BluetoothAdapter.STATE_TURNING_OFF -> BluetoothState.BLUETOOTH_STATE_POWERED_ON - else -> throw IllegalArgumentException() - } - return state.number.toLong() - } - -val BluetoothAdapter.stateNumber: Long - get() { - return if (bluetoothAvailable) { - state.stateNumber - } else { - BluetoothState.BLUETOOTH_STATE_UNSUPPORTED.number.toLong() - } - } - -val BluetoothDevice.uuid: UUID - get() { - val node = address.filter { char -> char != ':' }.lowercase() - // We don't know the timestamp of the bluetooth device, use nil UUID as prefix. - return uUID { - this.value = "00000000-0000-0000-$node" - } - } - -//val UUID.address: String -// get() = value.takeLast(12).chunked(2).joinToString(":").uppercase() - -val ScanRecord.rawManufacturerSpecificData: ByteArray? - get() { - var begin = 0 - while (begin < bytes.size) { - val length = bytes[begin++].toInt() and 0xff - if (length == 0) { - break - } - val end = begin + length - val type = bytes[begin++].toInt() and 0xff - if (type == MyScanCallback.DATA_TYPE_MANUFACTURER_SPECIFIC_DATA) { - return bytes.slice(begin until end).toByteArray() - } - begin = end - } - return null - } \ No newline at end of file diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt deleted file mode 100644 index 3ca0879..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt +++ /dev/null @@ -1,179 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.* -import android.util.Log -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon -import dev.yanshouwang.bluetooth_low_energy.proto.gattService -import dev.yanshouwang.bluetooth_low_energy.proto.uUID - -// TODO: Clear results when connection state changed or central manager state changed. - -object MyBluetoothGattCallback : BluetoothGattCallback() { - override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { - super.onConnectionStateChange(gatt, status, newState) - Log.d(TAG, "onConnectionStateChange: $gatt, $status, $newState") - val id = gatt.device.hashCode().toString() - if (status == BluetoothGatt.GATT_SUCCESS) { - if (newState == BluetoothProfile.STATE_CONNECTED) { - // Must be connected. - val result = instances.remove("$id/$KEY_CONNECT_RESULT") as Pigeon.Result - result.success(null) - } else { - // Must be disconnected. - gatt.close() - val result = instances.remove("$id/$KEY_DISCONNECT_RESULT") as Pigeon.Result - result.success(null) - } - } else { - gatt.close() - val result = instances.remove("$id/$KEY_CONNECT_RESULT") as Pigeon.Result? - if (result == null) { - // Connection lost. - val errorMessage = "GATT error with status: $status." - mainExecutor.execute { - peripheralFlutterApi.onConnectionLost(id, errorMessage) {} - } - } else { - // Connect failed. - val error = BluetoothLowEnergyException("GATT error with status: $status.") - result.error(error) - } - } - } - - override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) { - super.onMtuChanged(gatt, mtu, status) - Log.d(TAG, "onMtuChanged: $gatt, $mtu, $status") - val id = gatt.device.hashCode().toString() - // Maybe triggered in response to a connection event. - val result = instances.remove("$id/$KEY_REQUEST_MTU_RESULT") as Pigeon.Result? ?: return - when (status) { - BluetoothGatt.GATT_SUCCESS -> { - val maximumWriteLength = (mtu - 3).toLong() - result.success(maximumWriteLength) - } - else -> { - val error = BluetoothLowEnergyException("GATT request MTU failed with status: $status") - result.error(error) - } - } - } - - override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { - super.onServicesDiscovered(gatt, status) - Log.d(TAG, "onServicesDiscovered: $gatt, $status") - val id = gatt.device.hashCode().toString() - val result = instances.remove("$id/$KEY_DISCOVER_SERVICES_RESULT") as Pigeon.Result> - if (status == BluetoothGatt.GATT_SUCCESS) { - val serviceValues = mutableListOf() - for (service in gatt.services) { - val serviceValue = registerService(gatt, service) - serviceValues.add(serviceValue) - } - result.success(serviceValues) - } else { - val error = BluetoothLowEnergyException("GATT discover services failed with status: $status") - result.error(error) - } - } - - private fun registerService(gatt: BluetoothGatt, service: BluetoothGattService): ByteArray { - val id = service.hashCode().toString() - val items = register(id) - items[KEY_GATT] = gatt - items[KEY_SERVICE] = service - return gattService { - this.id = id - this.uuid = uUID { - this.value = service.uuid.toString() - } - }.toByteArray() - } - - override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) { - super.onCharacteristicRead(gatt, characteristic, status) - Log.d(TAG, "onCharacteristicRead: $gatt, $characteristic, $status") - val id = characteristic.hashCode().toString() - val result = instances.remove("$id/$KEY_READ_RESULT") as Pigeon.Result - if (status == BluetoothGatt.GATT_SUCCESS) { - result.success(characteristic.value) - } else { - val error = BluetoothLowEnergyException("GATT read characteristic failed with status: $status.") - result.error(error) - } - } - - override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) { - super.onCharacteristicWrite(gatt, characteristic, status) - Log.d(TAG, "onCharacteristicWrite: $gatt, $characteristic, $status") - val id = characteristic.hashCode().toString() - val result = instances.remove("$id/$KEY_WRITE_RESULT") as Pigeon.Result - if (status == BluetoothGatt.GATT_SUCCESS) { - result.success(null) - } else { - val error = BluetoothLowEnergyException("GATT write characteristic failed with status: $status.") - result.error(error) - } - } - - override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) { - super.onCharacteristicChanged(gatt, characteristic) - Log.d(TAG, "onCharacteristicChanged: $gatt, $characteristic") - val id = characteristic.hashCode().toString() - val value = characteristic.value - mainExecutor.execute { - characteristicFlutterApi.onValueChanged(id, value) {} - } - } - - override fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) { - super.onDescriptorRead(gatt, descriptor, status) - Log.d(TAG, "onDescriptorRead: $gatt, $descriptor, $status") - val id = descriptor.hashCode().toString() - val result = instances.remove("$id/$KEY_READ_RESULT") as Pigeon.Result - if (status == BluetoothGatt.GATT_SUCCESS) { - result.success(descriptor.value) - } else { - val error = BluetoothLowEnergyException("GATT read descriptor failed with status: $status.") - result.error(error) - } - } - - override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) { - super.onDescriptorWrite(gatt, descriptor, status) - Log.d(TAG, "onDescriptorWrite: $gatt, $descriptor, $status") - val id = descriptor.hashCode().toString() - val result = instances.remove("$id/$KEY_WRITE_RESULT") as Pigeon.Result - if (status == BluetoothGatt.GATT_SUCCESS) { - result.success(null) - } else { - val error = BluetoothLowEnergyException("GATT write descriptor failed with status: $status.") - result.error(error) - } - } - - override fun onPhyRead(gatt: BluetoothGatt, txPhy: Int, rxPhy: Int, status: Int) { - super.onPhyRead(gatt, txPhy, rxPhy, status) - Log.d(TAG, "onPhyRead: $gatt, $txPhy, $rxPhy, $status") - } - - override fun onPhyUpdate(gatt: BluetoothGatt, txPhy: Int, rxPhy: Int, status: Int) { - super.onPhyUpdate(gatt, txPhy, rxPhy, status) - Log.d(TAG, "onPhyUpdate: $gatt, $txPhy, $rxPhy, $status") - } - - override fun onReadRemoteRssi(gatt: BluetoothGatt, rssi: Int, status: Int) { - super.onReadRemoteRssi(gatt, rssi, status) - Log.d(TAG, "onReadRemoteRssi: $gatt, $rssi, $status") - } - - override fun onReliableWriteCompleted(gatt: BluetoothGatt, status: Int) { - super.onReliableWriteCompleted(gatt, status) - Log.d(TAG, "onReliableWriteCompleted: $gatt, $status") - } - - override fun onServiceChanged(gatt: BluetoothGatt) { - super.onServiceChanged(gatt) - Log.d(TAG, "onServiceChanged: $gatt") - } -} diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt deleted file mode 100644 index f3605a6..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.BluetoothAdapter -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.util.Log - -object MyBroadcastReceiver : BroadcastReceiver() { - private const val STATE_UNKNOWN = -1 - - override fun onReceive(context: Context, intent: Intent) { - Log.d(TAG, "onReceive: $context, $intent") - val previousStateNumber = - intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, STATE_UNKNOWN).stateNumber - val stateNumber = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, STATE_UNKNOWN).stateNumber - if (stateNumber == previousStateNumber) return - centralFlutterApi.onStateChanged(stateNumber) {} - } -} \ No newline at end of file diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralManagerHostApi.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralManagerHostApi.kt deleted file mode 100644 index a42e893..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralManagerHostApi.kt +++ /dev/null @@ -1,64 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.le.ScanFilter -import android.bluetooth.le.ScanSettings -import android.content.pm.PackageManager -import android.os.Build -import android.os.ParcelUuid -import android.util.Log -import androidx.core.app.ActivityCompat -import dev.yanshouwang.bluetooth_low_energy.proto.UUID -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon - -object MyCentralManagerHostApi : Pigeon.CentralManagerHostApi { - const val REQUEST_CODE = 443 - - override fun authorize(result: Pigeon.Result) { - Log.d(TAG, "authorize: ") - val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_CONNECT) - } else { - arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION) - } - val authorized = permissions.all { permission -> - ActivityCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED - } - if (authorized) { - result.success(true) - } else { - ActivityCompat.requestPermissions(activity, permissions, REQUEST_CODE) - instances[KEY_AUTHORIZE_RESULT] = result - } - } - - override fun getState(): Long { - Log.d(TAG, "getState: ") - return bluetoothAdapter.stateNumber - } - - override fun startScan(uuidBuffers: MutableList?, result: Pigeon.Result) { - Log.d(TAG, "startScan: $uuidBuffers") - val filters = uuidBuffers?.map { buffer -> - val uuid = UUID.parseFrom(buffer).value - val serviceUUID = ParcelUuid.fromString(uuid) - ScanFilter.Builder().setServiceUuid(serviceUUID).build() - } - val settings = ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) - .build() - bluetoothAdapter.bluetoothLeScanner.startScan(filters, settings, MyScanCallback) - // Use main handler.post to delay until ScanCallback.onScanFailed executed. - mainHandler.post { - val error = instances.remove(KEY_START_SCAN_ERROR) as Throwable? - if (error == null) { - result.success(null) - } else { - result.error(error) - } - } - } - - override fun stopScan() { - Log.d(TAG, "stopScan: ") - bluetoothAdapter.bluetoothLeScanner.stopScan(MyScanCallback) - } -} \ No newline at end of file diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattCharacteristicHostApi.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattCharacteristicHostApi.kt deleted file mode 100644 index 9c682bf..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattCharacteristicHostApi.kt +++ /dev/null @@ -1,111 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.BluetoothGatt -import android.bluetooth.BluetoothGattCharacteristic -import android.bluetooth.BluetoothGattDescriptor -import android.util.Log -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon -import dev.yanshouwang.bluetooth_low_energy.proto.gattDescriptor -import dev.yanshouwang.bluetooth_low_energy.proto.uUID -import java.util.UUID - -object MyGattCharacteristicHostApi : Pigeon.GattCharacteristicHostApi { - private const val CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb" - - override fun free(id: String) { - Log.d(TAG, "free: $id") - unregister(id) - } - - override fun discoverDescriptors(id: String, result: Pigeon.Result>) { - Log.d(TAG, "discoverDescriptors: $id") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val characteristic = items[KEY_CHARACTERISTIC] as BluetoothGattCharacteristic - val descriptorValues = mutableListOf() - for (descriptor in characteristic.descriptors) { - val descriptorValue = registerDescriptor(gatt, descriptor) - descriptorValues.add(descriptorValue) - } - result.success(descriptorValues) - } - - private fun registerDescriptor(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor): ByteArray { - val id = descriptor.hashCode().toString() - val items = register(id) - items[KEY_GATT] = gatt - items[KEY_DESCRIPTOR] = descriptor - return gattDescriptor { - this.id = id - this.uuid = uUID { - this.value = descriptor.uuid.toString() - } - }.toByteArray() - } - - override fun read(id: String, result: Pigeon.Result) { - Log.d(TAG, "read: $id") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val characteristic = items[KEY_CHARACTERISTIC] as BluetoothGattCharacteristic - val succeed = gatt.readCharacteristic(characteristic) - if (succeed) { - instances["$id/$KEY_READ_RESULT"] = result - } else { - val error = BluetoothLowEnergyException("GATT read characteristic failed.") - result.error(error) - } - } - - override fun write(id: String, value: ByteArray, withoutResponse: Boolean, result: Pigeon.Result) { - Log.d(TAG, "write: $id, $value") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val characteristic = items[KEY_CHARACTERISTIC] as BluetoothGattCharacteristic - characteristic.writeType = if (withoutResponse) { - BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE - } else { - BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT - } - characteristic.value = value - val succeed = gatt.writeCharacteristic(characteristic) - if (succeed) { - instances["$id/$KEY_WRITE_RESULT"] = result - } else { - val error = BluetoothLowEnergyException("GATT write characteristic failed.") - result.error(error) - } - } - - override fun setNotify(id: String, value: Boolean, result: Pigeon.Result) { - Log.d(TAG, "setNotify: $id, $value") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val characteristic = items[KEY_CHARACTERISTIC] as BluetoothGattCharacteristic - val succeed = gatt.setCharacteristicNotification(characteristic, value) - if (succeed) { - writeClientCharacteristicConfig(gatt, characteristic, value, result) - } else { - val error = BluetoothLowEnergyException("GATT set characteristic notification failed.") - result.error(error) - } - } - - private fun writeClientCharacteristicConfig(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: Boolean, result: Pigeon.Result) { - val uuid = UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG) - val descriptor = characteristic.getDescriptor(uuid) - descriptor.value = if (value) { - BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE - } else { - BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE - } - val succeed = gatt.writeDescriptor(descriptor) - if (succeed) { - val id = descriptor.hashCode().toString() - instances["$id/$KEY_WRITE_RESULT"] = result - } else { - val error = BluetoothLowEnergyException("GATT write client characteristic config failed.") - result.error(error) - } - } -} diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattDescriptorHostApi.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattDescriptorHostApi.kt deleted file mode 100644 index 10093b2..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattDescriptorHostApi.kt +++ /dev/null @@ -1,42 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.BluetoothGatt -import android.bluetooth.BluetoothGattDescriptor -import android.util.Log -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon - -object MyGattDescriptorHostApi : Pigeon.GattDescriptorHostApi { - override fun free(id: String) { - Log.d(TAG, "free: $id") - unregister(id) - } - - override fun read(id: String, result: Pigeon.Result) { - Log.d(TAG, "read: $id") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val descriptor = items[KEY_DESCRIPTOR] as BluetoothGattDescriptor - val succeed = gatt.readDescriptor(descriptor) - if (succeed) { - instances["$id/$KEY_READ_RESULT"] = result - } else { - val error = BluetoothLowEnergyException("GATT read descriptor failed.") - result.error(error) - } - } - - override fun write(id: String, value: ByteArray, result: Pigeon.Result) { - Log.d(TAG, "write: $id, $value") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val descriptor = items[KEY_DESCRIPTOR] as BluetoothGattDescriptor - descriptor.value = value - val succeed = gatt.writeDescriptor(descriptor) - if (succeed) { - instances["$id/$KEY_WRITE_RESULT"] = result - } else { - val error = BluetoothLowEnergyException("GATT write descriptor failed.") - result.error(error) - } - } -} diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattServiceHostApi.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattServiceHostApi.kt deleted file mode 100644 index d7e23f6..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyGattServiceHostApi.kt +++ /dev/null @@ -1,47 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.BluetoothGatt -import android.bluetooth.BluetoothGattCharacteristic -import android.bluetooth.BluetoothGattService -import android.util.Log -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon -import dev.yanshouwang.bluetooth_low_energy.proto.gattCharacteristic -import dev.yanshouwang.bluetooth_low_energy.proto.uUID - -object MyGattServiceHostApi : Pigeon.GattServiceHostApi { - override fun free(id: String) { - Log.d(TAG, "free: $id") - unregister(id) - } - - override fun discoverCharacteristics(id: String, result: Pigeon.Result>) { - Log.d(TAG, "discoverCharacteristics: $id") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val service = items[KEY_SERVICE] as BluetoothGattService - val characteristicValues = mutableListOf() - for (characteristic in service.characteristics) { - val characteristicValue = registerCharacteristic(gatt, characteristic) - characteristicValues.add(characteristicValue) - } - result.success(characteristicValues) - } - - private fun registerCharacteristic(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic): ByteArray { - val id = characteristic.hashCode().toString() - val items = register(id) - items[KEY_GATT] = gatt - items[KEY_CHARACTERISTIC] = characteristic - return gattCharacteristic { - this.id = id - this.uuid = uUID { - this.value = characteristic.uuid.toString() - } - this.canRead = characteristic.properties and BluetoothGattCharacteristic.PROPERTY_READ != 0 - this.canWrite = characteristic.properties and BluetoothGattCharacteristic.PROPERTY_WRITE != 0 - this.canWriteWithoutResponse = - characteristic.properties and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE != 0 - this.canNotify = characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY != 0 - }.toByteArray() - } -} diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyPeripheralHostApi.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyPeripheralHostApi.kt deleted file mode 100644 index b5ea4a8..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyPeripheralHostApi.kt +++ /dev/null @@ -1,63 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.BluetoothDevice -import android.bluetooth.BluetoothGatt -import android.os.Build -import android.util.Log -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon - -object MyPeripheralHostApi : Pigeon.PeripheralHostApi { - override fun free(id: String) { - Log.d(TAG, "free: $id") - unregister(id) - } - - override fun connect(id: String, result: Pigeon.Result) { - Log.d(TAG, "connect: $id") - val items = instances[id] as MutableMap - val device = items[KEY_DEVICE] as BluetoothDevice - val autoConnect = false - val gatt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val transport = BluetoothDevice.TRANSPORT_LE - device.connectGatt(activity, autoConnect, MyBluetoothGattCallback, transport) - } else { - device.connectGatt(activity, autoConnect, MyBluetoothGattCallback) - } - items[KEY_GATT] = gatt - instances["$id/$KEY_CONNECT_RESULT"] = result - } - - override fun disconnect(id: String, result: Pigeon.Result) { - Log.d(TAG, "disconnect: $id") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - gatt.disconnect() - instances["$id/$KEY_DISCONNECT_RESULT"] = result - } - - override fun requestMtu(id: String, result: Pigeon.Result) { - Log.d(TAG, "requestMtu: $id") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val succeed = gatt.requestMtu(512) - if (succeed) { - instances["$id/$KEY_REQUEST_MTU_RESULT"] = result - } else { - val error = BluetoothLowEnergyException("GATT request MTU failed.") - result.error(error) - } - } - - override fun discoverServices(id: String, result: Pigeon.Result>) { - Log.d(TAG, "discoverServices: $id") - val items = instances[id] as MutableMap - val gatt = items[KEY_GATT] as BluetoothGatt - val succeed = gatt.discoverServices() - if (succeed) { - instances["$id/$KEY_DISCOVER_SERVICES_RESULT"] = result - } else { - val error = BluetoothLowEnergyException("GATT discover services failed.") - result.error(error) - } - } -} diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionsResultListener.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionsResultListener.kt deleted file mode 100644 index 6c50554..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionsResultListener.kt +++ /dev/null @@ -1,21 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.content.pm.PackageManager -import android.util.Log -import dev.yanshouwang.bluetooth_low_energy.pigeon.Messages as Pigeon -import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener - -object MyRequestPermissionsResultListener : RequestPermissionsResultListener { - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray): Boolean { - Log.d(TAG, "onRequestPermissionsResult: $requestCode, $permissions, $grantResults") - return when (requestCode) { - MyCentralManagerHostApi.REQUEST_CODE -> { - val result = instances.remove(KEY_AUTHORIZE_RESULT) as Pigeon.Result - val authorized = grantResults.all { grantResult -> grantResult == PackageManager.PERMISSION_GRANTED } - result.success(authorized) - true - } - else -> false - } - } -} \ No newline at end of file diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt deleted file mode 100644 index 06feee6..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt +++ /dev/null @@ -1,92 +0,0 @@ -package dev.yanshouwang.bluetooth_low_energy - -import android.bluetooth.le.ScanCallback -import android.bluetooth.le.ScanResult -import android.os.Build -import android.util.Log -import com.google.protobuf.ByteString -import dev.yanshouwang.bluetooth_low_energy.proto.* - -object MyScanCallback : ScanCallback() { - const val DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xff - - override fun onScanFailed(errorCode: Int) { - super.onScanFailed(errorCode) - Log.d(TAG, "onScanFailed: $errorCode") - val error = BluetoothLowEnergyException("Start scan failed with code: $errorCode") - instances[KEY_START_SCAN_ERROR] = error - } - - override fun onScanResult(callbackType: Int, result: ScanResult) { - super.onScanResult(callbackType, result) - Log.d(TAG, "onScanResult: $callbackType, $result") - onScanned(result) - } - - override fun onBatchScanResults(results: MutableList) { - super.onBatchScanResults(results) - Log.d(TAG, "onBatchScanResults: $results") - for (result in results) { - onScanned(result) - } - } - - private fun onScanned(result: ScanResult): Unit { - val device = result.device - val id = device.hashCode().toString() - val items = register(id) - items[KEY_DEVICE] = device - val broadcastValue = broadcast { - this.peripheral = peripheral { - this.id = id - this.uuid = result.device.uuid - } - this.rssi = result.rssi - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - this.connectable = result.isConnectable - } - val scanRecord = result.scanRecord - if (scanRecord == null) { - this.data = ByteString.EMPTY - } else { - this.data = ByteString.copyFrom(scanRecord.bytes) - val deviceName = scanRecord.deviceName - if (deviceName != null) { - this.localName = deviceName - } - val manufacturerSpecificData = scanRecord.rawManufacturerSpecificData - if (manufacturerSpecificData != null) { - this.manufacturerSpecificData = ByteString.copyFrom(manufacturerSpecificData) - } - val serviceDatas = scanRecord.serviceData.map { entry -> - serviceData { - this.uuid = uUID { - this.value = entry.key.toString() - } - this.data = ByteString.copyFrom(entry.value) - } - } - this.serviceDatas.addAll(serviceDatas) - val serviceUUIDs = scanRecord.serviceUuids - if (serviceUUIDs != null) { - val uuids = serviceUUIDs.map { uuid -> - uUID { - this.value = uuid.toString() - } - } - this.serviceUuids.addAll(uuids) - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - val uuids = scanRecord.serviceSolicitationUuids.map { uuid -> - uUID { - this.value = uuid.toString() - } - } - this.solicitedServiceUuids.addAll(uuids) - } - this.txPowerLevel = scanRecord.txPowerLevel - } - }.toByteArray() - centralFlutterApi.onScanned(broadcastValue) {} - } -} diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastKt.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastKt.kt deleted file mode 100644 index b59a7b4..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/BroadcastKt.kt +++ /dev/null @@ -1,395 +0,0 @@ -//Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -@kotlin.jvm.JvmName("-initializebroadcast") -inline fun broadcast(block: dev.yanshouwang.bluetooth_low_energy.proto.BroadcastKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.Broadcast = - dev.yanshouwang.bluetooth_low_energy.proto.BroadcastKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.newBuilder()).apply { block() }._build() -object BroadcastKt { - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - @com.google.protobuf.kotlin.ProtoDslMarker - class Dsl private constructor( - private val _builder: dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.Builder - ) { - companion object { - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.Builder): Dsl = Dsl(builder) - } - - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _build(): dev.yanshouwang.bluetooth_low_energy.proto.Broadcast = _builder.build() - - /** - * .proto.Peripheral peripheral = 1; - */ - var peripheral: dev.yanshouwang.bluetooth_low_energy.proto.Peripheral - @JvmName("getPeripheral") - get() = _builder.getPeripheral() - @JvmName("setPeripheral") - set(value) { - _builder.setPeripheral(value) - } - /** - * .proto.Peripheral peripheral = 1; - */ - fun clearPeripheral() { - _builder.clearPeripheral() - } - /** - * .proto.Peripheral peripheral = 1; - * @return Whether the peripheral field is set. - */ - fun hasPeripheral(): kotlin.Boolean { - return _builder.hasPeripheral() - } - - /** - * int32 rssi = 2; - */ - var rssi: kotlin.Int - @JvmName("getRssi") - get() = _builder.getRssi() - @JvmName("setRssi") - set(value) { - _builder.setRssi(value) - } - /** - * int32 rssi = 2; - */ - fun clearRssi() { - _builder.clearRssi() - } - - /** - * optional bool connectable = 3; - */ - var connectable: kotlin.Boolean - @JvmName("getConnectable") - get() = _builder.getConnectable() - @JvmName("setConnectable") - set(value) { - _builder.setConnectable(value) - } - /** - * optional bool connectable = 3; - */ - fun clearConnectable() { - _builder.clearConnectable() - } - /** - * optional bool connectable = 3; - * @return Whether the connectable field is set. - */ - fun hasConnectable(): kotlin.Boolean { - return _builder.hasConnectable() - } - - /** - * bytes data = 4; - */ - var data: com.google.protobuf.ByteString - @JvmName("getData") - get() = _builder.getData() - @JvmName("setData") - set(value) { - _builder.setData(value) - } - /** - * bytes data = 4; - */ - fun clearData() { - _builder.clearData() - } - - /** - * optional string local_name = 5; - */ - var localName: kotlin.String - @JvmName("getLocalName") - get() = _builder.getLocalName() - @JvmName("setLocalName") - set(value) { - _builder.setLocalName(value) - } - /** - * optional string local_name = 5; - */ - fun clearLocalName() { - _builder.clearLocalName() - } - /** - * optional string local_name = 5; - * @return Whether the localName field is set. - */ - fun hasLocalName(): kotlin.Boolean { - return _builder.hasLocalName() - } - - /** - * bytes manufacturer_specific_data = 6; - */ - var manufacturerSpecificData: com.google.protobuf.ByteString - @JvmName("getManufacturerSpecificData") - get() = _builder.getManufacturerSpecificData() - @JvmName("setManufacturerSpecificData") - set(value) { - _builder.setManufacturerSpecificData(value) - } - /** - * bytes manufacturer_specific_data = 6; - */ - fun clearManufacturerSpecificData() { - _builder.clearManufacturerSpecificData() - } - - /** - * An uninstantiable, behaviorless type to represent the field in - * generics. - */ - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - class ServiceDatasProxy private constructor() : com.google.protobuf.kotlin.DslProxy() - /** - * repeated .proto.ServiceData service_datas = 7; - */ - val serviceDatas: com.google.protobuf.kotlin.DslList - @kotlin.jvm.JvmSynthetic - get() = com.google.protobuf.kotlin.DslList( - _builder.getServiceDatasList() - ) - /** - * repeated .proto.ServiceData service_datas = 7; - * @param value The serviceDatas to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("addServiceDatas") - fun com.google.protobuf.kotlin.DslList.add(value: dev.yanshouwang.bluetooth_low_energy.proto.ServiceData) { - _builder.addServiceDatas(value) - } - /** - * repeated .proto.ServiceData service_datas = 7; - * @param value The serviceDatas to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("plusAssignServiceDatas") - @Suppress("NOTHING_TO_INLINE") - inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: dev.yanshouwang.bluetooth_low_energy.proto.ServiceData) { - add(value) - } - /** - * repeated .proto.ServiceData service_datas = 7; - * @param values The serviceDatas to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("addAllServiceDatas") - fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { - _builder.addAllServiceDatas(values) - } - /** - * repeated .proto.ServiceData service_datas = 7; - * @param values The serviceDatas to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("plusAssignAllServiceDatas") - @Suppress("NOTHING_TO_INLINE") - inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { - addAll(values) - } - /** - * repeated .proto.ServiceData service_datas = 7; - * @param index The index to set the value at. - * @param value The serviceDatas to set. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("setServiceDatas") - operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: dev.yanshouwang.bluetooth_low_energy.proto.ServiceData) { - _builder.setServiceDatas(index, value) - } - /** - * repeated .proto.ServiceData service_datas = 7; - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("clearServiceDatas") - fun com.google.protobuf.kotlin.DslList.clear() { - _builder.clearServiceDatas() - } - - - /** - * An uninstantiable, behaviorless type to represent the field in - * generics. - */ - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - class ServiceUuidsProxy private constructor() : com.google.protobuf.kotlin.DslProxy() - /** - * repeated .proto.UUID service_uuids = 8; - */ - val serviceUuids: com.google.protobuf.kotlin.DslList - @kotlin.jvm.JvmSynthetic - get() = com.google.protobuf.kotlin.DslList( - _builder.getServiceUuidsList() - ) - /** - * repeated .proto.UUID service_uuids = 8; - * @param value The serviceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("addServiceUuids") - fun com.google.protobuf.kotlin.DslList.add(value: dev.yanshouwang.bluetooth_low_energy.proto.UUID) { - _builder.addServiceUuids(value) - } - /** - * repeated .proto.UUID service_uuids = 8; - * @param value The serviceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("plusAssignServiceUuids") - @Suppress("NOTHING_TO_INLINE") - inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: dev.yanshouwang.bluetooth_low_energy.proto.UUID) { - add(value) - } - /** - * repeated .proto.UUID service_uuids = 8; - * @param values The serviceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("addAllServiceUuids") - fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { - _builder.addAllServiceUuids(values) - } - /** - * repeated .proto.UUID service_uuids = 8; - * @param values The serviceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("plusAssignAllServiceUuids") - @Suppress("NOTHING_TO_INLINE") - inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { - addAll(values) - } - /** - * repeated .proto.UUID service_uuids = 8; - * @param index The index to set the value at. - * @param value The serviceUuids to set. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("setServiceUuids") - operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: dev.yanshouwang.bluetooth_low_energy.proto.UUID) { - _builder.setServiceUuids(index, value) - } - /** - * repeated .proto.UUID service_uuids = 8; - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("clearServiceUuids") - fun com.google.protobuf.kotlin.DslList.clear() { - _builder.clearServiceUuids() - } - - - /** - * An uninstantiable, behaviorless type to represent the field in - * generics. - */ - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - class SolicitedServiceUuidsProxy private constructor() : com.google.protobuf.kotlin.DslProxy() - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - val solicitedServiceUuids: com.google.protobuf.kotlin.DslList - @kotlin.jvm.JvmSynthetic - get() = com.google.protobuf.kotlin.DslList( - _builder.getSolicitedServiceUuidsList() - ) - /** - * repeated .proto.UUID solicited_service_uuids = 9; - * @param value The solicitedServiceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("addSolicitedServiceUuids") - fun com.google.protobuf.kotlin.DslList.add(value: dev.yanshouwang.bluetooth_low_energy.proto.UUID) { - _builder.addSolicitedServiceUuids(value) - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - * @param value The solicitedServiceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("plusAssignSolicitedServiceUuids") - @Suppress("NOTHING_TO_INLINE") - inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: dev.yanshouwang.bluetooth_low_energy.proto.UUID) { - add(value) - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - * @param values The solicitedServiceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("addAllSolicitedServiceUuids") - fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { - _builder.addAllSolicitedServiceUuids(values) - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - * @param values The solicitedServiceUuids to add. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("plusAssignAllSolicitedServiceUuids") - @Suppress("NOTHING_TO_INLINE") - inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { - addAll(values) - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - * @param index The index to set the value at. - * @param value The solicitedServiceUuids to set. - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("setSolicitedServiceUuids") - operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: dev.yanshouwang.bluetooth_low_energy.proto.UUID) { - _builder.setSolicitedServiceUuids(index, value) - } - /** - * repeated .proto.UUID solicited_service_uuids = 9; - */ - @kotlin.jvm.JvmSynthetic - @kotlin.jvm.JvmName("clearSolicitedServiceUuids") - fun com.google.protobuf.kotlin.DslList.clear() { - _builder.clearSolicitedServiceUuids() - } - - - /** - * optional int32 tx_power_level = 10; - */ - var txPowerLevel: kotlin.Int - @JvmName("getTxPowerLevel") - get() = _builder.getTxPowerLevel() - @JvmName("setTxPowerLevel") - set(value) { - _builder.setTxPowerLevel(value) - } - /** - * optional int32 tx_power_level = 10; - */ - fun clearTxPowerLevel() { - _builder.clearTxPowerLevel() - } - /** - * optional int32 tx_power_level = 10; - * @return Whether the txPowerLevel field is set. - */ - fun hasTxPowerLevel(): kotlin.Boolean { - return _builder.hasTxPowerLevel() - } - } -} -@kotlin.jvm.JvmSynthetic -inline fun dev.yanshouwang.bluetooth_low_energy.proto.Broadcast.copy(block: dev.yanshouwang.bluetooth_low_energy.proto.BroadcastKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.Broadcast = - dev.yanshouwang.bluetooth_low_energy.proto.BroadcastKt.Dsl._create(this.toBuilder()).apply { block() }._build() - -val dev.yanshouwang.bluetooth_low_energy.proto.BroadcastOrBuilder.peripheralOrNull: dev.yanshouwang.bluetooth_low_energy.proto.Peripheral? - get() = if (hasPeripheral()) getPeripheral() else null - diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicKt.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicKt.kt deleted file mode 100644 index fccaf9c..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattCharacteristicKt.kt +++ /dev/null @@ -1,141 +0,0 @@ -//Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -@kotlin.jvm.JvmName("-initializegattCharacteristic") -inline fun gattCharacteristic(block: dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristicKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic = - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristicKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.newBuilder()).apply { block() }._build() -object GattCharacteristicKt { - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - @com.google.protobuf.kotlin.ProtoDslMarker - class Dsl private constructor( - private val _builder: dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.Builder - ) { - companion object { - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.Builder): Dsl = Dsl(builder) - } - - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _build(): dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic = _builder.build() - - /** - * string id = 1; - */ - var id: kotlin.String - @JvmName("getId") - get() = _builder.getId() - @JvmName("setId") - set(value) { - _builder.setId(value) - } - /** - * string id = 1; - */ - fun clearId() { - _builder.clearId() - } - - /** - * .proto.UUID uuid = 2; - */ - var uuid: dev.yanshouwang.bluetooth_low_energy.proto.UUID - @JvmName("getUuid") - get() = _builder.getUuid() - @JvmName("setUuid") - set(value) { - _builder.setUuid(value) - } - /** - * .proto.UUID uuid = 2; - */ - fun clearUuid() { - _builder.clearUuid() - } - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - fun hasUuid(): kotlin.Boolean { - return _builder.hasUuid() - } - - /** - * bool can_read = 3; - */ - var canRead: kotlin.Boolean - @JvmName("getCanRead") - get() = _builder.getCanRead() - @JvmName("setCanRead") - set(value) { - _builder.setCanRead(value) - } - /** - * bool can_read = 3; - */ - fun clearCanRead() { - _builder.clearCanRead() - } - - /** - * bool can_write = 4; - */ - var canWrite: kotlin.Boolean - @JvmName("getCanWrite") - get() = _builder.getCanWrite() - @JvmName("setCanWrite") - set(value) { - _builder.setCanWrite(value) - } - /** - * bool can_write = 4; - */ - fun clearCanWrite() { - _builder.clearCanWrite() - } - - /** - * bool can_write_without_response = 5; - */ - var canWriteWithoutResponse: kotlin.Boolean - @JvmName("getCanWriteWithoutResponse") - get() = _builder.getCanWriteWithoutResponse() - @JvmName("setCanWriteWithoutResponse") - set(value) { - _builder.setCanWriteWithoutResponse(value) - } - /** - * bool can_write_without_response = 5; - */ - fun clearCanWriteWithoutResponse() { - _builder.clearCanWriteWithoutResponse() - } - - /** - * bool can_notify = 6; - */ - var canNotify: kotlin.Boolean - @JvmName("getCanNotify") - get() = _builder.getCanNotify() - @JvmName("setCanNotify") - set(value) { - _builder.setCanNotify(value) - } - /** - * bool can_notify = 6; - */ - fun clearCanNotify() { - _builder.clearCanNotify() - } - } -} -@kotlin.jvm.JvmSynthetic -inline fun dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic.copy(block: dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristicKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristic = - dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristicKt.Dsl._create(this.toBuilder()).apply { block() }._build() - -val dev.yanshouwang.bluetooth_low_energy.proto.GattCharacteristicOrBuilder.uuidOrNull: dev.yanshouwang.bluetooth_low_energy.proto.UUID? - get() = if (hasUuid()) getUuid() else null - diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorKt.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorKt.kt deleted file mode 100644 index 20a1c62..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattDescriptorKt.kt +++ /dev/null @@ -1,73 +0,0 @@ -//Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -@kotlin.jvm.JvmName("-initializegattDescriptor") -inline fun gattDescriptor(block: dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptorKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor = - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptorKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.newBuilder()).apply { block() }._build() -object GattDescriptorKt { - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - @com.google.protobuf.kotlin.ProtoDslMarker - class Dsl private constructor( - private val _builder: dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.Builder - ) { - companion object { - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.Builder): Dsl = Dsl(builder) - } - - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _build(): dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor = _builder.build() - - /** - * string id = 1; - */ - var id: kotlin.String - @JvmName("getId") - get() = _builder.getId() - @JvmName("setId") - set(value) { - _builder.setId(value) - } - /** - * string id = 1; - */ - fun clearId() { - _builder.clearId() - } - - /** - * .proto.UUID uuid = 2; - */ - var uuid: dev.yanshouwang.bluetooth_low_energy.proto.UUID - @JvmName("getUuid") - get() = _builder.getUuid() - @JvmName("setUuid") - set(value) { - _builder.setUuid(value) - } - /** - * .proto.UUID uuid = 2; - */ - fun clearUuid() { - _builder.clearUuid() - } - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - fun hasUuid(): kotlin.Boolean { - return _builder.hasUuid() - } - } -} -@kotlin.jvm.JvmSynthetic -inline fun dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor.copy(block: dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptorKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptor = - dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptorKt.Dsl._create(this.toBuilder()).apply { block() }._build() - -val dev.yanshouwang.bluetooth_low_energy.proto.GattDescriptorOrBuilder.uuidOrNull: dev.yanshouwang.bluetooth_low_energy.proto.UUID? - get() = if (hasUuid()) getUuid() else null - diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceKt.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceKt.kt deleted file mode 100644 index 8837a4f..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/GattServiceKt.kt +++ /dev/null @@ -1,73 +0,0 @@ -//Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -@kotlin.jvm.JvmName("-initializegattService") -inline fun gattService(block: dev.yanshouwang.bluetooth_low_energy.proto.GattServiceKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.GattService = - dev.yanshouwang.bluetooth_low_energy.proto.GattServiceKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.proto.GattService.newBuilder()).apply { block() }._build() -object GattServiceKt { - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - @com.google.protobuf.kotlin.ProtoDslMarker - class Dsl private constructor( - private val _builder: dev.yanshouwang.bluetooth_low_energy.proto.GattService.Builder - ) { - companion object { - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.proto.GattService.Builder): Dsl = Dsl(builder) - } - - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _build(): dev.yanshouwang.bluetooth_low_energy.proto.GattService = _builder.build() - - /** - * string id = 1; - */ - var id: kotlin.String - @JvmName("getId") - get() = _builder.getId() - @JvmName("setId") - set(value) { - _builder.setId(value) - } - /** - * string id = 1; - */ - fun clearId() { - _builder.clearId() - } - - /** - * .proto.UUID uuid = 2; - */ - var uuid: dev.yanshouwang.bluetooth_low_energy.proto.UUID - @JvmName("getUuid") - get() = _builder.getUuid() - @JvmName("setUuid") - set(value) { - _builder.setUuid(value) - } - /** - * .proto.UUID uuid = 2; - */ - fun clearUuid() { - _builder.clearUuid() - } - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - fun hasUuid(): kotlin.Boolean { - return _builder.hasUuid() - } - } -} -@kotlin.jvm.JvmSynthetic -inline fun dev.yanshouwang.bluetooth_low_energy.proto.GattService.copy(block: dev.yanshouwang.bluetooth_low_energy.proto.GattServiceKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.GattService = - dev.yanshouwang.bluetooth_low_energy.proto.GattServiceKt.Dsl._create(this.toBuilder()).apply { block() }._build() - -val dev.yanshouwang.bluetooth_low_energy.proto.GattServiceOrBuilder.uuidOrNull: dev.yanshouwang.bluetooth_low_energy.proto.UUID? - get() = if (hasUuid()) getUuid() else null - diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralKt.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralKt.kt deleted file mode 100644 index 7eadd5c..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/PeripheralKt.kt +++ /dev/null @@ -1,73 +0,0 @@ -//Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -@kotlin.jvm.JvmName("-initializeperipheral") -inline fun peripheral(block: dev.yanshouwang.bluetooth_low_energy.proto.PeripheralKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.Peripheral = - dev.yanshouwang.bluetooth_low_energy.proto.PeripheralKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.newBuilder()).apply { block() }._build() -object PeripheralKt { - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - @com.google.protobuf.kotlin.ProtoDslMarker - class Dsl private constructor( - private val _builder: dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder - ) { - companion object { - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.Builder): Dsl = Dsl(builder) - } - - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _build(): dev.yanshouwang.bluetooth_low_energy.proto.Peripheral = _builder.build() - - /** - * string id = 1; - */ - var id: kotlin.String - @JvmName("getId") - get() = _builder.getId() - @JvmName("setId") - set(value) { - _builder.setId(value) - } - /** - * string id = 1; - */ - fun clearId() { - _builder.clearId() - } - - /** - * .proto.UUID uuid = 2; - */ - var uuid: dev.yanshouwang.bluetooth_low_energy.proto.UUID - @JvmName("getUuid") - get() = _builder.getUuid() - @JvmName("setUuid") - set(value) { - _builder.setUuid(value) - } - /** - * .proto.UUID uuid = 2; - */ - fun clearUuid() { - _builder.clearUuid() - } - /** - * .proto.UUID uuid = 2; - * @return Whether the uuid field is set. - */ - fun hasUuid(): kotlin.Boolean { - return _builder.hasUuid() - } - } -} -@kotlin.jvm.JvmSynthetic -inline fun dev.yanshouwang.bluetooth_low_energy.proto.Peripheral.copy(block: dev.yanshouwang.bluetooth_low_energy.proto.PeripheralKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.Peripheral = - dev.yanshouwang.bluetooth_low_energy.proto.PeripheralKt.Dsl._create(this.toBuilder()).apply { block() }._build() - -val dev.yanshouwang.bluetooth_low_energy.proto.PeripheralOrBuilder.uuidOrNull: dev.yanshouwang.bluetooth_low_energy.proto.UUID? - get() = if (hasUuid()) getUuid() else null - diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataKt.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataKt.kt deleted file mode 100644 index 9c2ec89..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/ServiceDataKt.kt +++ /dev/null @@ -1,73 +0,0 @@ -//Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -@kotlin.jvm.JvmName("-initializeserviceData") -inline fun serviceData(block: dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.ServiceData = - dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.newBuilder()).apply { block() }._build() -object ServiceDataKt { - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - @com.google.protobuf.kotlin.ProtoDslMarker - class Dsl private constructor( - private val _builder: dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder - ) { - companion object { - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.Builder): Dsl = Dsl(builder) - } - - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _build(): dev.yanshouwang.bluetooth_low_energy.proto.ServiceData = _builder.build() - - /** - * .proto.UUID uuid = 1; - */ - var uuid: dev.yanshouwang.bluetooth_low_energy.proto.UUID - @JvmName("getUuid") - get() = _builder.getUuid() - @JvmName("setUuid") - set(value) { - _builder.setUuid(value) - } - /** - * .proto.UUID uuid = 1; - */ - fun clearUuid() { - _builder.clearUuid() - } - /** - * .proto.UUID uuid = 1; - * @return Whether the uuid field is set. - */ - fun hasUuid(): kotlin.Boolean { - return _builder.hasUuid() - } - - /** - * bytes data = 2; - */ - var data: com.google.protobuf.ByteString - @JvmName("getData") - get() = _builder.getData() - @JvmName("setData") - set(value) { - _builder.setData(value) - } - /** - * bytes data = 2; - */ - fun clearData() { - _builder.clearData() - } - } -} -@kotlin.jvm.JvmSynthetic -inline fun dev.yanshouwang.bluetooth_low_energy.proto.ServiceData.copy(block: dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.ServiceData = - dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataKt.Dsl._create(this.toBuilder()).apply { block() }._build() - -val dev.yanshouwang.bluetooth_low_energy.proto.ServiceDataOrBuilder.uuidOrNull: dev.yanshouwang.bluetooth_low_energy.proto.UUID? - get() = if (hasUuid()) getUuid() else null - diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/UUIDKt.kt b/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/UUIDKt.kt deleted file mode 100644 index cb9ed3d..0000000 --- a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/UUIDKt.kt +++ /dev/null @@ -1,46 +0,0 @@ -//Generated by the protocol buffer compiler. DO NOT EDIT! -// source: proto/messages.proto - -package dev.yanshouwang.bluetooth_low_energy.proto; - -@kotlin.jvm.JvmName("-initializeuUID") -inline fun uUID(block: dev.yanshouwang.bluetooth_low_energy.proto.UUIDKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.UUID = - dev.yanshouwang.bluetooth_low_energy.proto.UUIDKt.Dsl._create(dev.yanshouwang.bluetooth_low_energy.proto.UUID.newBuilder()).apply { block() }._build() -object UUIDKt { - @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) - @com.google.protobuf.kotlin.ProtoDslMarker - class Dsl private constructor( - private val _builder: dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder - ) { - companion object { - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _create(builder: dev.yanshouwang.bluetooth_low_energy.proto.UUID.Builder): Dsl = Dsl(builder) - } - - @kotlin.jvm.JvmSynthetic - @kotlin.PublishedApi - internal fun _build(): dev.yanshouwang.bluetooth_low_energy.proto.UUID = _builder.build() - - /** - * string value = 1; - */ - var value: kotlin.String - @JvmName("getValue") - get() = _builder.getValue() - @JvmName("setValue") - set(value) { - _builder.setValue(value) - } - /** - * string value = 1; - */ - fun clearValue() { - _builder.clearValue() - } - } -} -@kotlin.jvm.JvmSynthetic -inline fun dev.yanshouwang.bluetooth_low_energy.proto.UUID.copy(block: dev.yanshouwang.bluetooth_low_energy.proto.UUIDKt.Dsl.() -> kotlin.Unit): dev.yanshouwang.bluetooth_low_energy.proto.UUID = - dev.yanshouwang.bluetooth_low_energy.proto.UUIDKt.Dsl._create(this.toBuilder()).apply { block() }._build() - diff --git a/.gitignore b/bluetooth_low_energy/.gitignore similarity index 100% rename from .gitignore rename to bluetooth_low_energy/.gitignore diff --git a/bluetooth_low_energy/.metadata b/bluetooth_low_energy/.metadata new file mode 100644 index 0000000..226b72c --- /dev/null +++ b/bluetooth_low_energy/.metadata @@ -0,0 +1,42 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + - platform: android + create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + - platform: ios + create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + - platform: linux + create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + - platform: macos + create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + - platform: windows + create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/CHANGELOG.md b/bluetooth_low_energy/CHANGELOG.md similarity index 85% rename from CHANGELOG.md rename to bluetooth_low_energy/CHANGELOG.md index b442eb4..e252a4a 100644 --- a/CHANGELOG.md +++ b/bluetooth_low_energy/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.0 + +- Rewrite the whole project with federated plugins. +- Support macOS and Linux. + ## 1.1.0 - Fix the crash by onMtuChanged called multi-times on Android. @@ -27,4 +32,4 @@ - Add central APIs. - Add implementations on Android. - Add example. -- Add test. +- Add test. \ No newline at end of file diff --git a/bluetooth_low_energy/LICENSE b/bluetooth_low_energy/LICENSE new file mode 100644 index 0000000..515ed4b --- /dev/null +++ b/bluetooth_low_energy/LICENSE @@ -0,0 +1,21 @@ +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. \ No newline at end of file diff --git a/bluetooth_low_energy/README.md b/bluetooth_low_energy/README.md new file mode 100644 index 0000000..e95ee9c --- /dev/null +++ b/bluetooth_low_energy/README.md @@ -0,0 +1,47 @@ +# bluetooth_low_energy + +A Flutter plugin for controlling the bluetooth low energy. + +## Features + +### CentralController + +- [x] SetUp/TearDown central controller. +- [x] Get/Listen central state. +- [x] Start/Stop discovery. +- [x] Connect/Disconnect peripherals. +- [x] Discover GATT. +- [x] Get GATT services. +- [x] Get GATT characteristics. +- [x] Get GATT descriptors. +- [x] Read/Write/Notify GATT characteristics. +- [x] Read/Write GATT descriptors. + +## Getting Started + +Add `bluetooth_low_energy` as a [dependency in your pubspec.yaml file](https://flutter.dev/using-packages/). + +``` +dependencies: + bluetooth_low_energy: ^ +``` + +Remember to call `await CentralController.setUp()` before use any apis of this plugin. + +*Note*: Bluetooth Low Energy doesn't work on emulators, so use physical devices which has bluetooth features for development. + +### Android + +Make sure you have a `miniSdkVersion` with 21 or higher in your `android/app/build.gradle` file. + +### iOS and macOS + +According to Apple's [documents](https://developer.apple.com/documentation/corebluetooth/), you must include the [`NSBluetoothAlwaysUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothalwaysusagedescription) on or after iOS 13, and include the [`NSBluetoothPeripheralUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothperipheralusagedescription) key before iOS 13. + +### Linux + +Not tested yet, if you occured any problems, file an issue to let me know about it, i will fix it as soon as possible. + +### Windows + +Not implemented yet but maybe someday or someone can use the `win32` api to implement this plugin_interface or someday the flutter team support C# on windows platform or someday I am familiar with C++ language... \ No newline at end of file diff --git a/bluetooth_low_energy/analysis_options.yaml b/bluetooth_low_energy/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/bluetooth_low_energy/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/example/.gitignore b/bluetooth_low_energy/example/.gitignore similarity index 93% rename from example/.gitignore rename to bluetooth_low_energy/example/.gitignore index a8e938c..24476c5 100644 --- a/example/.gitignore +++ b/bluetooth_low_energy/example/.gitignore @@ -32,9 +32,6 @@ migrate_working_dir/ .pub/ /build/ -# Web related -lib/generated_plugin_registrant.dart - # Symbolication related app.*.symbols diff --git a/example/README.md b/bluetooth_low_energy/example/README.md similarity index 100% rename from example/README.md rename to bluetooth_low_energy/example/README.md diff --git a/example/analysis_options.yaml b/bluetooth_low_energy/example/analysis_options.yaml similarity index 100% rename from example/analysis_options.yaml rename to bluetooth_low_energy/example/analysis_options.yaml diff --git a/example/android/.gitignore b/bluetooth_low_energy/example/android/.gitignore similarity index 100% rename from example/android/.gitignore rename to bluetooth_low_energy/example/android/.gitignore diff --git a/example/android/app/build.gradle b/bluetooth_low_energy/example/android/app/build.gradle similarity index 88% rename from example/android/app/build.gradle rename to bluetooth_low_energy/example/android/app/build.gradle index 7deef07..0a7b461 100644 --- a/example/android/app/build.gradle +++ b/bluetooth_low_energy/example/android/app/build.gradle @@ -1,7 +1,8 @@ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) } } @@ -25,6 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { + namespace "dev.yanshouwang.bluetooth_low_energy_example" compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion @@ -45,7 +47,8 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "dev.yanshouwang.bluetooth_low_energy_example" // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + // minSdkVersion flutter.minSdkVersion minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() diff --git a/example/android/app/src/debug/AndroidManifest.xml b/bluetooth_low_energy/example/android/app/src/debug/AndroidManifest.xml similarity index 85% rename from example/android/app/src/debug/AndroidManifest.xml rename to bluetooth_low_energy/example/android/app/src/debug/AndroidManifest.xml index f695679..399f698 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/bluetooth_low_energy/example/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,4 @@ - + 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 literal 0 HcmV?d00001 diff --git a/bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000000000000000000000000000000000000..0a3f5fa40fb3d1e0710331a48de5d256da3f275d GIT binary patch literal 520 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uuz(rC1}QWNE&K#jR^;j87-Auq zoUlN^K{r-Q+XN;zI ze|?*NFmgt#V#GwrSWaz^2G&@SBmck6ZcIFMww~vE<1E?M2#KUn1CzsB6D2+0SuRV@ zV2kK5HvIGB{HX-hQzs0*AB%5$9RJ@a;)Ahq#p$GSP91^&hi#6sg*;a~dt}4AclK>h z_3MoPRQ{i;==;*1S-mY<(JFzhAxMI&<61&m$J0NDHdJ3tYx~j0%M-uN6Zl8~_0DOkGXc0001@sz3l12C6Xg{AT~( zm6w64BA|AX`Ve)YY-glyudNN>MAfkXz-T7`_`fEolM;0T0BA)(02-OaW z0*cW7Z~ec94o8&g0D$N>b!COu{=m}^%oXZ4?T8ZyPZuGGBPBA7pbQMoV5HYhiT?%! zcae~`(QAN4&}-=#2f5fkn!SWGWmSeCISBcS=1-U|MEoKq=k?_x3apK>9((R zuu$9X?^8?@(a{qMS%J8SJPq))v}Q-ZyDm6Gbie0m92=`YlwnQPQP1kGSm(N2UJ3P6 z^{p-u)SSCTW~c1rw;cM)-uL2{->wCn2{#%;AtCQ!m%AakVs1K#v@(*-6QavyY&v&*wO_rCJXJuq$c$7ZjsW+pJo-$L^@!7X04CvaOpPyfw|FKvu;e(&Iw>Tbg zL}#8e^?X%TReXTt>gsBByt0kSU20oQx*~P=4`&tcZ7N6t-6LiK{LxX*p6}9c<0Pu^ zLx1w_P4P2V>bX=`F%v$#{sUDdF|;rbI{p#ZW`00Bgh(eB(nOIhy8W9T>3aQ=k8Z9% zB+TusFABF~J?N~fAd}1Rme=@4+1=M{^P`~se7}e3;mY0!%#MJf!XSrUC{0uZqMAd7%q zQY#$A>q}noIB4g54Ue)x>ofVm3DKBbUmS4Z-bm7KdKsUixva)1*&z5rgAG2gxG+_x zqT-KNY4g7eM!?>==;uD9Y4iI(Hu$pl8!LrK_Zb}5nv(XKW{9R144E!cFf36p{i|8pRL~p`_^iNo z{mf7y`#hejw#^#7oKPlN_Td{psNpNnM?{7{R-ICBtYxk>?3}OTH_8WkfaTLw)ZRTfxjW+0>gMe zpKg~`Bc$Y>^VX;ks^J0oKhB#6Ukt{oQhN+o2FKGZx}~j`cQB%vVsMFnm~R_1Y&Ml? zwFfb~d|dW~UktY@?zkau>Owe zRroi(<)c4Ux&wJfY=3I=vg)uh;sL(IYY9r$WK1$F;jYqq1>xT{LCkIMb3t2jN8d`9 z=4(v-z7vHucc_fjkpS}mGC{ND+J-hc_0Ix4kT^~{-2n|;Jmn|Xf9wGudDk7bi*?^+ z7fku8z*mbkGm&xf&lmu#=b5mp{X(AwtLTf!N`7FmOmX=4xwbD=fEo8CaB1d1=$|)+ z+Dlf^GzGOdlqTO8EwO?8;r+b;gkaF^$;+#~2_YYVH!hD6r;PaWdm#V=BJ1gH9ZK_9 zrAiIC-)z)hRq6i5+$JVmR!m4P>3yJ%lH)O&wtCyum3A*})*fHODD2nq!1@M>t@Za+ zH6{(Vf>_7!I-APmpsGLYpl7jww@s5hHOj5LCQXh)YAp+y{gG(0UMm(Ur z3o3n36oFwCkn+H*GZ-c6$Y!5r3z*@z0`NrB2C^q#LkOuooUM8Oek2KBk}o1PU8&2L z4iNkb5CqJWs58aR394iCU^ImDqV;q_Pp?pl=RB2372(Io^GA^+oKguO1(x$0<7w3z z)j{vnqEB679Rz4i4t;8|&Zg77UrklxY9@GDq(ZphH6=sW`;@uIt5B?7Oi?A0-BL}(#1&R;>2aFdq+E{jsvpNHjLx2t{@g1}c~DQcPNmVmy| zNMO@ewD^+T!|!DCOf}s9dLJU}(KZy@Jc&2Nq3^;vHTs}Hgcp`cw&gd7#N}nAFe3cM1TF%vKbKSffd&~FG9y$gLyr{#to)nxz5cCASEzQ}gz8O)phtHuKOW6p z@EQF(R>j%~P63Wfosrz8p(F=D|Mff~chUGn(<=CQbSiZ{t!e zeDU-pPsLgtc#d`3PYr$i*AaT!zF#23htIG&?QfcUk+@k$LZI}v+js|yuGmE!PvAV3 ztzh90rK-0L6P}s?1QH`Ot@ilbgMBzWIs zIs6K<_NL$O4lwR%zH4oJ+}JJp-bL6~%k&p)NGDMNZX7)0kni&%^sH|T?A)`z z=adV?!qnWx^B$|LD3BaA(G=ePL1+}8iu^SnnD;VE1@VLHMVdSN9$d)R(Wk{JEOp(P zm3LtAL$b^*JsQ0W&eLaoYag~=fRRdI>#FaELCO7L>zXe6w*nxN$Iy*Q*ftHUX0+N- zU>{D_;RRVPbQ?U+$^%{lhOMKyE5>$?U1aEPist+r)b47_LehJGTu>TcgZe&J{ z{q&D{^Ps~z7|zj~rpoh2I_{gAYNoCIJmio3B}$!5vTF*h$Q*vFj~qbo%bJCCRy509 zHTdDh_HYH8Zb9`}D5;;J9fkWOQi%Y$B1!b9+ESj+B@dtAztlY2O3NE<6HFiqOF&p_ zW-K`KiY@RPSY-p9Q99}Hcd05DT79_pfb{BV7r~?9pWh=;mcKBLTen%THFPo2NN~Nf zriOtFnqx}rtO|A6k!r6 zf-z?y-UD{dT0kT9FJ`-oWuPHbo+3wBS(}?2ql(+e@VTExmfnB*liCb zmeI+v5*+W_L;&kQN^ChW{jE0Mw#0Tfs}`9bk3&7UjxP^Ke(%eJu2{VnW?tu7Iqecm zB5|=-QdzK$=h50~{X3*w4%o1FS_u(dG2s&427$lJ?6bkLet}yYXCy)u_Io1&g^c#( z-$yYmSpxz{>BL;~c+~sxJIe1$7eZI_9t`eB^Pr0)5CuA}w;;7#RvPq|H6!byRzIJG ziQ7a4y_vhj(AL`8PhIm9edCv|%TX#f50lt8+&V+D4<}IA@S@#f4xId80oH$!_!q?@ zFRGGg2mTv&@76P7aTI{)Hu%>3QS_d)pQ%g8BYi58K~m-Ov^7r8BhX7YC1D3vwz&N8{?H*_U7DI?CI)+et?q|eGu>42NJ?K4SY zD?kc>h@%4IqNYuQ8m10+8xr2HYg2qFNdJl=Tmp&ybF>1>pqVfa%SsV*BY$d6<@iJA ziyvKnZ(~F9xQNokBgMci#pnZ}Igh0@S~cYcU_2Jfuf|d3tuH?ZSSYBfM(Y3-JBsC|S9c;# zyIMkPxgrq};0T09pjj#X?W^TFCMf1-9P{)g88;NDI+S4DXe>7d3Mb~i-h&S|Jy{J< zq3736$bH?@{!amD!1Ys-X)9V=#Z={fzsjVYMX5BG6%}tkzwC#1nQLj1y1f#}8**4Y zAvDZHw8)N)8~oWC88CgzbwOrL9HFbk4}h85^ptuu7A+uc#$f^9`EWv1Vr{5+@~@Uv z#B<;-nt;)!k|fRIg;2DZ(A2M2aC65kOIov|?Mhi1Sl7YOU4c$T(DoRQIGY`ycfkn% zViHzL;E*A{`&L?GP06Foa38+QNGA zw3+Wqs(@q+H{XLJbwZzE(omw%9~LPZfYB|NF5%j%E5kr_xE0u;i?IOIchn~VjeDZ) zAqsqhP0vu2&Tbz3IgJvMpKbThC-@=nk)!|?MIPP>MggZg{cUcKsP8|N#cG5 zUXMXxcXBF9`p>09IR?x$Ry3;q@x*%}G#lnB1}r#!WL88I@uvm}X98cZ8KO&cqT1p> z+gT=IxPsq%n4GWgh-Bk8E4!~`r@t>DaQKsjDqYc&h$p~TCh8_Mck5UB84u6Jl@kUZCU9BA-S!*bf>ZotFX9?a_^y%)yH~rsAz0M5#^Di80_tgoKw(egN z`)#(MqAI&A84J#Z<|4`Co8`iY+Cv&iboMJ^f9ROUK0Lm$;-T*c;TCTED_0|qfhlcS zv;BD*$Zko#nWPL}2K8T-?4}p{u)4xon!v_(yVW8VMpxg4Kh^J6WM{IlD{s?%XRT8P|yCU`R&6gwB~ zg}{At!iWCzOH37!ytcPeC`(({ovP7M5Y@bYYMZ}P2Z3=Y_hT)4DRk}wfeIo%q*M9UvXYJq!-@Ly79m5aLD{hf@BzQB>FdQ4mw z6$@vzSKF^Gnzc9vbccii)==~9H#KW<6)Uy1wb~auBn6s`ct!ZEos`WK8e2%<00b%# zY9Nvnmj@V^K(a_38dw-S*;G-(i(ETuIwyirs?$FFW@|66a38k+a%GLmucL%Wc8qk3 z?h_4!?4Y-xt)ry)>J`SuY**fuq2>u+)VZ+_1Egzctb*xJ6+7q`K$^f~r|!i?(07CD zH!)C_uerf-AHNa?6Y61D_MjGu*|wcO+ZMOo4q2bWpvjEWK9yASk%)QhwZS%N2_F4& z16D18>e%Q1mZb`R;vW{+IUoKE`y3(7p zplg5cBB)dtf^SdLd4n60oWie|(ZjgZa6L*VKq02Aij+?Qfr#1z#fwh92aV-HGd^_w zsucG24j8b|pk>BO7k8dS86>f-jBP^Sa}SF{YNn=^NU9mLOdKcAstv&GV>r zLxKHPkFxpvE8^r@MSF6UA}cG`#yFL8;kA7ccH9D=BGBtW2;H>C`FjnF^P}(G{wU;G z!LXLCbPfsGeLCQ{Ep$^~)@?v`q(uI`CxBY44osPcq@(rR-633!qa zsyb>?v%@X+e|Mg`+kRL*(;X>^BNZz{_kw5+K;w?#pReiw7eU8_Z^hhJ&fj80XQkuU z39?-z)6Fy$I`bEiMheS(iB6uLmiMd1i)cbK*9iPpl+h4x9ch7x- z1h4H;W_G?|)i`z??KNJVwgfuAM=7&Apd3vm#AT8uzQZ!NII}}@!j)eIfn53h{NmN7 zAKG6SnKP%^k&R~m5#@_4B@V?hYyHkm>0SQ@PPiw*@Tp@UhP-?w@jW?nxXuCipMW=L zH*5l*d@+jXm0tIMP_ec6Jcy6$w(gKK@xBX8@%oPaSyG;13qkFb*LuVx3{AgIyy&n3 z@R2_DcEn|75_?-v5_o~%xEt~ONB>M~tpL!nOVBLPN&e5bn5>+7o0?Nm|EGJ5 zmUbF{u|Qn?cu5}n4@9}g(G1JxtzkKv(tqwm_?1`?YSVA2IS4WI+*(2D*wh&6MIEhw z+B+2U<&E&|YA=3>?^i6)@n1&&;WGHF-pqi_sN&^C9xoxME5UgorQ_hh1__zzR#zVC zOQt4q6>ME^iPJ37*(kg4^=EFqyKH@6HEHXy79oLj{vFqZGY?sVjk!BX^h$SFJlJnv z5uw~2jLpA)|0=tp>qG*tuLru?-u`khGG2)o{+iDx&nC}eWj3^zx|T`xn5SuR;Aw8U z`p&>dJw`F17@J8YAuW4=;leBE%qagVTG5SZdh&d)(#ZhowZ|cvWvGMMrfVsbg>_~! z19fRz8CSJdrD|Rl)w!uznBF&2-dg{>y4l+6(L(vzbLA0Bk&`=;oQQ>(M8G=3kto_) zP8HD*n4?MySO2YrG6fwSrVmnesW+D&fxjfEmp=tPd?RKLZJcH&K(-S+x)2~QZ$c(> zru?MND7_HPZJVF%wX(49H)+~!7*!I8w72v&{b={#l9yz+S_aVPc_So%iF8>$XD1q1 zFtucO=rBj0Ctmi0{njN8l@}!LX}@dwl>3yMxZ;7 z0Ff2oh8L)YuaAGOuZ5`-p%Z4H@H$;_XRJQ|&(MhO78E|nyFa158gAxG^SP(vGi^+< zChY}o(_=ci3Wta#|K6MVljNe0T$%Q5ylx-v`R)r8;3+VUpp-)7T`-Y&{Zk z*)1*2MW+_eOJtF5tCMDV`}jg-R(_IzeE9|MBKl;a7&(pCLz}5<Zf+)T7bgNUQ_!gZtMlw=8doE}#W+`Xp~1DlE=d5SPT?ymu!r4z%&#A-@x^=QfvDkfx5-jz+h zoZ1OK)2|}_+UI)i9%8sJ9X<7AA?g&_Wd7g#rttHZE;J*7!e5B^zdb%jBj&dUDg4&B zMMYrJ$Z%t!5z6=pMGuO-VF~2dwjoXY+kvR>`N7UYfIBMZGP|C7*O=tU z2Tg_xi#Q3S=1|=WRfZD;HT<1D?GMR%5kI^KWwGrC@P2@R>mDT^3qsmbBiJc21kip~ zZp<7;^w{R;JqZ)C4z-^wL=&dBYj9WJBh&rd^A^n@07qM$c+kGv^f+~mU5_*|eePF| z3wDo-qaoRjmIw<2DjMTG4$HP{z54_te_{W^gu8$r=q0JgowzgQPct2JNtWPUsjF8R zvit&V8$(;7a_m%%9TqPkCXYUp&k*MRcwr*24>hR! z$4c#E=PVE=P4MLTUBM z7#*RDe0}=B)(3cvNpOmWa*eH#2HR?NVqXdJ=hq);MGD07JIQQ7Y0#iD!$C+mk7x&B zMwkS@H%>|fmSu#+ zI!}Sb(%o29Vkp_Th>&&!k7O>Ba#Om~B_J{pT7BHHd8(Ede(l`7O#`_}19hr_?~JP9 z`q(`<)y>%)x;O7)#-wfCP{?llFMoH!)ZomgsOYFvZ1DxrlYhkWRw#E-#Qf*z@Y-EQ z1~?_=c@M4DO@8AzZ2hKvw8CgitzI9yFd&N1-{|vP#4IqYb*#S0e3hrjsEGlnc4xwk z4o!0rxpUt8j&`mJ8?+P8G{m^jbk)bo_UPM+ifW*y-A*et`#_Ja_3nYyRa9fAG1Xr5 z>#AM_@PY|*u)DGRWJihZvgEh#{*joJN28uN7;i5{kJ*Gb-TERfN{ERe_~$Es~NJCpdKLRvdj4658uYYx{ng7I<6j~w@p%F<7a(Ssib|j z51;=Py(Nu*#hnLx@w&8X%=jrADn3TW>kplnb zYbFIWWVQXN7%Cwn6KnR)kYePEBmvM45I)UJb$)ninpdYg3a5N6pm_7Q+9>!_^xy?k za8@tJ@OOs-pRAAfT>Nc2x=>sZUs2!9Dwa%TTmDggH4fq(x^MW>mcRyJINlAqK$YQCMgR8`>6=Sg$ zFnJZsA8xUBXIN3i70Q%8px@yQPMgVP=>xcPI38jNJK<=6hC={a07+n@R|$bnhB)X$ z(Zc%tadp70vBTnW{OUIjTMe38F}JIH$#A}PB&RosPyFZMD}q}5W%$rh>5#U;m`z2K zc(&WRxx7DQLM-+--^w*EWAIS%bi>h587qkwu|H=hma3T^bGD&Z!`u(RKLeNZ&pI=q$|HOcji(0P1QC!YkAp*u z3%S$kumxR}jU<@6`;*-9=5-&LYRA<~uFrwO3U0k*4|xUTp4ZY7;Zbjx|uw&BWU$zK(w55pWa~#=f$c zNDW0O68N!xCy>G}(CX=;8hJLxAKn@Aj(dbZxO8a$+L$jK8$N-h@4$i8)WqD_%Snh4 zR?{O%k}>lr>w$b$g=VP8mckcCrjnp>uQl5F_6dPM8FWRqs}h`DpfCv20uZhyY~tr8 zkAYW4#yM;*je)n=EAb(q@5BWD8b1_--m$Q-3wbh1hM{8ihq7UUQfg@)l06}y+#=$( z$x>oVYJ47zAC^>HLRE-!HitjUixP6!R98WU+h>zct7g4eD;Mj#FL*a!VW!v-@b(Jv zj@@xM5noCp5%Vk3vY{tyI#oyDV7<$`KG`tktVyC&0DqxA#>V;-3oH%NW|Q&=UQ&zU zXNIT67J4D%5R1k#bW0F}TD`hlW7b)-=-%X4;UxQ*u4bK$mTAp%y&-(?{sXF%e_VH6 zTkt(X)SSN|;8q@8XX6qfR;*$r#HbIrvOj*-5ND8RCrcw4u8D$LXm5zlj@E5<3S0R# z??=E$p{tOk96$SloZ~ARe5`J=dB|Nj?u|zy2r(-*(q^@YwZiTF@QzQyPx_l=IDKa) zqD@0?IHJqSqZ_5`)81?4^~`yiGh6>7?|dKa8!e|}5@&qV!Iu9<@G?E}Vx9EzomB3t zEbMEm$TKGwkHDpirp;FZD#6P5qIlQJ8}rf;lHoz#h4TFFPYmS3+8(13_Mx2`?^=8S z|0)0&dQLJTU6{b%*yrpQe#OKKCrL8}YKw+<#|m`SkgeoN69TzIBQOl_Yg)W*w?NW) z*WxhEp$zQBBazJSE6ygu@O^!@Fr46j=|K`Mmb~xbggw7<)BuC@cT@Bwb^k?o-A zKX^9AyqR?zBtW5UA#siILztgOp?r4qgC`9jYJG_fxlsVSugGprremg-W(K0{O!Nw-DN%=FYCyfYA3&p*K>+|Q}s4rx#CQK zNj^U;sLM#q8}#|PeC$p&jAjqMu(lkp-_50Y&n=qF9`a3`Pr9f;b`-~YZ+Bb0r~c+V z*JJ&|^T{}IHkwjNAaM^V*IQ;rk^hnnA@~?YL}7~^St}XfHf6OMMCd9!vhk#gRA*{L zp?&63axj|Si%^NW05#87zpU_>QpFNb+I00v@cHwvdBn+Un)n2Egdt~LcWOeBW4Okm zD$-e~RD+W|UB;KQ;a7GOU&%p*efGu2$@wR74+&iP8|6#_fmnh^WcJLs)rtz{46);F z4v0OL{ZP9550>2%FE(;SbM*#sqMl*UXOb>ch`fJ|(*bOZ9=EB1+V4fkQ)hjsm3-u^Pk-4ji_uDDHdD>84tER!MvbH`*tG zzvbhBR@}Yd`azQGavooV=<WbvWLlO#x`hyO34mKcxrGv=`{ssnP=0Be5#1B;Co9 zh{TR>tjW2Ny$ZxJpYeg57#0`GP#jxDCU0!H15nL@@G*HLQcRdcsUO3sO9xvtmUcc{F*>FQZcZ5bgwaS^k-j5mmt zI7Z{Xnoml|A(&_{imAjK!kf5>g(oDqDI4C{;Bv162k8sFNr;!qPa2LPh>=1n z=^_9)TsLDvTqK7&*Vfm5k;VXjBW^qN3Tl&}K=X5)oXJs$z3gk0_+7`mJvz{pK|FVs zHw!k&7xVjvY;|(Py<;J{)b#Yjj*LZO7x|~pO4^MJ2LqK3X;Irb%nf}L|gck zE#55_BNsy6m+W{e zo!P59DDo*s@VIi+S|v93PwY6d?CE=S&!JLXwE9{i)DMO*_X90;n2*mPDrL%{iqN!?%-_95J^L z=l<*{em(6|h7DR4+4G3Wr;4*}yrBkbe3}=p7sOW1xj!EZVKSMSd;QPw>uhKK z#>MlS@RB@-`ULv|#zI5GytO{=zp*R__uK~R6&p$q{Y{iNkg61yAgB8C^oy&``{~FK z8hE}H&nIihSozKrOONe5Hu?0Zy04U#0$fB7C6y~?8{or}KNvP)an=QP&W80mj&8WL zEZQF&*FhoMMG6tOjeiCIV;T{I>jhi9hiUwz?bkX3NS-k5eWKy)Mo_orMEg4sV6R6X&i-Q%JG;Esl+kLpn@Bsls9O|i9z`tKB^~1D5)RIBB&J<6T@a4$pUvh$IR$%ubH)joi z!7>ON0DPwx=>0DA>Bb^c?L8N0BBrMl#oDB+GOXJh;Y&6I)#GRy$W5xK%a;KS8BrER zX)M>Rdoc*bqP*L9DDA3lF%U8Yzb6RyIsW@}IKq^i7v&{LeIc=*ZHIbO68x=d=+0T( zev=DT9f|x!IWZNTB#N7}V4;9#V$%Wo0%g>*!MdLOEU>My0^gni9ocID{$g9ytD!gy zKRWT`DVN(lcYjR|(}f0?zgBa3SwunLfAhx><%u0uFkrdyqlh8_g zDKt#R6rA2(Vm2LW_>3lBNYKG_F{TEnnKWGGC15y&OebIRhFL4TeMR*v9i0wPoK#H< zu4){s4K&K)K(9~jgGm;H7lS7y_RYfS;&!Oj5*eqbvEcW^a*i67nevzOZxN6F+K~A%TYEtsAVsR z@J=1hc#Dgs7J2^FL|qV&#WBFQyDtEQ2kPO7m2`)WFhqAob)Y>@{crkil6w9VoA?M6 zADGq*#-hyEVhDG5MQj677XmcWY1_-UO40QEP&+D)rZoYv^1B_^w7zAvWGw&pQyCyx zD|ga$w!ODOxxGf_Qq%V9Z7Q2pFiUOIK818AGeZ-~*R zI1O|SSc=3Z?#61Rd|AXx2)K|F@Z1@x!hBBMhAqiU)J=U|Y)T$h3D?ZPPQgkSosnN! zIqw-t$0fqsOlgw3TlHJF*t$Q@bg$9}A3X=cS@-yU3_vNG_!#9}7=q7!LZ?-%U26W4 z$d>_}*s1>Ac%3uFR;tnl*fNlylJ)}r2^Q3&@+is3BIv<}x>-^_ng;jhdaM}6Sg3?p z0jS|b%QyScy3OQ(V*~l~bK>VC{9@FMuW_JUZO?y(V?LKWD6(MXzh}M3r3{7b4eB(#`(q1m{>Be%_<9jw8HO!x#yF6vez$c#kR+}s zZO-_;25Sxngd(}){zv?ccbLqRAlo;yog>4LH&uZUK1n>x?u49C)Y&2evH5Zgt~666 z_2_z|H5AO5Iqxv_Bn~*y1qzRPcob<+Otod5Xd2&z=C;u+F}zBB@b^UdGdUz|s!H}M zXG%KiLzn3G?FZgdY&3pV$nSeY?ZbU^jhLz9!t0K?ep}EFNqR1@E!f*n>x*!uO*~JF zW9UXWrVgbX1n#76_;&0S7z}(5n-bqnII}_iDsNqfmye@)kRk`w~1 z6j4h4BxcPe6}v)xGm%=z2#tB#^KwbgMTl2I*$9eY|EWAHFc3tO48Xo5rW z5oHD!G4kb?MdrOHV=A+8ThlIqL8Uu+7{G@ zb)cGBm|S^Eh5= z^E^SZ=yeC;6nNCdztw&TdnIz}^Of@Ke*@vjt)0g>Y!4AJvWiL~e7+9#Ibhe)> ziNwh>gWZL@FlWc)wzihocz+%+@*euwXhW%Hb>l7tf8aJe5_ZSH1w-uG|B;9qpcBP0 zM`r1Hu#htOl)4Cl1c7oY^t0e4Jh$-I(}M5kzWqh{F=g&IM#JiC`NDSd@BCKX#y<P@Gwl$3a3w z6<(b|K(X5FIR22M)sy$4jY*F4tT{?wZRI+KkZFb<@j@_C316lu1hq2hA|1wCmR+S@ zRN)YNNE{}i_H`_h&VUT5=Y(lN%m?%QX;6$*1P}K-PcPx>*S55v)qZ@r&Vcic-sjkm z! z=nfW&X`}iAqa_H$H%z3Tyz5&P3%+;93_0b;zxLs)t#B|up}JyV$W4~`8E@+BHQ+!y zuIo-jW!~)MN$2eHwyx-{fyGjAWJ(l8TZtUp?wZWBZ%}krT{f*^fqUh+ywHifw)_F> zp76_kj_B&zFmv$FsPm|L7%x-j!WP>_P6dHnUTv!9ZWrrmAUteBa`rT7$2ixO;ga8U z3!91micm}{!Btk+I%pMgcKs?H4`i+=w0@Ws-CS&n^=2hFTQ#QeOmSz6ttIkzmh^`A zYPq)G1l3h(E$mkyr{mvz*MP`x+PULBn%CDhltKkNo6Uqg!vJ#DA@BIYr9TQ`18Un2 zv$}BYzOQuay9}w(?JV63F$H6WmlYPPpH=R|CPb%C@BCv|&Q|&IcW7*LX?Q%epS z`=CPx{1HnJ9_46^=0VmNb>8JvMw-@&+V8SDLRYsa>hZXEeRbtf5eJ>0@Ds47zIY{N z42EOP9J8G@MXXdeiPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91AfN*P1ONa40RR91AOHXW0IY^$^8f$?lu1NER9Fe^SItioK@|V(ZWmgL zZT;XwPgVuWM>O%^|Dc$VK;n&?9!&g5)aVsG8cjs5UbtxVVnQNOV~7Mrg3+jnU;rhE z6fhW6P)R>_eXrXo-RW*y6RQ_qcb^s1wTu$TwriZ`=JUws>vRi}5x}MW1MR#7p|gIWJlaLK;~xaN}b< z<-@=RX-%1mt`^O0o^~2=CD7pJ<<$Rp-oUL-7PuG>do^5W_Mk#unlP}6I@6NPxY`Q} zuXJF}!0l)vwPNAW;@5DjPRj?*rZxl zwn;A(cFV!xe^CUu+6SrN?xe#mz?&%N9QHf~=KyK%DoB8HKC)=w=3E?1Bqj9RMJs3U z5am3Uv`@+{jgqO^f}Lx_Jp~CoP3N4AMZr~4&d)T`R?`(M{W5WWJV^z~2B|-oih@h^ zD#DuzGbl(P5>()u*YGo*Och=oRr~3P1wOlKqI)udc$|)(bacG5>~p(y>?{JD7nQf_ z*`T^YL06-O>T(s$bi5v~_fWMfnE7Vn%2*tqV|?~m;wSJEVGkNMD>+xCu#um(7}0so zSEu7?_=Q64Q5D+fz~T=Rr=G_!L*P|(-iOK*@X8r{-?oBlnxMNNgCVCN9Y~ocu+?XA zjjovJ9F1W$Nf!{AEv%W~8oahwM}4Ruc+SLs>_I_*uBxdcn1gQ^2F8a*vGjgAXYyh? zWCE@c5R=tbD(F4nL9NS?$PN1V_2*WR?gjv3)4MQeizuH`;sqrhgykEzj z593&TGlm3h`sIXy_U<7(dpRXGgp0TB{>s?}D{fwLe>IV~exweOfH!qM@CV5kib!YA z6O0gvJi_0J8IdEvyP#;PtqP*=;$iI2t(xG2YI-e!)~kaUn~b{6(&n zp)?iJ`z2)Xh%sCV@BkU`XL%_|FnCA?cVv@h*-FOZhY5erbGh)%Q!Av#fJM3Csc_g zC2I6x%$)80`Tkz#KRA!h1FzY`?0es3t!rKDT5EjPe6B=BLPr7s0GW!if;Ip^!AmGW zL;$`Vdre+|FA!I4r6)keFvAx3M#1`}ijBHDzy)3t0gwjl|qC2YB`SSxFKHr(oY#H$)x{L$LL zBdLKTlsOrmb>T0wd=&6l3+_Te>1!j0OU8%b%N342^opKmT)gni(wV($s(>V-fUv@0p8!f`=>PxC|9=nu ze{ToBBj8b<{PLfXV$h8YPgA~E!_sF9bl;QOF{o6t&JdsX?}rW!_&d`#wlB6T_h;Xf zl{4Tz5>qjF4kZgjO7ZiLPRz_~U@k5%?=30+nxEh9?s78gZ07YHB`FV`4%hlQlMJe@J`+e(qzy+h(9yY^ckv_* zb_E6o4p)ZaWfraIoB2)U7_@l(J0O%jm+Or>8}zSSTkM$ASG^w3F|I? z$+eHt7T~04(_WfKh27zqS$6* zzyy-ZyqvSIZ0!kkSvHknm_P*{5TKLQs8S6M=ONuKAUJWtpxbL#2(_huvY(v~Y%%#~ zYgsq$JbLLprKkV)32`liIT$KKEqs$iYxjFlHiRNvBhxbDg*3@Qefw4UM$>i${R5uB zhvTgmqQsKA{vrKN;TSJU2$f9q=y{$oH{<)woSeV>fkIz6D8@KB zf4M%v%f5U2?<8B(xn}xV+gWP?t&oiapJhJbfa;agtz-YM7=hrSuxl8lAc3GgFna#7 zNjX7;`d?oD`#AK+fQ=ZXqfIZFEk{ApzjJF0=yO~Yj{7oQfXl+6v!wNnoqwEvrs81a zGC?yXeSD2NV!ejp{LdZGEtd1TJ)3g{P6j#2jLR`cpo;YX}~_gU&Gd<+~SUJVh+$7S%`zLy^QqndN<_9 zrLwnXrLvW+ew9zX2)5qw7)zIYawgMrh`{_|(nx%u-ur1B7YcLp&WFa24gAuw~& zKJD3~^`Vp_SR$WGGBaMnttT)#fCc^+P$@UHIyBu+TRJWbcw4`CYL@SVGh!X&y%!x~ zaO*m-bTadEcEL6V6*{>irB8qT5Tqd54TC4`h`PVcd^AM6^Qf=GS->x%N70SY-u?qr>o2*OV7LQ=j)pQGv%4~z zz?X;qv*l$QSNjOuQZ>&WZs2^@G^Qas`T8iM{b19dS>DaXX~=jd4B2u`P;B}JjRBi# z_a@&Z5ev1-VphmKlZEZZd2-Lsw!+1S60YwW6@>+NQ=E5PZ+OUEXjgUaXL-E0fo(E* zsjQ{s>n33o#VZm0e%H{`KJi@2ghl8g>a~`?mFjw+$zlt|VJhSU@Y%0TWs>cnD&61fW4e0vFSaXZa4-c}U{4QR8U z;GV3^@(?Dk5uc@RT|+5C8-24->1snH6-?(nwXSnPcLn#X_}y3XS)MI_?zQ$ZAuyg+ z-pjqsw}|hg{$~f0FzmmbZzFC0He_*Vx|_uLc!Ffeb8#+@m#Z^AYcWcZF(^Os8&Z4g zG)y{$_pgrv#=_rV^D|Y<_b@ICleUv>c<0HzJDOsgJb#Rd-Vt@+EBDPyq7dUM9O{Yp zuGUrO?ma2wpuJuwl1M=*+tb|qx7Doj?!F-3Z>Dq_ihFP=d@_JO;vF{iu-6MWYn#=2 zRX6W=`Q`q-+q@Db|6_a1#8B|#%hskH82lS|9`im0UOJn?N#S;Y0$%xZw3*jR(1h5s z?-7D1tnIafviko>q6$UyqVDq1o@cwyCb*})l~x<@s$5D6N=-Uo1yc49p)xMzxwnuZ zHt!(hu-Ek;Fv4MyNTgbW%rPF*dB=;@r3YnrlFV{#-*gKS_qA(G-~TAlZ@Ti~Yxw;k za1EYyX_Up|`rpbZ0&Iv#$;eC|c0r4XGaQ-1mw@M_4p3vKIIpKs49a8Ns#ni)G314Z z8$Ei?AhiT5dQGWUYdCS|IC7r z=-8ol>V?u!n%F*J^^PZ(ONT&$Ph;r6X;pj|03HlDY6r~0g~X#zuzVU%a&!fs_f|m?qYvg^Z{y?9Qh7Rn?T*F%7lUtA6U&={HzhYEzA`knx1VH> z{tqv?p@I(&ObD5L4|YJV$QM>Nh-X3cx{I&!$FoPC_2iIEJfPk-$;4wz>adRu@n`_y z_R6aN|MDHdK;+IJmyw(hMoDCFCQ(6?hCAG5&7p{y->0Uckv# zvooVuu04$+pqof777ftk<#42@KQ((5DPcSMQyzGOJ{e9H$a9<2Qi_oHjl{#=FUL9d z+~0^2`tcvmp0hENwfHR`Ce|<1S@p;MNGInXCtHnrDPXCKmMTZQ{HVm_cZ>@?Wa6}O zHsJc7wE)mc@1OR2DWY%ZIPK1J2p6XDO$ar`$RXkbW}=@rFZ(t85AS>>U0!yt9f49^ zA9@pc0P#k;>+o5bJfx0t)Lq#v4`OcQn~av__dZ-RYOYu}F#pdsl31C^+Qgro}$q~5A<*c|kypzd} ziYGZ~?}5o`S5lw^B{O@laad9M_DuJle- z*9C7o=CJh#QL=V^sFlJ0c?BaB#4bV^T(DS6&Ne&DBM_3E$S^S13qC$7_Z?GYXTpR@wqr70wu$7+qvf-SEUa5mdHvFbu^7ew!Z1a^ zo}xKOuT*gtGws-a{Tx}{#(>G~Y_h&5P@Q8&p!{*s37^QX_Ibx<6XU*AtDOIvk|^{~ zPlS}&DM5$Ffyu-T&0|KS;Wnaqw{9DB&B3}vcO14wn;)O_e@2*9B&0I_ zZz{}CMxx`hv-XouY>^$Y@J(_INeM>lIQI@I>dBAqq1)}?Xmx(qRuX^i4IV%=MF306 z9g)i*79pP%_7Ex?m6ag-4Tlm=Z;?DQDyC-NpUIb#_^~V_tsL<~5<&;Gf2N+p?(msn zzUD~g>OoW@O}y0@Z;RN)wjam`CipmT&O7a|YljZqU=U86 zedayEdY)2F#BJ6xvmW8K&ffdS*0!%N<%RB!2~PAT4AD*$W7yzHbX#Eja9%3aD+Ah2 zf#T;XJW-GMxpE=d4Y>}jE=#U`IqgSoWcuvgaWQ9j1CKzG zDkoMDDT)B;Byl3R2PtC`ip=yGybfzmVNEx{xi_1|Cbqj>=FxQc{g`xj6fIfy`D8fA z##!-H_e6o0>6Su&$H2kQTujtbtyNFeKc}2=|4IfLTnye#@$Au7Kv4)dnA;-fz@D_8 z)>irG$)dkBY~zX zC!ZXLy*L3xr6cb70QqfN#Q>lFIc<>}>la4@3%7#>a1$PU&O^&VszpxLC%*!m-cO{B z-Y}rQr4$84(hvy#R69H{H zJ*O#uJh)TF6fbXy;fZkk%X=CjsTK}o5N1a`d7kgYYZLPxsHx%9*_XN8VWXEkVJZ%A z1A+5(B;0^{T4aPYr8%i@i32h)_)|q?9vws)r+=5u)1YNftF5mknwfd*%jXA2TeP}Z zQ!m?xJ3?9LpPM?_A3$hQ1QxNbR&}^m z!F999s?p^ak#C4NM_x2p9FoXWJ$>r?lJ)2bG)sX{gExgLA2s5RwHV!h6!C~d_H||J z>9{E{mEv{Z1z~65Vix@dqM4ZqiU|!)eWX$mwS5mLSufxbpBqqS!jShq1bmwCR6 z4uBri7ezMeS6ycaXPVu(i2up$L; zjpMtB`k~WaNrdgM_R=e#SN?Oa*u%nQy01?()h4A(jyfeNfx;5o+kX?maO4#1A^L}0 zYNyIh@QVXIFiS0*tE}2SWTrWNP3pH}1Vz1;E{@JbbgDFM-_Mky^7gH}LEhl~Ve5PexgbIyZ(IN%PqcaV@*_`ZFb=`EjspSz%5m2E34BVT)d=LGyHVz@-e%9Ova*{5@RD;7=Ebkc2GP%pIP^P7KzKapnh`UpH?@h z$RBpD*{b?vhohOKf-JG3?A|AX|2pQ?(>dwIbWhZ38GbTm4AImRNdv_&<99ySX;kJ| zo|5YgbHZC#HYgjBZrvGAT4NZYbp}qkVSa;C-LGsR26Co+i_HM&{awuO9l)Ml{G8zD zs$M8R`r+>PT#Rg!J(K6T4xHq7+tscU(}N$HY;Yz*cUObX7J7h0#u)S7b~t^Oj}TBF zuzsugnst;F#^1jm>22*AC$heublWtaQyM6RuaquFd8V#hJ60Z3j7@bAs&?dD#*>H0SJaDwp%U~27>zdtn+ z|8sZzklZy$%S|+^ie&P6++>zbrq&?+{Yy11Y>@_ce@vU4ZulS@6yziG6;iu3Iu`M= zf3rcWG<+3F`K|*(`0mE<$89F@jSq;j=W#E>(R}2drCB7D*0-|D;S;(;TwzIJkGs|q z2qH{m_zZ+el`b;Bv-#bQ>}*VPYC|7`rgBFf2oivXS^>v<&HHTypvd4|-zn|=h=TG{ z05TH2+{T%EnADO>3i|CB zCu60#qk`}GW{n4l-E$VrqgZGbI zbQW690KgZt4U3F^5@bdO1!xu~p@7Y~*_FfWg2CdvED5P5#w#V46LH`<&V0{t&Ml~4 zHNi7lIa+#i+^Z6EnxO7KJQw)wD)4~&S-Ki8)3=jpqxmx6c&zU&<&h%*c$I(5{1HZT zc9WE}ijcWJiVa^Q^xC|WX0habl89qycOyeViIbi(LFsEY_8a|+X^+%Qv+W4vzj>`y zpuRnjc-eHNkvXvI_f{=*FX=OKQzT?bck#2*qoKTHmDe>CDb&3AngA1O)1b}QJ1Tun z_<@yVEM>qG7664Pa@dzL@;DEh`#?yM+M|_fQS<7yv|i*pw)|Z8)9IR+QB7N3v3K(wv4OY*TXnH&X0nQB}?|h2XQeGL^q~N7N zDFa@x0E(UyN7k9g%IFq7Sf+EAfE#K%%#`)!90_)Dmy3Bll&e1vHQyPA87TaF(xbqMpDntVp?;8*$87STop$!EAnGhZ?>mqPJ(X zFsr336p3P{PpZCGn&^LP(JjnBbl_3P3Kcq+m}xVFMVr1zdCPJMDIV_ki#c=vvTwbU z*gKtfic&{<5ozL6Vfpx>o2Tts?3fkhWnJD&^$&+Mh5WGGyO7fG@6WDE`tEe(8<;+q z@Ld~g08XDzF8xtmpIj`#q^(Ty{Hq>t*v`pedHnuj(0%L(%sjkwp%s}wMd!a<*L~9T z9MM@s)Km~ogxlqEhIw5(lc46gCPsSosUFsgGDr8H{mj%OzJz{N#;bQ;KkV+ZWA1(9 zu0PXzyh+C<4OBYQ0v3z~Lr;=C@qmt8===Ov2lJ1=DeLfq*#jgT{YQCuwz?j{&3o_6 zsqp2Z_q-YWJg?C6=!Or|b@(zxTlg$ng2eUQzuC<+o)k<6^9ju_Z*#x+oioZ5T8Z_L zz9^A1h2eFS0O5muq8;LuDKwOv4A9pxmOjgb6L*i!-(0`Ie^d5Fsgspon%X|7 zC{RRXEmYn!5zP9XjG*{pLa)!2;PJB2<-tH@R7+E1cRo=Wz_5Ko8h8bB$QU%t9#vol zAoq?C$~~AsYC|AQQ)>>7BJ@{Cal)ZpqE=gjT+Juf!RD-;U0mbV1ED5PbvFD6M=qj1 zZ{QERT5@(&LQ~1X9xSf&@%r|3`S#ZCE=sWD`D4YQZ`MR`G&s>lN{y2+HqCfvgcw3E z-}Kp(dfGG?V|97kAHQX+OcKCZS`Q%}HD6u*e$~Ki&Vx53&FC!x94xJd4F2l^qQeFO z?&JdmgrdVjroKNJx64C!H&Vncr^w zzR#XI}Dn&o8jB~_YlVM^+#0W(G1LZH5K^|uYT@KSR z^Y5>^*Bc45E1({~EJB(t@4n9gb-eT#s@@7)J^^<_VV`Pm!h7av8XH6^5zO zOcQBhTGr;|MbRsgxCW69w{bl4EW#A~);L?d4*y#j8Ne=Z@fmJP0k4{_cQ~KA|Y#_#BuUiYx8y*za3_6Y}c=GSe7(2|KAfhdzud!Zq&}j)=o4 z7R|&&oX7~e@~HmyOOsCCwy`AR+deNjZ3bf6ijI_*tKP*_5JP3;0d;L_p(c>W1b%sG zJ*$wcO$ng^aW0E(5ldckV9unU7}OB7s?Wx(761?1^&8tA5y0_(ieV>(x-e@}1`lWC z-YH~G$D>#ud!SxK2_Iw{K%92=+{4yb-_XC>ji&j7)1ofp(OGa4jjF;Hd*`6YQL+Jf zffg+6CPc8F@EDPN{Kn96yip;?g@)qgkPo^nVKFqY?8!=h$G$V=<>%5J&iVjwR!7H0 z$@QL|_Q81I;Bnq8-5JyNRv$Y>`sWl{qhq>u+X|)@cMlsG!{*lu?*H`Tp|!uv z9oEPU1jUEj@ueBr}%Y)7Luyi)REaJV>eQ{+uy4uh0ep0){t;OU8D*RZ& zE-Z-&=BrWQLAD^A&qut&4{ZfhqK1ZQB0fACP)=zgx(0(o-`U62EzTkBkG@mXqbjXm z>w`HNeQM?Is&4xq@BB(K;wv5nI6EXas)XXAkUuf}5uSrZLYxRCQPefn-1^#OCd4aO zzF=dQ*CREEyWf@n6h7(uXLNgJIwGp#Xrsj6S<^bzQ7N0B0N{XlT;`=m9Olg<>KL}9 zlp>EKTx-h|%d1Ncqa=wnQEuE;sIO-f#%Bs?g4}&xS?$9MG?n$isHky0caj za8W+B^ERK#&h?(x)7LLpOqApV5F>sqB`sntV%SV>Q1;ax67qs+WcssfFeF3Xk=e4^ zjR2^(%K1oBq%0%Rf!y&WT;lu2Co(rHi|r1_uW)n{<7fGc-c=ft7Z0Q}r4W$o$@tQF#i?jDBwZ8h+=SC}3?anUp3mtRVv9l#H?-UD;HjTF zQ*>|}e=6gDrgI9p%c&4iMUkQa4zziS$bO&i#DI$Wu$7dz7-}XLk%!US^XUIFf2obO zFCTjVEtkvYSKWB;<0C;_B{HHs~ax_48^Cml*mjfBC5*7^HJZiLDir(3k&BerVIZF8zF;0q80eX8c zPN4tc+Dc5DqEAq$Y3B3R&XPZ=AQfFMXv#!RQnGecJONe0H;+!f^h5x0wS<+%;D}MpUbTNUBA}S2n&U59-_5HKr{L^jPsV8B^%NaH|tUr)mq=qCBv_- ziZ1xUp(ZzxUYTCF@C}To;u60?RIfTGS?#JnB8S8@j`TKPkAa)$My+6ziGaBcA@){d z91)%+v2_ba7gNecdj^8*I4#<11l!{XKl6s0zkXfJPxhP+@b+5ev{a>p*W-3*25c&} zmCf{g9mPWVQ$?Sp*4V|lT@~>RR)9iNdN^7KT@>*MU3&v^3e?=NTbG9!h6C|9zO097 zN{Qs6YwR-5$)~ z`b~qs`a1Dbx8P>%V=1XGjBptMf%P~sl1qbHVm1HYpY|-Z^Dar8^HqjIw}xaeRlsYa zJ_@Apy-??`gxPmb`m`0`z`#G7*_C}qiSZe~l2z65tE~IwMw$1|-u&t|z-8SxliH00 zlh1#kuqB56s+E&PWQ7Nz17?c}pN+A@-c^xLqh(j;mS|?>(Pf7(?qd z5q@jkc^nA&!K-}-1P=Ry0yyze0W!+h^iW}7jzC1{?|rEFFWbE^Yu7Y}t?jmP-D$f+ zmqFT7nTl0HL|4jwGm7w@a>9 zKD)V~+g~ysmei$OT5}%$&LK8?ib|8aY|>W3;P+0B;=oD=?1rg+PxKcP(d;OEzq1CKA&y#boc51P^ZJPPS)z5 zAZ)dd2$glGQXFj$`XBBJyl2y-aoBA8121JC9&~|_nY>nkmW>TLi%mWdn-^Jks-Jv| zSR*wij;A3Fcy8KsDjQ15?Z9oOj|Qw2;jgJiq>dxG(2I2RE- z$As!#zSFIskebqU2bnoM^N<4VWD2#>!;saPSsY8OaCCQqkCMdje$C?Sp%V}f2~tG5 z0whMYk6tcaABwu*x)ak@n4sMElGPX1_lmv@bgdI2jPdD|2-<~Jf`L`@>Lj7{<-uLQ zE3S_#3e10q-ra=vaDQ42QUY^@edh>tnTtpBiiDVUk5+Po@%RmuTntOlE29I4MeJI?;`7;{3e4Qst#i-RH6s;>e(Sc+ubF2_gwf5Qi%P!aa89fx6^{~A*&B4Q zKTF|Kx^NkiWx=RDhe<{PWXMQ;2)=SC=yZC&mh?T&CvFVz?5cW~ritRjG2?I0Av_cI z)=s!@MXpXbarYm>Kj0wOxl=eFMgSMc?62U#2gM^li@wKPK9^;;0_h7B>F>0>I3P`{ zr^ygPYp~WVm?Qbp6O3*O2)(`y)x>%ZXtztz zMAcwKDr=TCMY!S-MJ8|2MJCVNUBI0BkJV6?(!~W!_dC{TS=eh}t#X+2D>Kp&)ZN~q zvg!ogxUXu^y(P*;Q+y_rDoGeSCYxkaGPldDDx)k;ocJvvGO#1YKoQLHUf2h_pjm&1 zqh&!_KFH03FcJvSdfgUYMp=5EpigZ*8}7N_W%Ms^WSQ4hH`9>3061OEcxmf~TcYn5_oHtscWn zo5!ayj<_fZ)vHu3!A!7M;4y1QIr8YGy$P2qDD_4+T8^=^dB6uNsz|D>p~4pF3Nrb6 zcpRK*($<~JUqOya#M1=#IhOZ zG)W+rJS-x(6EoVz)P zsSo>JtnChdj9^);su%SkFG~_7JPM zEDz3gk2T7Y%x>1tWyia|op(ilEzvAujW?Xwlw>J6d7yEi8E zv30riR|a_MM%ZZX&n!qm0{2agq(s?x9E@=*tyT$nND+{Djpm7Rsy!+c$j+wqMwTOF zZL8BQ|I`<^bGW)5apO{lh(Asqen?_U`$_n0-Ob~Yd%^89oEe%9yGumQ_8Be+l2k+n zCxT%s?bMpv|AdWP7M1LQwLm|x+igA~;+iK-*+tClF&ueX_V}>=4gvZ01xpubQWXD_ zi?Un>&3=$fu)dgk-Z;0Ll}HK5_YM->l^Czrd0^cJ))(DwL2g3aZuza7ga9^|mT_70 z))}A}r1#-(9cxtn<9jGRwOB4hb9kK@YCgjfOM-90I$8@l=H^`K$cyhe2mTM|FY9vW znH~h)I<_aa#V1xmhk?Ng@$Jw-s%a!$BI4Us+Df+?J&gKAF-M`v}j`OWKP3>6`X`tEmhe#y*(Xm$_^Ybbs=%;L7h zp7q^C*qM}Krqsinq|WolR99>_!GL#Z71Hhz|IwQQv<>Ds09B?Je(lhI1(FInO8mc} zl$RyKCUmfku+Cd^8s0|t+e}5g7M{ZPJQH=UB3(~U&(w#Bz#@DTDHy>_UaS~AtN>4O zJ-I#U@R($fgupHebcpuEBX`SZ>kN!rW$#9>s{^3`86ZRQRtYTY)hiFm_9wU3c`SC8 z-5M%g)h}3Pt|wyj#F%}pGC@VL`9&>9P+_UbudCkS%y2w&*o})hBplrB*@Z?gel5q+ z%|*59(sR9GMk3xME}wd%&k?7~J)OL`rK#4d-haC7uaU8-L@?$K6(r<0e<;y83rK&` z3Q!1rD9WkcB8WBQ|WT|$u^lkr0UL4WH4EQTJyk@5gzHb18cOte4w zS`fLv8q;PvAZyY;*Go3Qw1~5#gP0D0ERla6M6#{; zr1l?bR}Nh+OC7)4bfAs(0ZD(axaw6j9v`^jh5>*Eo&$dAnt?c|Y*ckEORIiJXfGcM zEo`bmIq6rJm`XhkXR-^3d8^RTK2;nmVetHfUNugJG(4XLOu>HJA;0EWb~?&|0abr6 zxqVp@p=b3MN^|~?djPe!=eex(u!x>RYFAj|*T$cTi*Sd3Bme7Pri1tkK9N`KtRmXf zZYNBNtik97ct1R^vamQBfo9ZUR@k*LhIg8OR9d_{iv#t)LQV91^5}K5u{eyxwOFoU zHMVq$C>tfa@uNDW^_>EmO~WYQd(@!nKmAvSSIb&hPO|}g-3985t?|R&WZXvxS}Kt2i^eRe>WHb_;-K5cM4=@AN1>E&1c$k!w4O*oscx(f=<1K6l#8Exi)U(ZiZ zdr#YTP6?m1e1dOKysUjQ^>-MR={OuD00g6+(a^cvcmn#A_%Fh3Of%(qP5nvjS1=(> z|Ld8{u%(J}%2SY~+$4pjy{()5HN2MYUjg1X9umxOMFFPdM+IwOVEs4Z(olynvT%G) zt9|#VR}%O2@f6=+6uvbZv{3U)l;C{tuc zZ{K$rut=eS%3_~fQv^@$HV6#9)K9>|0qD$EV2$G^XUNBLM|5-ZmFF!KV)$4l^KVj@ zZ4fI}Knv*K%zPqK77}B-h_V{66VrmoZP2>@^euu8Rc}#qwRwt5uEBWcJJE5*5rT2t zA4Jpx`QQ~1Sh_n_a9x%Il!t1&B~J6p54zxAJx`REov${jeuL8h8x-z=?qwMAmPK5i z_*ES)BW(NZluu#Bmn1-NUKQip_X&_WzJy~J`WYxEJQ&Gu7DD< z&F9urE;}8S{x4{yB zaq~1Zrz%8)<`prSQv$eu5@1RY2WLu=waPTrn`WK%;G5(jt^FeM;gOdvXQjYhax~_> z{bS_`;t#$RYMu-;_Dd&o+LD<5Afg6v{NK?0d8dD5ohAN?QoocETBj?y{MB)jQ%UQ}#t3j&iL!qr@#6JEajR3@^k5wgLfI9S9dT2^f`2wd z%I#Q*@Ctk@w=(u)@QC}yBvUP&fFRR-uYKJ){Wp3&$s(o~W7OzgsUIPx0|ph2L1(r*_Pa@T@mcH^JxBjh09#fgo|W#gG7}|)k&uD1iZxb0 z@|Y)W79SKj9sS&EhmTD;uI#)FE6VwQ*YAr&foK$RI5H8_ripb$^=;U%gWbrrk4!5P zXDcyscEZoSH~n6VJu8$^6LE6)>+=o#Q-~*jmob^@191+Ot1w454e3)WMliLtY6~^w zW|n#R@~{5K#P+(w+XC%(+UcOrk|yzkEes=!qW%imu6>zjdb!B#`efaliKtN}_c!Jp zfyZa`n+Nx8;*AquvMT2;c8fnYszdDA*0(R`bsof1W<#O{v%O!1IO4WZe=>XBu_D%d zOwWDaEtX%@B>4V%f1+dKqcXT>m2!|&?}(GK8e&R=&w?V`*Vj)sCetWp9lr@@{xe6a zE)JL&;p}OnOO}Nw?vFyoccXT*z*?r}E8{uPtd;4<(hmX;d$rqJhEF}I+kD+m(ke;J z7Cm$W*CSdcD=RYEBhedg>tuT{PHqwCdDP*NkHv4rvQTXkzEn*Mb0oJz&+WfWIOS4@ zzpPJ|e%a-PIwOaOC7uQcHQ-q(SE(e@fj+7oC@34wzaBNaP;cw&gm{Z8yYX?V(lIv5 zKbg*zo1m5aGA4^lwJ|bAU=j3*d8S{vp!~fLFcK8s6%Ng55_qW_d*3R%e=34aDZPfD z&Le39j|ahp6E7B0*9OVdeMNrTErFatiE+=Z!XZ^tv0y%zZKXRTBuPyP&C{5(H?t)S zKV24_-TKpOmCPzU&by8R1Q5HY^@IDoeDA9MbgizgQ*F1Er~HVmvSU>vx}pZVQ&tr| zOtZl8vfY2#L<)gZ=ba&wG~EI*Vd?}lRMCf+!b5CDz$8~be-HKMo5omk$w7p4`Mym*IR8WiTz4^kKcUo^8Hkcsu14u z`Pkg`#-Y^A%CqJ0O@UF|caAulf68@(zhqp~YjzInh7qSN7Ov%Aj(Qz%{3zW|xubJ- ztNE_u_MO7Q_585r;xD?e=Er}@U1G@BKW5v$UM((eByhH2p!^g9W}99OD8VV@7d{#H zv)Eam+^K(5>-Ot~U!R$Um3prQmM)7DyK=iM%vy>BRX4#aH7*oCMmz07YB(EL!^%F7?CA#>zXqiYDhS;e?LYPTf(bte6B ztrfvDXYG*T;ExK-w?Knt{jNv)>KMk*sM^ngZ-WiUN;=0Ev^GIDMs=AyLg2V@3R z7ugNc45;4!RPxvzoT}3NCMeK$7j#q3r_xV(@t@OPRyoKBzHJ#IepkDsm$EJRxL)A* zf{_GQYttu^OXr$jHQn}zs$Eh|s|Z!r?Yi+bS-bi+PE*lH zo|6ztu6$r_?|B~S#m>imI!kQP9`6X426uHRri!wGcK;J;`%sFM(D#*Le~W*t2uH`Q z(HEO9-c_`mhA@4QhbW+tgtt9Pzx=_*3Kh~TB$SKmU4yx-Ay&)n%PZPKg#rD4H{%Ke zdMY@rf5EAFfqtrf?Vmk&N(_d-<=bvfOdPrYwY*;5%j@O6@O#Qj7LJTk-x3LN+dEKy+X z>~U8j3Ql`exr1jR>+S4nEy+4c2f{-Q!3_9)yY758tLGg7k^=nt<6h$YE$ltA+13S<}uOg#XHe6 zZHKdNsAnMQ_RIuB;mdoZ%RWpandzLR-BnjN2j@lkBbBd+?i ze*!5mC}!Qj(Q!rTu`KrRRqp22c=hF6<^v&iCDB`n7mHl;vdclcer%;{;=kA(PwdGG zdX#BWoC!leBC4);^J^tPkPbIe<)~nYb6R3u{HvC!NOQa?DC^Q`|_@ zcz;rk`a!4rSLAS>_=b@g?Yab4%=J3Cc7pRv8?_rHMl_aK*HSPU%0pG2Fyhef_biA!aW|-(( z*RIdG&Lmk(=(nk28Q1k1Oa$8Oa-phG%Mc6dT3>JIylcMMIc{&FsBYBD^n@#~>C?HG z*1&FpYVvXOU@~r2(BUa+KZv;tZ15#RewooEM0LFb>guQN;Z0EBFMFMZ=-m$a3;gVD z)2EBD4+*=6ZF?+)P`z@DOT;azK0Q4p4>NfwDR#Pd;no|{q_qB!zk1O8QojE;>zhPu z1Q=1z^0MYHo1*``H3ex|bW-Zy==5J4fE2;g6sq6YcXMYK5i|S^9(OSw#v!3^!EB<% zZF~J~CleS`V-peStyf*I%1^R88D;+8{{qN6-t!@gTARDg^w2`uSzFZbPQ!)q^oC}m zPo8VOQxq2BaIN`pAVFGu8!{p3}(+iZ`f4ck2ygVpEZMQW38nLpj3NQx+&sAkb8`}P3- zc>N*k6AG?r}bfO6_vccTuKX+*- z7W4Q#2``P0jIHYs)F>uG#AM#I6W2)!Nu2nD5{CRV_PmkDS2ditmbd#pggqEgAo%5oC?|CP zGa0CV)wA*ko!xC7pZYkqo{10CN_e00FX5SjWkI3?@XG}}bze!(&+k2$C-C`6temSk z_YyYpB^wh3woo`B zrMSTd4T?(X-jh`FeO76C(3xsOm9s2BP_b%ospg^!#*2*o9N;tf4(X9$qc_d(()yz5 zDk@1}u_Xd+86vy5RBs?LQCuYKCGPS;E4uFOi@V%1JTK&|eRf~lp$AV#;*#O}iRI2=i3rFL8{ zA^ptDZ0l6k-mq=hUJ0x$Y@J>UNfz~I5l63H(`~*v;qX`Z{zwsQQD-!wp0D&hyB8&Z z7$R07gIKGJ^%AvQ{4KM0edM39iFRx=P^6`!<1(s0t|JbB2tXs_B_IH9#ajH0C=-n+ z`nz`fKMBKLlf?2AC+|83M+0rqR%uhNGD;uKA6jOjp7YDe^4%0fRB<^bcjlS2KF~F; zu09wh1x0&4pG&76M;x8$u`b134t=dEPBn6PV|X29<#T4F1mxGF*HOgiWU8tN@cguI z_F@o+XL7FJztR63wC|j4x_DANzcX94r7Iz-O2x$({&qd*mdLG=-Rv)uZ}UlMR+F&q zU}=lkfb0p1>1Ho){o$@}mSKIV;h*$AND7~Dl)QzpFBlSM99Kx+F7GsVK5xcR? z_4Q(Z%cgk8ST}U;;=!LwyZVu^S$>B-Waeik%wzcKTIqeX=0FP(TGQ=nxi=dsS5BYF zl@?}NT!Y!Iyos^@v7XWXA{_bV~1lxz7gC?xuXxy0_?GaN!AhRRM5>)^t%&ODd;@HN5L{MD3 zc>i2keQZVm#?NrDwbfd}_<*5^U&w0zv~n-y8=GGN-!=_`FU^cM8oVCWRFxw?BM^YD zi=Vxz4q|jwPTg+?q7_XI)-S@gQkh>w0ZUB}a{^ z_i;`Y(~fvpI!vmW*A^|P7(6+@C4UeL2WATf{P1?H5rk`5{TL zcf!CgP6Mi{MvjZS)rfo7JLDZK7M7ANd$3`{j9baD*7{#Zu-33fOYUzjvtKzR2)_T1I1s7fe&z|=)QkX;=`zX8!Byw-veM#yr;|wjO^II>!B*B z0+w%;0(=*G3V@88t!}~zx)&do(uF=073Yeh*fEhZb3Vn>t!m(9p~Y_FdV3IgR)9eT z)~e9xpI%2deTWyHlXA(7srrfc_`7ACm!R>SoIgkuF8 z!wkOhrixFy9y@)GdxAntd!!7@=L_tFD2T5OdSUO)I%yj02le`qeQ=yKq$g^h)NG;# za(0J@#VBi^5YI|QI=rq{KlxwGabZJ0dKmfWDROkcM}lUN$@DV`K7fU?8CP2H23QPi zG?YF*=Vn=kTK*#Y_{AQN&oLju|0#E=fx%YVh>S{puu&K$b;BN*jIo@VYhqPiJPzzM>#kxoy0vW9i;ne2_BIG0zyRFp<3M(iY(%*M_>q0ulV2K}Tg zkG{EWKS{i%4DUuHi%DVKy%e+Q!~Uf`>>F6NgD{{I8~nO4!VgOvtFOc7(O)X`|7n*f zxBa4CJ-v9fUUH+`7sPVvpM_C*udZ@OTGTzx56QM5y~OlrZc&w9=)B?nmd@keRn+^= zvm~4sa5987LFDnU{(N|N zJAR8H@}p1fC+H(yTI4n#%~TbImMpuqYn9cQ<0QQ%=PzZItLkC*ef9WJUvfITKWh#D zc#__8`4am9%#NslIUw+<82#SR8AYG|woLfBg#!-&dqq}@P>|I0%lbdy0lSMmNe+}o zj0zZuFr6Wb?Y{Qy-S=|r`bdrDmhnmvkRnkdn`YCleU>Q$=je}LGhh>_QAj6aa_0Oc z%Swsmui;IRx7bN*=AAS@5yW&Y2hy;3&|HAiA8}!HT6!Z!RVn~MZg`RmI6&%#tBZDx zfD+y@Z~NWlk*4l13vmt3AK2wP!fQlnBbECL>?p)F?T)<`w&QN>cP_V>r7UTcsTaaP zTOb$f!P@zf$6>890NVKbIkG8rE?9!Y97sMSZjfF?A zYR8lp`LMoz~O?iaZN;gcX;LC-%Ia*R%A&SLx!YIf29?P+=XAAojK8!^OU*@?R&DK!#G_lsn!#;S375uZ&B0HH1|BO0R90$U>qs zSvHv>H~mAgNCcjo-e+;RjY6B9NCbQrZ|BHjTkehaU<9CSkdd>Vl*ifA2LNOP&R2Qdy3k3-TQ+ zbq=#vI43x`s=%~cGyN&y4Y!FxhwgDe@i6uv8^BLL&3z*SO=D0aLjih?gY4-9uWp5or)H+v~w6n5X#F-I52z=Z_p4JB(;M| zeaVFhuR2|3UD2MzVc~^nSoD2(dD#uL_1PdnIxeA{V5n`#3xf1Zx@4lw(DsQ&H$h zw#%3O<1173hjg2_nhKi!d1ej=h7y`hVjCNB6|HTnx>SWuCE-kgTnfT+YGX4_Lun({ zDv2`>d3vrS)tTf7ps_vvh!Cx^e1BFuWnEAh0(7fkNk|-3oU|iRWdsC6U)?Raft~HN z;^$U}vZK5O8|LV$>6X5T(uYkblv{zwPxnQBh(BQ5tA~J!vGiAMYP^_ki~pkIxDfOZ zUJDwq%O~WueeV6%uN<54&u*c&E4y431cklBNrb06zGOOy4XNT~JS-q(s6@)F@ovbe ze`fial(O4(-su%6@@1+V0MsdLLMyE8;)nou(7}czU(5ASaZYDT(kUZ0L(&g$nF^n9 z9-Pi`ZZLX&)^*M6As4_2Mmc9S7OT)F8KkL2NJ)KJcnCuWU=Wy402A&45#Q9Id~BBH z0cY*xlv!uXzKrXLH!xQu(OtJvEj|0-DmRj1vjFz{c*I4$Pe(+_V|^b~S!0xm{8lq= zZv)@NlcyL3Xdz+*|L137F7y6L-2VsrKw=q^S>F6i%<{Fr8zk06$Ay-(!L$fY@7mcng!2}L0t zgi|KxfB63Xtk_Q8#ZPipQ@!zgjdpEIbK_?q17Hoi4Eiyun$hrc>T(7pOLVLQE=lgGwA+A308p& z7@=09(|$>eLy5gLe{*|3b(M;1n;C^~v?o88jYib48eR4$QGsBFzd}3QuwO^_XE(=B zq+hMi0UFC|dB{LCwch7;zYT=NK})O%sgi0k#yV;My@24^B1+CuZmYOh0^b)5Ba_)) zC%i#_Iev&nsu%I|1N5=MVc#PrlunKAs&hY|3s5;@}`>sB>}gzxuB zB=2vrRyB3uiyW(hkDUNe1@&(b`;>ZvGgw|@s{zVC#_`HXIN_^J@Etb zA7A+F?ot37T{<-vTy8h&b3e+WKHE1oh;pUQrN4yRRrx?mT_9jRa2i4l1fUnLW^Cbl z!I1>VzyFe?VELWWhM?@?t-YPZkD-Qjo@bC2(o#ZtZmr{KZsdFWItV`rs$gp{724@C zL8K5}E0+DHcWcL^{BGei4>@J-3%a#$y6;I}=upc};-NDv-z#kPX26ylOpH)Ov1uU{ zkLj6oiH6l_s+B~_z;|Jc2oi?naS7#3H63~~lWj4rUnd=fCnKdkik<@R&kch9q##G{ z4u!%=rlM~Yp3jk*t8}1B`Sv6<%Z^}~1e@aq zg|JQ`QO2pSjAm-g*?IrNc$^~sIrNBo2$m|Sxanr?Mfs>2@Auu49 zGXlsS<9XS1&8h(dD*Hl&5HBDG!^pJ*lkau_Ur+7`7z;rcs$hT4we?3bT=7Fe<>{5( z2m2(c+hUz2BTHM8dCe*Z3XX&Av;b~a=$6EF>&^E8%nyxO@m_n!q&XD^A{SRjRZQ0L~qDeC=j&0$j6=LNIz@`ni^>ch|sv}^6 zlm>?28yPl@WmDPR?Y-A9X{U9Dv_IsbXJnzKCjkRksLOg#42uG2mE_acbTQ4)J|1V>%U@K(FP3AYhL0U zdeOCPN1qLv!|#c=p!_+%VNV(GHt`RuLRV^vz<5tt-r)yOK**kUWPspVAf|}ZL{LS= z@k(@@!P&W!>wwe`x{+GrFSWhHov7hu?{KuuT%kl#WO@*WX$i_@retlhQBj++SVNCx z5$78LxP>Z=^aJ)D280r_jj=zFfMJFXCIe^B{~V@d1rl_F(qo&AB4bC-vYL>x2jSKX zpuTG-6kgp3e^T&+dtV*i6a~)v@n?n*MffN59y}<0djUX zt27R+SE#hp8bzc#;rk$jw3r4)Q@eI$*`_)=Pvge8@8|8>H3X)<9YX6cXa=ii#Le;(qKm@%0-7$>2ShnYc`j#zJ7gu_FE^?uAkL|H)UIH#gPu^40!6^J=^ zr`}iwa^!4tzW~vOMZAaKF>*8A{^8m$i(VK)>?=#l`xrVe>wseSvM_aF zATNkY>kM_P3?1kE`uIq#mvr-wuTgUH0N<&JhF=(E9%^NS*HLm!4GZ4_XI zL=R5tlG5Mk_1rPfg)sk^llFuKPMPBhuU|L5q#yP_mzxp1o&pAzi-X31sgFpIHn@($ z_>=`AB5(8tP6p2zS5VEvH5J$M` z_much3>S7t3Yo`Yx!>83-hW9LYzDKP?mKdkD#QAK8*M((sx{eBQdrR<^3ZhFP81+& zBnJMUefQyNBji~$5d88Wfw1Lv59aJN9t2!pABLg;ewJ#LXL-10;QcJl+Y4Mtngb)k6JZlCf)3uD_u)J3sYyN;NN5hNbg$%W!i-GK%e&!Us)2IExWSss$YG(hm3kJ-h%yD z>8q^n$+4I(_y_mbT{du4P%h1j3oSpjhY97{+IZ`aA4ug!vNJ6*p?<2H(2w+GD3j$I z1TUXGyNzdf>_yB3grP~FZUs<2Quw;eEi*7s(-MiIkQ%@J^+WGdQvYSUN+TRiD-xto zJ=OUU+kxGYc!HCLNbCvR4lGTp~#L;DFzGd-#gJe*xf(P3hDQz|y)?b9mwU3WUVnpcqXM<@w%r-k*Wr^gzAv)8T^sqA=Ye z!7qy&exJmAcAt~CwS#@yNmjr8*T*!A6w4~E*ibaLRs0CFo(;R3=ODhDt6zWNodmo0 zXx&bT$6&+5c>a|WJ)F4G-^GjY0H#*tY=UNyYr_q5fsrcjk(c^~e*7Lf`!Jd`)p412 zn|^*hV= zFI4UbwA%X@smDd$cQOiMC%jfitTxTb+#`9`G=2rJDfK!E=5ra|So>lc{X1$~w28i+ z4p&cTGwZ#5VueiXS9O8#;RR$yg7tL9!^)Sz&pZYIzlSh}0}V{LxL$Cu%B4U5_}k}- zm~|CsD<076x@<>m=6w6N?WaThIBP`!u{-;WF)xc=2otx*lwf|5+MkdJePjh(B z9SH+%cHGCMAXNxB{_3^otDWdsV7Ob6n{0 z+&!(;iaHOX__5z_$Qk{%xYV%Ig@7iokGBwR`3642ZP#H#v9QGbWl8<|MS*=@qO@Uj z6+SZ_v9`1paUe5tFN~v(b#J3a_Lx0+;r9giZIx-A5TxdbG>xi#AZ5_z1V}B^n)sxT zz49}eK7EWb6wR!6-qQOrHQHkUvshvq%=G2d&@(#XM*Am1;WbnJ{X_!a{ZkphD$^TQ z=Iskb&}=lBm(RHiwJoGg`*NiQ6#RB$T#LF+>#ef;Jne&MxKPX!#r`&TVEFsp2jnNx>dClzpcPy&G&13a_<0qaR3i+k212~hoQ z8nMk{JP-t04I{GW5gUBqcJW-jSMrlw}>p)ptx?WKuCUV77taMiV zHok9V=6yv+Uts@fMY&A}amC=!Yj}eL@=e%XJ#%?agkt1jWF+10{(E9mHLDa>Ll7Vj zG=3cp%ljIB-6pC}6&`xJ*6WCP|IlglLWJ^?yviI8Ve)?V_i4%n;olzny62_`-|IGi z^=}p_O>Z8M;c4|RExu70E7ePW(HWVS&E$+LL6xSQgB`QfMQJ|4pCTFowA39p5P-|$ zUtM_H2HnP8_RoS~Vwk(FhbG zH41licj%=0a;Ln2STFBvU}Ne&O&%8bYKj!h1FA#sNM`232fX|U3QPp#3C?mN2;hE9 z;)!@5ixSPl<89^7gwhHc2YAX1KJK$#*3`KOMIQ253q7-*RJ5k)zp9GBO|Ga~X*^}US5oN@aG&waHV%vi~r{t^`ptTxb zL}q1W8S7*>7oWwvgV4uFLZ(@k`R*=LO_|Gu`prs~!WQXj-NLIa^2(7IHg>BG^N zc|i{-^=&Cek9dkJFQys|sjG9i>LLz|;yCv{^1i%c*h>8zF91kLvS9HBQi~ZU!JL`B zK8N+U0fr1*6??Ium)AF!6tc1eGhXIYL6IRT7rmKp7+>?%5Pa6zC5)KY$ycF0ZJ`G5nEQDG100U-jLkH8^UE4g6wq?sg%pP=-$&G#bcN`^?w3a6 z((s$6eRKcSEIslW-kk5Qi|5Mg-(xdLF}PxxVh$PuO}#aR6pW1kV4Af!Bqh*btXNNZ z>-4(IUl+L4dw+3LcpGut=qB45O+W)Q5?*zZ2A6rJcg`qkSvWA!j^r2mqKuCm6`Py? z@^T#Ux04HemPGd!Hs7NkZdVn1}8_j`o?)*OKZGS!`ff)gF zG?v-lj$wWNWCcw2Mg2o18D~1?3_b0XzdiKBNkYSDpcv@&kp0POmweJE2ZkIQ3B!a! zIgIoE+Xv?;34kyo^QYjZk+tEqZvq^#QG(OzX4~X+KtsoQoddTWUR(yo8R+ObEF1j<-syWOb>)JQ&Zbdu(sctU%Mt zW&YR0{ttY2TTXYZ?~WNU&cES1Z2q(7SrWDh``!J(JM+Nk$!hu&Y;(7E`ZNKTe0w+% zJc?Qnw2B+%UR}0;cB0Rufa(7-3FF}?629@LgTiEC&2uyL6NxexOp?AKT^aAx3gi(W zao>r>MPw0eQ3>IV02uLsC@>yK_epX6GRg4{NEL2wPPF9=*L2RV3yyK8DhuEK>rmmV z`&Q~#c`lgR&93TdOCja|ewOXmPNRh7!&dMT(1ett#iDr8HZW~VqWW@7fe9B6;7S+? zbC`d4@MEau&mKlOPKd>*10q0c{~^baw6!a*w^sY#0Xim{oOsiXiDOhbG&kl3c$$n1 zMRrD83&QucDSEcV*7LIp8VTA@F<%qe+_c`L;6on(>SjAU^}5c9!BCffT>$VQhe=)z z8(=Ej{5>jhmjB3{xDfj2R@VmHQ!CqjlO4KnuOmvHy3K#po$yp_V;p_MKjh1`(rzj6 zHW956k1yvntz{_g?Xbs`avK(IjlTnsu%htO;D7 z?J#x^EzuvVn&NA=!MEj7cwe5A-Z$Zk2LBZH$~%E* zf`((xH0?`}hs|HA%mtwfOEsZJxxrennkTYcwP#FKO5%Lpc^JXhSpV|ZH$Wr;`}`_( zIP==gd3LYyVtwD|*ZJGi{7~x8{=^bGVqu0RJ`n_BZH9+}kz%-4ZRsImi@rx%=ZEKs zcPnUXo6hbJV>fH;@1|bAHIe0ijYI*&kdT|HkDS$9No9 zCHo=*HWb~U+Dtzxr+Esao}6@|;Pf+E$ay0$kQp#s{wlw+7aIKbMdf`OqhoG*;Tco0 zjrP}VQG#Y2cJuqoJg&5({)S(BA}q9T1lGeWRyu=Je|)I!6a+aj!IP^1({)ZYe&x6w zt3a)Dq^TB+A7CdB0-}#z2Ur$W&h3YVw8==!xONy$uQmDWh-@15iEOt!q2m&?ZLA|w z8loSb(0}7y6Xu0?M5Uf4>VZGluB`wMf2oh;m)ghxVda>3m}4%V)r^0nVQ5V6f3>*) z0&VN!N0~GC^P}vj$`EDMZEmVV;N&RISY2C;$0;2(<{Lt&PKzqRByQdiEHGAbwtbS zPj`Da5%U6k1oEtVzI}QNw;!hT6F+~|@=c@$C4NtO@=xgP?|5MyZAyuCzcvq4rdAv@C06%gZ`9%I);R6UGiGJobfux+<0DLS&|MSG4UH z_~o{^^9>ixMg~mY!-@Fai{xaE4^;qy9iZN15Gbn5ZqHWf>Jc5Rv6(#n8`1NcCsdmG zab*dSXVPaE?)wCalD;$ivF%@nB#7D`@YG04p6ed9m}4iJW|pfVMLE<-c{=-8$e?cH zUdU#mCj4gb zZKA^b9p*9S(}8@tw~1RNPHr7tQr;P+-)D8|sq=*o)G%RGqt> zzP5yf`pVxb)I51D_G~Xp^GNK zVI6sAX)a9s)e{8N3?35YA6aQTXuyszK3ah~CemzA&CII#8F&F#KN41~8I^&_%}6MCNb{W87qAF`zj_Y^szhb> z3p3}KbOxotY|(lD=;)`fYE_*{S}x;f^SW#)SU&5X#o|-R|trpa|L5PS5aa0 zTHw8%SDSVtU4?vyrhnq+^@dgFS)|(y{~(4j%3UEiO-rBM9%`)8(dh33pMLiuurNY# z#10AsQ7%*0Cu_DSAU}P;X(JwA64~Q_^R%d_zSm^6Aux?Pn70PM>9EvLeOX z&w9c)pGmcL22;MO3C_B>=NC0RJpMp8?#ZUf=GWRvy z6RHq3B}=MGVg?9@iKFBpsvnkVh3{Vpp=`CcD=u~@ql{my|6?3ssi3mCOPnjI&E}VC zc@X+Yl>;;DNo0W0`0th!X{?luDhOC{E8N=?!w}K1{V=)+1={m(f`Oc|N=07>}3;z{-(A zm{JL=j?Sro5iecmE2-pWlRf(r%|HEQ7kgwQ9+kt=NBhtQI7OwcZ#3%$Uf%^r2nhjY zoQ08MfC%_X{O9~WcirMZMhn#z^ux4Erx-tf-6bHD)9eH&^L>^jvAd^9A^DCDs?0;k zkm7LE*KjP6`2d17MrQaaLqd_Rka}J$csvUec#hw78<=s(hyR>065~YCVCA9+#Q+; za(*L0IEw!r5P|@-;x33L$Lv9 zcuN8YG&g{<(SeJG18~(b!5yywSqQiLAX0;---;}mF5&b4lg|T?LwKREa{9YX_-zL@ZE?Zqi@HxK^2KO1>0LATu{te=T zprmHtY)bDVfxI1S}KBE7V zznP7KQ8HekWU#W6mw`dr-boV}pMQR==&5=Q5T=_q091jfc;R*jX#&=MQ%~@E@9^?`$v48ks<>(fI(F6L(5ppKy|$HWng*bKOb(4|cMUB&z$#ob#XV z5-mg)gmFIybZf=znm3ZPyUO^GJfxt0kmHjaTZ|sthsxXw&}Y)fOUSg=JhRSR^UjZ- zhqqb}Wsyw4zdnj6@#BAJa#-PdI4_dgafFXh85DsEQ_cT+5)XpZq$fZlBA_9UsE9r6 zEFec5?uqN@QhJ^IzwZrwl-5J`CmVPv{(YDTqEqWR^dI;5hXc~cxP%B3v&~s0`Ct89 z@S`i~a^c%V^N81dDT*ItFS*&IN;@O$EgzX0e7x&}TD=!zS}hTpezBLS>mdX(5< z)8DEI(-o_D)c-UX@dA1MuJ*yc>Hf4|`*B2S_O>w*-tbUwtiu`;W(Ud{HTty@(&x(T(F&;M zJ=?H>6`B7nf-90e8V`WSVp|0oEKB-P2M{}4ZDawzvM&a!y>`Y#jCsD%T_l``@ah(I2nJs~Q|%uSKu@k!m~*8B*IoA{*TgtF<(5sHCGG;n@NE%~Xt(G$^&<87u;}Na zx-8cq0g`uA(&RBFo=-4Y1GUZ<``Zw{xL4jfHkZw~%~wvtGueszcXt)_QwH8g!; z%s&3kSa~R$dO$-%L-)c@_hi7&>{6L_M>OZFkUQu;{sL_bUMStNrt{{&O(Wn~*zPOk zB>dnfszb29NSTf2pqIs68k|p-UrSrxgLHqi?3N-UFa!LHy9n1)=s>`yS+J{MEzS@ zNlfGtpma7kG&LR3JE@wB%rFA*h~~KitlO=IP)ZjN6dQLM6qsry zHkB#cyNh#n`)}bCrN1My*;k)^@>e4gJ`LJK?2)Pwp?4Tl4)4FA0(tvY+#1jOUM)xw zlMz4x-f@g^+yKUN`?Vu)|AwujArnM~Pa@y*Q9S8eS(u{-S%(Z5=R~pRl5ZGDjdqH% zC8rW&{##wOpU_oTIG4WXMk4&%2t1;lWcW5&!yxmOT*!hBcKyTqEcNoO+R2;Q?Yj+W z1-Y4?59fijz4(MIDwGe4-baYf08UCs;r|YefD-Md2ST;=cxwpgW=tR76-dQVAhn^= zG9Wk5lQk%jIR@KNU!UMp6@BfU;r+;y4VQ)D2!Il9HX%yW-9nOzV+m$YKzVaO`B8S7t z$!S2Mz`xw>V(RjE`0>bQp<0y&h~Y=M#jpy!#=dE>`=e_AjSZq6u!Dy1xJf~-7|0F! zPR9|n`e_7D2DIV2H(CESQ}hA>U>n|6`%z?YKEA~)BOVY%y=jPV zT=44R!L?J)736X#csn|lfBJ)o8ixaZclguWgrGO<`TN2FMfO}7;5}d+BlK0yTSH3* z4!=;5rOh85&2|x=46hkNaz?)U8&=bcfh=N_#8BNpZ2v$aVBo;sk^*X`v;4-LU;D>! zM*h12MxXIQy)SfAqE4;jY)wgnppazZkdNNVVF;(PLf^qK$FgY9+VFyBKE7UC|f z`R|?&egV11K3s$rJ6!GvoeW=jV*!-e(wA;x(2=d0E_e_%0x--0o8#~m^H1%AH5Z^B zn!TNPn927*bvaf0pt}zhK0o^V@WlGwwKo(*nQ|Q~4_;>~-8y20`HP>@UJa)3nEnGG z5Hwhs|FcmFG16ZVNb5hL`2Gc1{zWIMM{_OiKewV!hCi}U!VuE?s9wU-QbZ!)+Y^tS zGzp5OSi5iq6hmEr$w}&9DFgoB+i*`q`8TBi^MVS{SKEb8Aw%@K7@XCo(De2A`6%mf&a2#~y1N)+kJLD$1HCP!22)(U}xo2|j?WRzt(11j8Z_*v;P$R+Ug*Gy3VxV4K; zGGUGabnW*`Z}~`ydXL-l9e=GC$pY#z|63vy>E*m=$=j}iWP{sRTh0%H54`t>2xYH% zsk+M&u&pNgMCM@3e)Xc?jBWX-TIR_cQ1Z!RW7!B zBjZX=+^3}?SE)B+$EP+0oi1Fp5blDT?*}nsP>filqXH{ms zxU<$hetC`u)Wi+x|EKL-`y^#aQX+sDYIa{M;V%LqLrOk~lR>u0Q!+pyQSU4zY`?E^ z|5@)C)w6G_=i5YYC5SE_u(7hDNYr}uKT|@DSqF%S++lTIbIk^$a>{~0IH8KNFEy%+ zW#$&!ynpgNJh>6uR~?2c)ZMW+h0OKu231(7L_vETPaR+(P)Zy%0~yGm>E9?@@x!Jy z3PYgS}Q@b}x}E#F27@F+j}0=&Ql4gES&f8acMrPAVlVs9$97`FR))R5wI zc&}KFI1UIewh>3PkhnB7u zS3AT8_*|nexznG|Z*DU0c!K@jsI4J)5#DyNi#|e#`l1Vv1`1)*NVcy0LZ``aL0n8B zecupJ(rhq3u8bW0NIRhKYq$v1li+jp*4hfAd&wxYDE8vn1TQ7S@bTM|I2Ob z8vMOIxA7&_j{AKmD+O@EyXT`|dElt0pED^@IV0m)RPBUs*5jW60>>w1!@_G3aBKzG z_f(KfAPBk}-jQtR*Sroq!*3rbQ_m27e+YdzQjUb<_*k8vc_C)y!@cj5E>NxUhPu&g z@Z2<~esU`)ih+4opWe+K7sbN9n*9@n>#@n3*o z?xoROgDuvhq>jJ;Ve{6i<3roQNfgo5^4Q4(|GNExO2Dr7GjgA2zWuKp_K)K0R(6lv z!l$!zW-+T6mb3gQaAFviTQi{|*t%>{(mhTdy+y;Re4qT@kccy#{b z&zWy~kLO@>*WPj2k#H)|7L&gAJ37DmHQAme#@m;(Y8Nu^`D5vf8sZFW#+lA2!HK=( zJ)#hO6JD*`o~&c*&46d}g=Qj@SsoB5ikC z^1V8E+&<-OzuS_C`p5<<(A6fB`LXT(!kV^0_~hL6PpW4={l%|#xgdh?5EIk~lu8{D z2hiyhv3Yxij_#$Wu>P@7SYsl`-~3;}Ktx{34_NL^Kwin&=?!HDv3elQDbcU*qyYpN z(#yw~f1vFGK-t%CC-qa-4FYHbA^h>bag-I&*qaxwn?Qv|idE$<>1H|Gr6JtUu(he2$eg!N z@HTF@dG1)*y;4fxe)4_ZkpaBHH9hXp9p4|gLrRQyuevRd@gSS}JhRnWqrvm|U@>qM z=yl7RQROTKwQtzP3!zUF)_6Ld#NGA6v~2{J9Dd`h6{%+XsU#qGLh%`fB1Hc?wfayK zN`H4BpDp)npVQuu$DVW1qsBS&AJ2eP%6Qw>;k{)Z$8%HL=Q4(a$Ng2_vHw&vA!1L+9zc8vaX2GtqJ{L-;gvF0IR$em zMQ8@{Qp3+3Quk)TJ$?I<8KmwzD*7#(q<@Mc`dchngW}cRG14(Z6K7{T|LhFXwhqUQ;BET;cYqPcAcMgt6M$V9$(?jHo@Sud$an$U&5F zZ1QNh^ztt)E*d#Ij;<43oSKKnd+WNr$_r}+s_O_x6DZSB10*5Q{ourqq>mTl| zx4y^(cy+9;t@R=*j>3_dmm_m)$k$#937V(sllby&5)Xex^UD-|m|q<(jEd#@DV(of zAd7sSdmS*zUDqJ9|K%O2J2OfdUiK{{b{PCy)pi<;hp~7v1CQj&4-10 zgO<3dqhYH1#-Fa}Q{pjql5>>P6gZH21zLfxZ4$SK4T@7b!|`nWF9b*84Bq8&Eht;9 z*P72x&NUCZ7*@B$`FtE=hz5b}S`|c6Ey+j@D1ZibjJaRlR;{cxAWv z?Nqa>QqV*H-*zzaPvpLMHt~nl(x6?vrPpR?zn7~wow?oj*1TKmx4j71>$hvtC$DLD zUrz0^tiP0792U&dxJxNv@r}Elsjn^aSLUu=9#mD{&9n8|ayIL$!H3s>%KEvbchBFW z%cd?VU83mGF#Dar9*s~w&AnmQRQIOvR+uWsuZ?+|a=TzApXO@q^(r%8=}iv#wCnFq z=K9}JbqU@k99Q%j-}NNk+qLCP)jXfmOO|)@?mHcnynd6({mJisP1_}u7k)|eYHXWK z63eQ)E$ufFi!3CWUY2gw%e>omCv}qEX66aH-k&35f9`Q@Us|NPetVqe8=dX*VxJdn ze`q7b=Dn(UA(2sf&g)cOmQFhNJ#<-aMELJZbA#@to>25@kbW<)&!X01 z%NMJt>1ST)tyX)h@?`DxhbgCHr>S4wv}WC&Nw-!{+Z7$2D}74QAcXTvip=M0%Tp_N zor=k`)t|ra^ySr-+(|R9mB(E=`MX#y(wSw)$!iymzB;^c*>%&^*7HxTnRga=soSZT zdDl+9s;r!v8hk6POtzBaig4pRp7eWF(<8gufvNHPu6xs-=e{;mnHzJyGKE+8L0j}; z@%8-e^UCL5HhMiR>sD3Rve&yVZ#{Q1*CO8c+qSr^Z#CN;)(X5>tGG5yUw3<+CfhaL z%bP;hZ?jvgJU67BWyiy74_)6r)_nSxttxn0`0?HE^5(uydHVgP+HE$V?Lv)Leti43 zWA|;f-RqX``95>)^P-fw!Vi{3KNsII-*5f){gdxqd%gVdB1sOBNe=nEW%;i~g_P8J w!5uhoe-Jcg1nPN%MiEAtgE$;km@@t6ukO)1^!cY^83Pb_y85}Sb4q9e0FIsP9{>OV literal 0 HcmV?d00001 diff --git a/bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/bluetooth_low_energy/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1632cfddf3d9dade342351e627a0a75609fb46 GIT binary patch literal 2218 zcmV;b2vzrqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuE6iGxuRCodHTWf3-RTMruyW6Fu zQYeUM04eX6D5c0FCjKKPrco1(K`<0SL=crI{PC3-^hZU0kQie$gh-5!7z6SH6Q0J% zqot*`H1q{R5fHFYS}dje@;kG=v$L0(yY0?wY2%*c?A&{2?!D*x?m71{of2gv!$5|C z3>qG_BW}7K_yUcT3A5C6QD<+{aq?x;MAUyAiJn#Jv8_zZtQ{P zTRzbL3U9!qVuZzS$xKU10KiW~Bgdcv1-!uAhQxf3a7q+dU6lj?yoO4Lq4TUN4}h{N z*fIM=SS8|C2$(T>w$`t@3Tka!(r!7W`x z-isCVgQD^mG-MJ;XtJuK3V{Vy72GQ83KRWsHU?e*wrhKk=ApIYeDqLi;JI1e zuvv}5^Dc=k7F7?nm3nIw$NVmU-+R>> zyqOR$-2SDpJ}Pt;^RkJytDVXNTsu|mI1`~G7yw`EJR?VkGfNdqK9^^8P`JdtTV&tX4CNcV4 z&N06nZa??Fw1AgQOUSE2AmPE@WO(Fvo`%m`cDgiv(fAeRA%3AGXUbsGw{7Q`cY;1BI#ac3iN$$Hw z0LT0;xc%=q)me?Y*$xI@GRAw?+}>=9D+KTk??-HJ4=A>`V&vKFS75@MKdSF1JTq{S zc1!^8?YA|t+uKigaq!sT;Z!&0F2=k7F0PIU;F$leJLaw2UI6FL^w}OG&!;+b%ya1c z1n+6-inU<0VM-Y_s5iTElq)ThyF?StVcebpGI znw#+zLx2@ah{$_2jn+@}(zJZ{+}_N9BM;z)0yr|gF-4=Iyu@hI*Lk=-A8f#bAzc9f z`Kd6K--x@t04swJVC3JK1cHY-Hq+=|PN-VO;?^_C#;coU6TDP7Bt`;{JTG;!+jj(` zw5cLQ-(Cz-Tlb`A^w7|R56Ce;Wmr0)$KWOUZ6ai0PhzPeHwdl0H(etP zUV`va_i0s-4#DkNM8lUlqI7>YQLf)(lz9Q3Uw`)nc(z3{m5ZE77Ul$V%m)E}3&8L0 z-XaU|eB~Is08eORPk;=<>!1w)Kf}FOVS2l&9~A+@R#koFJ$Czd%Y(ENTV&A~U(IPI z;UY+gf+&6ioZ=roly<0Yst8ck>(M=S?B-ys3mLdM&)ex!hbt+ol|T6CTS+Sc0jv(& z7ijdvFwBq;0a{%3GGwkDKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U z@~$z0V`OVtIbEx5pa|Tct|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-M2 z@O~lQ0OiKQp}o9I;?uxCgYVV?FH|?Riri*U$Zi_`V2eiA>l zdSm6;SEm6#T+SpcE8Ro_f2AwxzI z44hfe^WE3!h@W3RDyA_H440cpmYkv*)6m1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bluetooth_low_energy/example/macos/Runner/Configs/AppInfo.xcconfig b/bluetooth_low_energy/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..1aaf824 --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = bluetooth_low_energy_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = dev.yanshouwang.bluetoothLowEnergyExample + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2023 dev.yanshouwang. All rights reserved. diff --git a/bluetooth_low_energy/example/macos/Runner/Configs/Debug.xcconfig b/bluetooth_low_energy/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/bluetooth_low_energy/example/macos/Runner/Configs/Release.xcconfig b/bluetooth_low_energy/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/bluetooth_low_energy/example/macos/Runner/Configs/Warnings.xcconfig b/bluetooth_low_energy/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/bluetooth_low_energy/example/macos/Runner/DebugProfile.entitlements b/bluetooth_low_energy/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..14a39b7 --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.device.bluetooth + + com.apple.security.network.server + + + diff --git a/bluetooth_low_energy/example/macos/Runner/Info.plist b/bluetooth_low_energy/example/macos/Runner/Info.plist new file mode 100644 index 0000000..ea16286 --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSBluetoothAlwaysUsageDescription + Hello Bluetooth Low Energy! + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/bluetooth_low_energy/example/macos/Runner/MainFlutterWindow.swift b/bluetooth_low_energy/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..3cc05eb --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/bluetooth_low_energy/example/macos/Runner/Release.entitlements b/bluetooth_low_energy/example/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/bluetooth_low_energy/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/bluetooth_low_energy/example/macos/RunnerTests/RunnerTests.swift b/bluetooth_low_energy/example/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..3db3281 --- /dev/null +++ b/bluetooth_low_energy/example/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,27 @@ +import FlutterMacOS +import Cocoa +import XCTest + +@testable import bluetooth_low_energy + +// This demonstrates a simple unit test of the Swift portion of this plugin's implementation. +// +// See https://developer.apple.com/documentation/xctest for more information about using XCTest. + +class RunnerTests: XCTestCase { + + func testGetPlatformVersion() { + let plugin = BluetoothLowEnergyPlugin() + + let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) + + let resultExpectation = expectation(description: "result block must be called.") + plugin.handle(call) { result in + XCTAssertEqual(result as! String, + "macOS " + ProcessInfo.processInfo.operatingSystemVersionString) + resultExpectation.fulfill() + } + waitForExpectations(timeout: 1) + } + +} diff --git a/bluetooth_low_energy/example/pubspec.lock b/bluetooth_low_energy/example/pubspec.lock new file mode 100644 index 0000000..a0f0aac --- /dev/null +++ b/bluetooth_low_energy/example/pubspec.lock @@ -0,0 +1,389 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + args: + dependency: transitive + description: + name: args + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + bluetooth_low_energy: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "2.0.0" + bluetooth_low_energy_android: + dependency: transitive + description: + path: "../../bluetooth_low_energy_android" + relative: true + source: path + version: "2.0.0" + bluetooth_low_energy_ios: + dependency: transitive + description: + path: "../../bluetooth_low_energy_ios" + relative: true + source: path + version: "2.0.0" + bluetooth_low_energy_linux: + dependency: transitive + description: + path: "../../bluetooth_low_energy_linux" + relative: true + source: path + version: "2.0.0" + bluetooth_low_energy_macos: + dependency: transitive + description: + path: "../../bluetooth_low_energy_macos" + relative: true + source: path + version: "2.0.0" + bluetooth_low_energy_platform_interface: + dependency: transitive + description: + path: "../../bluetooth_low_energy_platform_interface" + relative: true + source: path + version: "2.0.0" + bluetooth_low_energy_windows: + dependency: transitive + description: + path: "../../bluetooth_low_energy_windows" + relative: true + source: path + version: "2.0.0" + bluez: + dependency: transitive + description: + name: bluez + sha256: bfd004c81e3de0f06dce8580bc39a4600e4a6efe465a866b31d4d954c9f356aa + url: "https://pub.dev" + source: hosted + version: "0.8.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" + source: hosted + version: "1.17.1" + convert: + dependency: "direct main" + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" + source: hosted + version: "1.0.5" + dbus: + dependency: transitive + description: + name: dbus + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" + source: hosted + version: "0.7.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 + url: "https://pub.dev" + source: hosted + version: "2.0.2" + file: + dependency: transitive + description: + name: file + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_driver: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + fuchsia_remote_debug_protocol: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + integration_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + intl: + dependency: "direct main" + description: + name: intl + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + url: "https://pub.dev" + source: hosted + version: "0.18.1" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + lints: + dependency: transitive + description: + name: lints + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + url: "https://pub.dev" + source: hosted + version: "0.12.15" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + url: "https://pub.dev" + source: hosted + version: "5.4.0" + platform: + dependency: transitive + description: + name: platform + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + process: + dependency: transitive + description: + name: process + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" + source: hosted + version: "4.2.4" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + sync_http: + dependency: transitive + description: + name: sync_http + sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + url: "https://pub.dev" + source: hosted + version: "0.5.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe + url: "https://pub.dev" + source: hosted + version: "11.3.0" + webdriver: + dependency: transitive + description: + name: webdriver + sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + win32: + dependency: transitive + description: + name: win32 + sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0 + url: "https://pub.dev" + source: hosted + version: "5.0.6" + xml: + dependency: transitive + description: + name: xml + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + url: "https://pub.dev" + source: hosted + version: "6.3.0" +sdks: + dart: ">=3.0.3 <4.0.0" + flutter: ">=3.3.0" diff --git a/example/pubspec.yaml b/bluetooth_low_energy/example/pubspec.yaml similarity index 97% rename from example/pubspec.yaml rename to bluetooth_low_energy/example/pubspec.yaml index 61cdae1..4d7d94e 100644 --- a/example/pubspec.yaml +++ b/bluetooth_low_energy/example/pubspec.yaml @@ -1,12 +1,11 @@ name: bluetooth_low_energy_example description: Demonstrates how to use the bluetooth_low_energy plugin. - # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.17.6 <3.0.0" + sdk: '>=3.0.3 <4.0.0' # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -29,9 +28,12 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 - convert: ^3.0.2 + convert: ^3.1.1 + intl: ^0.18.1 dev_dependencies: + integration_test: + sdk: flutter flutter_test: sdk: flutter diff --git a/example/test/widget_test.dart b/bluetooth_low_energy/example/test/widget_test.dart similarity index 100% rename from example/test/widget_test.dart rename to bluetooth_low_energy/example/test/widget_test.dart diff --git a/bluetooth_low_energy/example/windows/.gitignore b/bluetooth_low_energy/example/windows/.gitignore new file mode 100644 index 0000000..d492d0d --- /dev/null +++ b/bluetooth_low_energy/example/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/bluetooth_low_energy/example/windows/CMakeLists.txt b/bluetooth_low_energy/example/windows/CMakeLists.txt new file mode 100644 index 0000000..b2da711 --- /dev/null +++ b/bluetooth_low_energy/example/windows/CMakeLists.txt @@ -0,0 +1,104 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(bluetooth_low_energy_example LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "bluetooth_low_energy_example") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + +# Enable the test target. +set(include_bluetooth_low_energy_tests TRUE) + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/bluetooth_low_energy/example/windows/flutter/CMakeLists.txt b/bluetooth_low_energy/example/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..930d207 --- /dev/null +++ b/bluetooth_low_energy/example/windows/flutter/CMakeLists.txt @@ -0,0 +1,104 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.cc b/bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..37c2554 --- /dev/null +++ b/bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,14 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + BluetoothLowEnergyWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("BluetoothLowEnergyWindowsPluginCApi")); +} diff --git a/bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.h b/bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/bluetooth_low_energy/example/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/bluetooth_low_energy/example/windows/flutter/generated_plugins.cmake b/bluetooth_low_energy/example/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..4b19aa9 --- /dev/null +++ b/bluetooth_low_energy/example/windows/flutter/generated_plugins.cmake @@ -0,0 +1,24 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + bluetooth_low_energy_windows +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/bluetooth_low_energy/example/windows/runner/CMakeLists.txt b/bluetooth_low_energy/example/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..394917c --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/bluetooth_low_energy/example/windows/runner/Runner.rc b/bluetooth_low_energy/example/windows/runner/Runner.rc new file mode 100644 index 0000000..cdbc0d4 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "dev.yanshouwang" "\0" + VALUE "FileDescription", "bluetooth_low_energy_example" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "bluetooth_low_energy_example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2023 dev.yanshouwang. All rights reserved." "\0" + VALUE "OriginalFilename", "bluetooth_low_energy_example.exe" "\0" + VALUE "ProductName", "bluetooth_low_energy_example" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/bluetooth_low_energy/example/windows/runner/flutter_window.cpp b/bluetooth_low_energy/example/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..955ee30 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/flutter_window.cpp @@ -0,0 +1,71 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/bluetooth_low_energy/example/windows/runner/flutter_window.h b/bluetooth_low_energy/example/windows/runner/flutter_window.h new file mode 100644 index 0000000..6da0652 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/bluetooth_low_energy/example/windows/runner/main.cpp b/bluetooth_low_energy/example/windows/runner/main.cpp new file mode 100644 index 0000000..eafecf3 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"bluetooth_low_energy_example", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/bluetooth_low_energy/example/windows/runner/resource.h b/bluetooth_low_energy/example/windows/runner/resource.h new file mode 100644 index 0000000..66a65d1 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/bluetooth_low_energy/example/windows/runner/resources/app_icon.ico b/bluetooth_low_energy/example/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c04e20caf6370ebb9253ad831cc31de4a9c965f6 GIT binary patch literal 33772 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 literal 0 HcmV?d00001 diff --git a/bluetooth_low_energy/example/windows/runner/runner.exe.manifest b/bluetooth_low_energy/example/windows/runner/runner.exe.manifest new file mode 100644 index 0000000..a42ea76 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/bluetooth_low_energy/example/windows/runner/utils.cpp b/bluetooth_low_energy/example/windows/runner/utils.cpp new file mode 100644 index 0000000..b2b0873 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length <= 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/bluetooth_low_energy/example/windows/runner/utils.h b/bluetooth_low_energy/example/windows/runner/utils.h new file mode 100644 index 0000000..3879d54 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/bluetooth_low_energy/example/windows/runner/win32_window.cpp b/bluetooth_low_energy/example/windows/runner/win32_window.cpp new file mode 100644 index 0000000..60608d0 --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/win32_window.cpp @@ -0,0 +1,288 @@ +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/bluetooth_low_energy/example/windows/runner/win32_window.h b/bluetooth_low_energy/example/windows/runner/win32_window.h new file mode 100644 index 0000000..e901dde --- /dev/null +++ b/bluetooth_low_energy/example/windows/runner/win32_window.h @@ -0,0 +1,102 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/ios/.gitignore b/bluetooth_low_energy/ios/.gitignore similarity index 100% rename from ios/.gitignore rename to bluetooth_low_energy/ios/.gitignore diff --git a/ios/Assets/.gitkeep b/bluetooth_low_energy/ios/Assets/.gitkeep similarity index 100% rename from ios/Assets/.gitkeep rename to bluetooth_low_energy/ios/Assets/.gitkeep diff --git a/bluetooth_low_energy/ios/Classes/BluetoothLowEnergyPlugin.swift b/bluetooth_low_energy/ios/Classes/BluetoothLowEnergyPlugin.swift new file mode 100644 index 0000000..dbbf6d0 --- /dev/null +++ b/bluetooth_low_energy/ios/Classes/BluetoothLowEnergyPlugin.swift @@ -0,0 +1,19 @@ +import Flutter +import UIKit + +public class BluetoothLowEnergyPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "bluetooth_low_energy", binaryMessenger: registrar.messenger()) + let instance = BluetoothLowEnergyPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "getPlatformVersion": + result("iOS " + UIDevice.current.systemVersion) + default: + result(FlutterMethodNotImplemented) + } + } +} diff --git a/ios/bluetooth_low_energy.podspec b/bluetooth_low_energy/ios/bluetooth_low_energy.podspec similarity index 92% rename from ios/bluetooth_low_energy.podspec rename to bluetooth_low_energy/ios/bluetooth_low_energy.podspec index 1825560..c812080 100644 --- a/ios/bluetooth_low_energy.podspec +++ b/bluetooth_low_energy/ios/bluetooth_low_energy.podspec @@ -15,8 +15,7 @@ A new Flutter plugin project. s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency 'SwiftProtobuf', '~> 1.20' - s.platform = :ios, '9.0' + s.platform = :ios, '11.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/bluetooth_low_energy/lib/bluetooth_low_energy.dart b/bluetooth_low_energy/lib/bluetooth_low_energy.dart new file mode 100644 index 0000000..bc504e4 --- /dev/null +++ b/bluetooth_low_energy/lib/bluetooth_low_energy.dart @@ -0,0 +1 @@ +export 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; diff --git a/bluetooth_low_energy/linux/CMakeLists.txt b/bluetooth_low_energy/linux/CMakeLists.txt new file mode 100644 index 0000000..1230a30 --- /dev/null +++ b/bluetooth_low_energy/linux/CMakeLists.txt @@ -0,0 +1,94 @@ +# The Flutter tooling requires that developers have CMake 3.10 or later +# installed. You should not increase this version, as doing so will cause +# the plugin to fail to compile for some customers of the plugin. +cmake_minimum_required(VERSION 3.10) + +# Project-level configuration. +set(PROJECT_NAME "bluetooth_low_energy") +project(${PROJECT_NAME} LANGUAGES CXX) + +# This value is used when generating builds using this plugin, so it must +# not be changed. +set(PLUGIN_NAME "bluetooth_low_energy_plugin") + +# Any new source files that you add to the plugin should be added here. +list(APPEND PLUGIN_SOURCES + "bluetooth_low_energy_plugin.cc" +) + +# Define the plugin library target. Its name must not be changed (see comment +# on PLUGIN_NAME above). +add_library(${PLUGIN_NAME} SHARED + ${PLUGIN_SOURCES} +) + +# Apply a standard set of build settings that are configured in the +# application-level CMakeLists.txt. This can be removed for plugins that want +# full control over build settings. +apply_standard_settings(${PLUGIN_NAME}) + +# Symbols are hidden by default to reduce the chance of accidental conflicts +# between plugins. This should not be removed; any symbols that should be +# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro. +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) + +# Source include directories and library dependencies. Add any plugin-specific +# dependencies here. +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) +target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) + +# List of absolute paths to libraries that should be bundled with the plugin. +# This list could contain prebuilt libraries, or libraries created by an +# external build triggered from this build file. +set(bluetooth_low_energy_bundled_libraries + "" + PARENT_SCOPE +) + +# === Tests === +# These unit tests can be run from a terminal after building the example. + +# Only enable test builds when building the example (which sets this variable) +# so that plugin clients aren't building the tests. +if (${include_${PROJECT_NAME}_tests}) +if(${CMAKE_VERSION} VERSION_LESS "3.11.0") +message("Unit tests require CMake 3.11.0 or later") +else() +set(TEST_RUNNER "${PROJECT_NAME}_test") +enable_testing() + +# Add the Google Test dependency. +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/release-1.11.0.zip +) +# Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +# Disable install commands for gtest so it doesn't end up in the bundle. +set(INSTALL_GTEST OFF CACHE BOOL "Disable installation of googletest" FORCE) + +FetchContent_MakeAvailable(googletest) + +# The plugin's exported API is not very useful for unit testing, so build the +# sources directly into the test binary rather than using the shared library. +add_executable(${TEST_RUNNER} + test/bluetooth_low_energy_plugin_test.cc + ${PLUGIN_SOURCES} +) +apply_standard_settings(${TEST_RUNNER}) +target_include_directories(${TEST_RUNNER} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") +target_link_libraries(${TEST_RUNNER} PRIVATE flutter) +target_link_libraries(${TEST_RUNNER} PRIVATE PkgConfig::GTK) +target_link_libraries(${TEST_RUNNER} PRIVATE gtest_main gmock) + +# Enable automatic test discovery. +include(GoogleTest) +gtest_discover_tests(${TEST_RUNNER}) + +endif() # CMake version check +endif() # include_${PROJECT_NAME}_tests \ No newline at end of file diff --git a/bluetooth_low_energy/linux/bluetooth_low_energy_plugin.cc b/bluetooth_low_energy/linux/bluetooth_low_energy_plugin.cc new file mode 100644 index 0000000..b4a8c4a --- /dev/null +++ b/bluetooth_low_energy/linux/bluetooth_low_energy_plugin.cc @@ -0,0 +1,76 @@ +#include "include/bluetooth_low_energy/bluetooth_low_energy_plugin.h" + +#include +#include +#include + +#include + +#include "bluetooth_low_energy_plugin_private.h" + +#define BLUETOOTH_LOW_ENERGY_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), bluetooth_low_energy_plugin_get_type(), \ + BluetoothLowEnergyPlugin)) + +struct _BluetoothLowEnergyPlugin { + GObject parent_instance; +}; + +G_DEFINE_TYPE(BluetoothLowEnergyPlugin, bluetooth_low_energy_plugin, g_object_get_type()) + +// Called when a method call is received from Flutter. +static void bluetooth_low_energy_plugin_handle_method_call( + BluetoothLowEnergyPlugin* self, + FlMethodCall* method_call) { + g_autoptr(FlMethodResponse) response = nullptr; + + const gchar* method = fl_method_call_get_name(method_call); + + if (strcmp(method, "getPlatformVersion") == 0) { + response = get_platform_version(); + } else { + response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); + } + + fl_method_call_respond(method_call, response, nullptr); +} + +FlMethodResponse* get_platform_version() { + struct utsname uname_data = {}; + uname(&uname_data); + g_autofree gchar *version = g_strdup_printf("Linux %s", uname_data.version); + g_autoptr(FlValue) result = fl_value_new_string(version); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static void bluetooth_low_energy_plugin_dispose(GObject* object) { + G_OBJECT_CLASS(bluetooth_low_energy_plugin_parent_class)->dispose(object); +} + +static void bluetooth_low_energy_plugin_class_init(BluetoothLowEnergyPluginClass* klass) { + G_OBJECT_CLASS(klass)->dispose = bluetooth_low_energy_plugin_dispose; +} + +static void bluetooth_low_energy_plugin_init(BluetoothLowEnergyPlugin* self) {} + +static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call, + gpointer user_data) { + BluetoothLowEnergyPlugin* plugin = BLUETOOTH_LOW_ENERGY_PLUGIN(user_data); + bluetooth_low_energy_plugin_handle_method_call(plugin, method_call); +} + +void bluetooth_low_energy_plugin_register_with_registrar(FlPluginRegistrar* registrar) { + BluetoothLowEnergyPlugin* plugin = BLUETOOTH_LOW_ENERGY_PLUGIN( + g_object_new(bluetooth_low_energy_plugin_get_type(), nullptr)); + + g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); + g_autoptr(FlMethodChannel) channel = + fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), + "bluetooth_low_energy", + FL_METHOD_CODEC(codec)); + fl_method_channel_set_method_call_handler(channel, method_call_cb, + g_object_ref(plugin), + g_object_unref); + + g_object_unref(plugin); +} diff --git a/bluetooth_low_energy/linux/bluetooth_low_energy_plugin_private.h b/bluetooth_low_energy/linux/bluetooth_low_energy_plugin_private.h new file mode 100644 index 0000000..ed272ce --- /dev/null +++ b/bluetooth_low_energy/linux/bluetooth_low_energy_plugin_private.h @@ -0,0 +1,10 @@ +#include + +#include "include/bluetooth_low_energy/bluetooth_low_energy_plugin.h" + +// This file exposes some plugin internals for unit testing. See +// https://github.com/flutter/flutter/issues/88724 for current limitations +// in the unit-testable API. + +// Handles the getPlatformVersion method call. +FlMethodResponse *get_platform_version(); diff --git a/bluetooth_low_energy/linux/include/bluetooth_low_energy/bluetooth_low_energy_plugin.h b/bluetooth_low_energy/linux/include/bluetooth_low_energy/bluetooth_low_energy_plugin.h new file mode 100644 index 0000000..55ef70c --- /dev/null +++ b/bluetooth_low_energy/linux/include/bluetooth_low_energy/bluetooth_low_energy_plugin.h @@ -0,0 +1,26 @@ +#ifndef FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_H_ +#define FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_H_ + +#include + +G_BEGIN_DECLS + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) +#else +#define FLUTTER_PLUGIN_EXPORT +#endif + +typedef struct _BluetoothLowEnergyPlugin BluetoothLowEnergyPlugin; +typedef struct { + GObjectClass parent_class; +} BluetoothLowEnergyPluginClass; + +FLUTTER_PLUGIN_EXPORT GType bluetooth_low_energy_plugin_get_type(); + +FLUTTER_PLUGIN_EXPORT void bluetooth_low_energy_plugin_register_with_registrar( + FlPluginRegistrar* registrar); + +G_END_DECLS + +#endif // FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_H_ diff --git a/bluetooth_low_energy/linux/test/bluetooth_low_energy_plugin_test.cc b/bluetooth_low_energy/linux/test/bluetooth_low_energy_plugin_test.cc new file mode 100644 index 0000000..82160d1 --- /dev/null +++ b/bluetooth_low_energy/linux/test/bluetooth_low_energy_plugin_test.cc @@ -0,0 +1,31 @@ +#include +#include +#include + +#include "include/bluetooth_low_energy/bluetooth_low_energy_plugin.h" +#include "bluetooth_low_energy_plugin_private.h" + +// This demonstrates a simple unit test of the C portion of this plugin's +// implementation. +// +// Once you have built the plugin's example app, you can run these tests +// from the command line. For instance, for a plugin called my_plugin +// built for x64 debug, run: +// $ build/linux/x64/debug/plugins/my_plugin/my_plugin_test + +namespace bluetooth_low_energy { +namespace test { + +TEST(BluetoothLowEnergyPlugin, GetPlatformVersion) { + g_autoptr(FlMethodResponse) response = get_platform_version(); + ASSERT_NE(response, nullptr); + ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response)); + FlValue* result = fl_method_success_response_get_result( + FL_METHOD_SUCCESS_RESPONSE(response)); + ASSERT_EQ(fl_value_get_type(result), FL_VALUE_TYPE_STRING); + // The full string varies, so just validate that it has the right format. + EXPECT_THAT(fl_value_get_string(result), testing::StartsWith("Linux ")); +} + +} // namespace test +} // namespace bluetooth_low_energy diff --git a/bluetooth_low_energy/macos/Classes/BluetoothLowEnergyPlugin.swift b/bluetooth_low_energy/macos/Classes/BluetoothLowEnergyPlugin.swift new file mode 100644 index 0000000..c836587 --- /dev/null +++ b/bluetooth_low_energy/macos/Classes/BluetoothLowEnergyPlugin.swift @@ -0,0 +1,19 @@ +import Cocoa +import FlutterMacOS + +public class BluetoothLowEnergyPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "bluetooth_low_energy", binaryMessenger: registrar.messenger) + let instance = BluetoothLowEnergyPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "getPlatformVersion": + result("macOS " + ProcessInfo.processInfo.operatingSystemVersionString) + default: + result(FlutterMethodNotImplemented) + } + } +} diff --git a/bluetooth_low_energy/macos/bluetooth_low_energy.podspec b/bluetooth_low_energy/macos/bluetooth_low_energy.podspec new file mode 100644 index 0000000..6ae5f75 --- /dev/null +++ b/bluetooth_low_energy/macos/bluetooth_low_energy.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint bluetooth_low_energy.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'bluetooth_low_energy' + s.version = '0.0.1' + s.summary = 'A new Flutter plugin project.' + s.description = <<-DESC +A new Flutter plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'FlutterMacOS' + + s.platform = :osx, '10.11' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '5.0' +end diff --git a/bluetooth_low_energy/pubspec.yaml b/bluetooth_low_energy/pubspec.yaml new file mode 100644 index 0000000..c03d2c2 --- /dev/null +++ b/bluetooth_low_energy/pubspec.yaml @@ -0,0 +1,43 @@ +name: bluetooth_low_energy +description: A Flutter plugin for controlling the bluetooth low energy. +version: 2.0.0 +homepage: https://github.com/yanshouwang/bluetooth_low_energy + +environment: + sdk: '>=3.0.0 <4.0.0' + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + bluetooth_low_energy_platform_interface: + path: ../bluetooth_low_energy_platform_interface + bluetooth_low_energy_android: + path: ../bluetooth_low_energy_android + bluetooth_low_energy_ios: + path: ../bluetooth_low_energy_ios + bluetooth_low_energy_macos: + path: ../bluetooth_low_energy_macos + bluetooth_low_energy_windows: + path: ../bluetooth_low_energy_windows + bluetooth_low_energy_linux: + path: ../bluetooth_low_energy_linux + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + +flutter: + plugin: + platforms: + android: + default_package: bluetooth_low_energy_android + ios: + default_package: bluetooth_low_energy_ios + macos: + default_package: bluetooth_low_energy_macos + windows: + default_package: bluetooth_low_energy_windows + linux: + default_package: bluetooth_low_energy_linux diff --git a/bluetooth_low_energy/test/bluetooth_low_energy_test.dart b/bluetooth_low_energy/test/bluetooth_low_energy_test.dart new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/bluetooth_low_energy/test/bluetooth_low_energy_test.dart @@ -0,0 +1 @@ + diff --git a/bluetooth_low_energy/windows/.gitignore b/bluetooth_low_energy/windows/.gitignore new file mode 100644 index 0000000..b3eb2be --- /dev/null +++ b/bluetooth_low_energy/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/bluetooth_low_energy/windows/CMakeLists.txt b/bluetooth_low_energy/windows/CMakeLists.txt new file mode 100644 index 0000000..13df83f --- /dev/null +++ b/bluetooth_low_energy/windows/CMakeLists.txt @@ -0,0 +1,96 @@ +# The Flutter tooling requires that developers have a version of Visual Studio +# installed that includes CMake 3.14 or later. You should not increase this +# version, as doing so will cause the plugin to fail to compile for some +# customers of the plugin. +cmake_minimum_required(VERSION 3.14) + +# Project-level configuration. +set(PROJECT_NAME "bluetooth_low_energy") +project(${PROJECT_NAME} LANGUAGES CXX) + +# This value is used when generating builds using this plugin, so it must +# not be changed +set(PLUGIN_NAME "bluetooth_low_energy_plugin") + +# Any new source files that you add to the plugin should be added here. +list(APPEND PLUGIN_SOURCES + "bluetooth_low_energy_plugin.cpp" + "bluetooth_low_energy_plugin.h" +) + +# Define the plugin library target. Its name must not be changed (see comment +# on PLUGIN_NAME above). +add_library(${PLUGIN_NAME} SHARED + "include/bluetooth_low_energy/bluetooth_low_energy_plugin_c_api.h" + "bluetooth_low_energy_plugin_c_api.cpp" + ${PLUGIN_SOURCES} +) + +# Apply a standard set of build settings that are configured in the +# application-level CMakeLists.txt. This can be removed for plugins that want +# full control over build settings. +apply_standard_settings(${PLUGIN_NAME}) + +# Symbols are hidden by default to reduce the chance of accidental conflicts +# between plugins. This should not be removed; any symbols that should be +# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro. +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) + +# Source include directories and library dependencies. Add any plugin-specific +# dependencies here. +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) + +# List of absolute paths to libraries that should be bundled with the plugin. +# This list could contain prebuilt libraries, or libraries created by an +# external build triggered from this build file. +set(bluetooth_low_energy_bundled_libraries + "" + PARENT_SCOPE +) + +# === Tests === +# These unit tests can be run from a terminal after building the example, or +# from Visual Studio after opening the generated solution file. + +# Only enable test builds when building the example (which sets this variable) +# so that plugin clients aren't building the tests. +if (${include_${PROJECT_NAME}_tests}) +set(TEST_RUNNER "${PROJECT_NAME}_test") +enable_testing() + +# Add the Google Test dependency. +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/release-1.11.0.zip +) +# Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +# Disable install commands for gtest so it doesn't end up in the bundle. +set(INSTALL_GTEST OFF CACHE BOOL "Disable installation of googletest" FORCE) +FetchContent_MakeAvailable(googletest) + +# The plugin's C API is not very useful for unit testing, so build the sources +# directly into the test binary rather than using the DLL. +add_executable(${TEST_RUNNER} + test/bluetooth_low_energy_plugin_test.cpp + ${PLUGIN_SOURCES} +) +apply_standard_settings(${TEST_RUNNER}) +target_include_directories(${TEST_RUNNER} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") +target_link_libraries(${TEST_RUNNER} PRIVATE flutter_wrapper_plugin) +target_link_libraries(${TEST_RUNNER} PRIVATE gtest_main gmock) +# flutter_wrapper_plugin has link dependencies on the Flutter DLL. +add_custom_command(TARGET ${TEST_RUNNER} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${FLUTTER_LIBRARY}" $ +) + +# Enable automatic test discovery. +include(GoogleTest) +gtest_discover_tests(${TEST_RUNNER}) +endif() diff --git a/bluetooth_low_energy/windows/bluetooth_low_energy_plugin.cpp b/bluetooth_low_energy/windows/bluetooth_low_energy_plugin.cpp new file mode 100644 index 0000000..230438b --- /dev/null +++ b/bluetooth_low_energy/windows/bluetooth_low_energy_plugin.cpp @@ -0,0 +1,59 @@ +#include "bluetooth_low_energy_plugin.h" + +// This must be included before many other Windows headers. +#include + +// For getPlatformVersion; remove unless needed for your plugin implementation. +#include + +#include +#include +#include + +#include +#include + +namespace bluetooth_low_energy { + +// static +void BluetoothLowEnergyPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarWindows *registrar) { + auto channel = + std::make_unique>( + registrar->messenger(), "bluetooth_low_energy", + &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(); + + channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + + registrar->AddPlugin(std::move(plugin)); +} + +BluetoothLowEnergyPlugin::BluetoothLowEnergyPlugin() {} + +BluetoothLowEnergyPlugin::~BluetoothLowEnergyPlugin() {} + +void BluetoothLowEnergyPlugin::HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result) { + if (method_call.method_name().compare("getPlatformVersion") == 0) { + std::ostringstream version_stream; + version_stream << "Windows "; + if (IsWindows10OrGreater()) { + version_stream << "10+"; + } else if (IsWindows8OrGreater()) { + version_stream << "8"; + } else if (IsWindows7OrGreater()) { + version_stream << "7"; + } + result->Success(flutter::EncodableValue(version_stream.str())); + } else { + result->NotImplemented(); + } +} + +} // namespace bluetooth_low_energy diff --git a/bluetooth_low_energy/windows/bluetooth_low_energy_plugin.h b/bluetooth_low_energy/windows/bluetooth_low_energy_plugin.h new file mode 100644 index 0000000..e12faa6 --- /dev/null +++ b/bluetooth_low_energy/windows/bluetooth_low_energy_plugin.h @@ -0,0 +1,31 @@ +#ifndef FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_H_ +#define FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_H_ + +#include +#include + +#include + +namespace bluetooth_low_energy { + +class BluetoothLowEnergyPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar); + + BluetoothLowEnergyPlugin(); + + virtual ~BluetoothLowEnergyPlugin(); + + // Disallow copy and assign. + BluetoothLowEnergyPlugin(const BluetoothLowEnergyPlugin&) = delete; + BluetoothLowEnergyPlugin& operator=(const BluetoothLowEnergyPlugin&) = delete; + + // Called when a method is called on this plugin's channel from Dart. + void HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result); +}; + +} // namespace bluetooth_low_energy + +#endif // FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_H_ diff --git a/bluetooth_low_energy/windows/bluetooth_low_energy_plugin_c_api.cpp b/bluetooth_low_energy/windows/bluetooth_low_energy_plugin_c_api.cpp new file mode 100644 index 0000000..ef486c1 --- /dev/null +++ b/bluetooth_low_energy/windows/bluetooth_low_energy_plugin_c_api.cpp @@ -0,0 +1,12 @@ +#include "include/bluetooth_low_energy/bluetooth_low_energy_plugin_c_api.h" + +#include + +#include "bluetooth_low_energy_plugin.h" + +void BluetoothLowEnergyPluginCApiRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + bluetooth_low_energy::BluetoothLowEnergyPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +} diff --git a/bluetooth_low_energy/windows/include/bluetooth_low_energy/bluetooth_low_energy_plugin_c_api.h b/bluetooth_low_energy/windows/include/bluetooth_low_energy/bluetooth_low_energy_plugin_c_api.h new file mode 100644 index 0000000..a85ebae --- /dev/null +++ b/bluetooth_low_energy/windows/include/bluetooth_low_energy/bluetooth_low_energy_plugin_c_api.h @@ -0,0 +1,23 @@ +#ifndef FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_C_API_H_ +#define FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_C_API_H_ + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) +#else +#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void BluetoothLowEnergyPluginCApiRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_PLUGIN_C_API_H_ diff --git a/bluetooth_low_energy/windows/test/bluetooth_low_energy_plugin_test.cpp b/bluetooth_low_energy/windows/test/bluetooth_low_energy_plugin_test.cpp new file mode 100644 index 0000000..72c8764 --- /dev/null +++ b/bluetooth_low_energy/windows/test/bluetooth_low_energy_plugin_test.cpp @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "bluetooth_low_energy_plugin.h" + +namespace bluetooth_low_energy { +namespace test { + +namespace { + +using flutter::EncodableMap; +using flutter::EncodableValue; +using flutter::MethodCall; +using flutter::MethodResultFunctions; + +} // namespace + +TEST(BluetoothLowEnergyPlugin, GetPlatformVersion) { + BluetoothLowEnergyPlugin plugin; + // Save the reply value from the success callback. + std::string result_string; + plugin.HandleMethodCall( + MethodCall("getPlatformVersion", std::make_unique()), + std::make_unique>( + [&result_string](const EncodableValue* result) { + result_string = std::get(*result); + }, + nullptr, nullptr)); + + // Since the exact string varies by host, just ensure that it's a string + // with the expected format. + EXPECT_TRUE(result_string.rfind("Windows ", 0) == 0); +} + +} // namespace test +} // namespace bluetooth_low_energy diff --git a/bluetooth_low_energy_android/.gitignore b/bluetooth_low_energy_android/.gitignore new file mode 100644 index 0000000..96486fd --- /dev/null +++ b/bluetooth_low_energy_android/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/.metadata b/bluetooth_low_energy_android/.metadata similarity index 58% rename from .metadata rename to bluetooth_low_energy_android/.metadata index 8472cba..b0ed2b5 100644 --- a/.metadata +++ b/bluetooth_low_energy_android/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled. version: - revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf channel: stable project_type: plugin @@ -13,14 +13,11 @@ project_type: plugin migration: platforms: - platform: root - create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - platform: android - create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - - platform: ios - create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf # User provided section diff --git a/bluetooth_low_energy_android/CHANGELOG.md b/bluetooth_low_energy_android/CHANGELOG.md new file mode 100644 index 0000000..e510273 --- /dev/null +++ b/bluetooth_low_energy_android/CHANGELOG.md @@ -0,0 +1,4 @@ +## 2.0.0 + +- Rewrite the whole project with federated plugins. +- Support macOS and Linux. diff --git a/bluetooth_low_energy_android/LICENSE b/bluetooth_low_energy_android/LICENSE new file mode 100644 index 0000000..515ed4b --- /dev/null +++ b/bluetooth_low_energy_android/LICENSE @@ -0,0 +1,21 @@ +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. \ No newline at end of file diff --git a/bluetooth_low_energy_android/README.md b/bluetooth_low_energy_android/README.md new file mode 100644 index 0000000..feecc7c --- /dev/null +++ b/bluetooth_low_energy_android/README.md @@ -0,0 +1,15 @@ +# bluetooth_low_energy_android + +The Android implementation of [`bluetooth_low_energy`][1]. + +## Usage + +This package is [endorsed][2], which means you can simply use `bluetooth_low_energy` +normally. This package will be automatically included in your app when you do, +so you do not need to add it to your `pubspec.yaml`. + +However, if you `import` this package to use any of its APIs directly, you +should add it to your `pubspec.yaml` as usual. + +[1]: https://pub.dev/packages/bluetooth_low_energy +[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin \ No newline at end of file diff --git a/bluetooth_low_energy_android/analysis_options.yaml b/bluetooth_low_energy_android/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/bluetooth_low_energy_android/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/bluetooth_low_energy_android/android/.gitignore similarity index 100% rename from android/.gitignore rename to bluetooth_low_energy_android/android/.gitignore diff --git a/android/build.gradle b/bluetooth_low_energy_android/android/build.gradle similarity index 55% rename from android/build.gradle rename to bluetooth_low_energy_android/android/build.gradle index d8c2d5d..597dd27 100644 --- a/android/build.gradle +++ b/bluetooth_low_energy_android/android/build.gradle @@ -2,19 +2,19 @@ group 'dev.yanshouwang.bluetooth_low_energy' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.1.2' + classpath 'com.android.tools.build:gradle:7.3.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } -rootProject.allprojects { +allprojects { repositories { google() mavenCentral() @@ -38,15 +38,27 @@ android { sourceSets { main.java.srcDirs += 'src/main/kotlin' + test.java.srcDirs += 'src/test/kotlin' } defaultConfig { minSdkVersion 21 } -} -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.google.protobuf:protobuf-kotlin:3.19.4' - implementation 'com.google.guava:guava:31.1-android' + dependencies { + testImplementation 'org.jetbrains.kotlin:kotlin-test' + testImplementation 'org.mockito:mockito-core:5.0.0' + } + + testOptions { + unitTests.all { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + outputs.upToDateWhen {false} + showStandardStreams = true + } + } + } } diff --git a/android/settings.gradle b/bluetooth_low_energy_android/android/settings.gradle similarity index 100% rename from android/settings.gradle rename to bluetooth_low_energy_android/android/settings.gradle diff --git a/android/src/main/AndroidManifest.xml b/bluetooth_low_energy_android/android/src/main/AndroidManifest.xml similarity index 68% rename from android/src/main/AndroidManifest.xml rename to bluetooth_low_energy_android/android/src/main/AndroidManifest.xml index bc2c782..e469528 100644 --- a/android/src/main/AndroidManifest.xml +++ b/bluetooth_low_energy_android/android/src/main/AndroidManifest.xml @@ -1,13 +1,13 @@ - - + + + android:maxSdkVersion="30" /> + android:maxSdkVersion="30" /> - - + + diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyAndroid.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyAndroid.kt new file mode 100644 index 0000000..caeacc9 --- /dev/null +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyAndroid.kt @@ -0,0 +1,38 @@ +package dev.yanshouwang.bluetooth_low_energy + +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding + +/** BluetoothLowEnergyAndroid */ +class BluetoothLowEnergyAndroid : FlutterPlugin, ActivityAware { + private lateinit var centralController: MyCentralController + + override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { + val context = binding.applicationContext + val binaryMessenger = binding.binaryMessenger + centralController = MyCentralController(context, binaryMessenger) + MyCentralControllerHostApi.setUp(binaryMessenger, centralController) + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + val binaryMessenger = binding.binaryMessenger + MyCentralControllerHostApi.setUp(binaryMessenger, null) + } + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + centralController.onAttachedToActivity(binding) + } + + override fun onDetachedFromActivityForConfigChanges() { + centralController.onDetachedFromActivity() + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + centralController.onAttachedToActivity(binding) + } + + override fun onDetachedFromActivity() { + centralController.onDetachedFromActivity() + } +} diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyApi.g.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyApi.g.kt new file mode 100644 index 0000000..b2d1ebd --- /dev/null +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyApi.g.kt @@ -0,0 +1,653 @@ +// Autogenerated from Pigeon (v10.1.6), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +package dev.yanshouwang.bluetooth_low_energy + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer + +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + if (exception is FlutterError) { + return listOf( + exception.code, + exception.message, + exception.details + ) + } else { + return listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) + } +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class FlutterError ( + val code: String, + override val message: String? = null, + val details: Any? = null +) : Throwable() + +enum class MyCentralStateArgs(val raw: Int) { + UNKNOWN(0), + UNSUPPORTED(1), + UNAUTHORIZED(2), + POWEREDOFF(3), + POWEREDON(4); + + companion object { + fun ofRaw(raw: Int): MyCentralStateArgs? { + return values().firstOrNull { it.raw == raw } + } + } +} + +enum class MyGattCharacteristicPropertyArgs(val raw: Int) { + READ(0), + WRITE(1), + WRITEWITHOUTRESPONSE(2), + NOTIFY(3), + INDICATE(4); + + companion object { + fun ofRaw(raw: Int): MyGattCharacteristicPropertyArgs? { + return values().firstOrNull { it.raw == raw } + } + } +} + +enum class MyGattCharacteristicWriteTypeArgs(val raw: Int) { + WITHRESPONSE(0), + WITHOUTRESPONSE(1); + + companion object { + fun ofRaw(raw: Int): MyGattCharacteristicWriteTypeArgs? { + return values().firstOrNull { it.raw == raw } + } + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class MyCentralControllerArgs ( + val myStateNumber: Long + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): MyCentralControllerArgs { + val myStateNumber = list[0].let { if (it is Int) it.toLong() else it as Long } + return MyCentralControllerArgs(myStateNumber) + } + } + fun toList(): List { + return listOf( + myStateNumber, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class MyPeripheralArgs ( + val key: Long, + val uuid: String + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): MyPeripheralArgs { + val key = list[0].let { if (it is Int) it.toLong() else it as Long } + val uuid = list[1] as String + return MyPeripheralArgs(key, uuid) + } + } + fun toList(): List { + return listOf( + key, + uuid, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class MyAdvertisementArgs ( + val name: String? = null, + val manufacturerSpecificData: Map, + val serviceUUIDs: List, + val serviceData: Map + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): MyAdvertisementArgs { + val name = list[0] as String? + val manufacturerSpecificData = list[1] as Map + val serviceUUIDs = list[2] as List + val serviceData = list[3] as Map + return MyAdvertisementArgs(name, manufacturerSpecificData, serviceUUIDs, serviceData) + } + } + fun toList(): List { + return listOf( + name, + manufacturerSpecificData, + serviceUUIDs, + serviceData, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class MyGattServiceArgs ( + val key: Long, + val uuid: String + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): MyGattServiceArgs { + val key = list[0].let { if (it is Int) it.toLong() else it as Long } + val uuid = list[1] as String + return MyGattServiceArgs(key, uuid) + } + } + fun toList(): List { + return listOf( + key, + uuid, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class MyGattCharacteristicArgs ( + val key: Long, + val uuid: String, + val myPropertyNumbers: List + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): MyGattCharacteristicArgs { + val key = list[0].let { if (it is Int) it.toLong() else it as Long } + val uuid = list[1] as String + val myPropertyNumbers = list[2] as List + return MyGattCharacteristicArgs(key, uuid, myPropertyNumbers) + } + } + fun toList(): List { + return listOf( + key, + uuid, + myPropertyNumbers, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class MyGattDescriptorArgs ( + val key: Long, + val uuid: String + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): MyGattDescriptorArgs { + val key = list[0].let { if (it is Int) it.toLong() else it as Long } + val uuid = list[1] as String + return MyGattDescriptorArgs(key, uuid) + } + } + fun toList(): List { + return listOf( + key, + uuid, + ) + } +} + +@Suppress("UNCHECKED_CAST") +private object MyCentralControllerHostApiCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 128.toByte() -> { + return (readValue(buffer) as? List)?.let { + MyCentralControllerArgs.fromList(it) + } + } + 129.toByte() -> { + return (readValue(buffer) as? List)?.let { + MyGattCharacteristicArgs.fromList(it) + } + } + 130.toByte() -> { + return (readValue(buffer) as? List)?.let { + MyGattDescriptorArgs.fromList(it) + } + } + 131.toByte() -> { + return (readValue(buffer) as? List)?.let { + MyGattServiceArgs.fromList(it) + } + } + else -> super.readValueOfType(type, buffer) + } + } + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + when (value) { + is MyCentralControllerArgs -> { + stream.write(128) + writeValue(stream, value.toList()) + } + is MyGattCharacteristicArgs -> { + stream.write(129) + writeValue(stream, value.toList()) + } + is MyGattDescriptorArgs -> { + stream.write(130) + writeValue(stream, value.toList()) + } + is MyGattServiceArgs -> { + stream.write(131) + writeValue(stream, value.toList()) + } + else -> super.writeValue(stream, value) + } + } +} + +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface MyCentralControllerHostApi { + fun setUp(callback: (Result) -> Unit) + fun tearDown() + fun startDiscovery(callback: (Result) -> Unit) + fun stopDiscovery() + fun connect(myPeripheralKey: Long, callback: (Result) -> Unit) + fun disconnect(myPeripheralKey: Long, callback: (Result) -> Unit) + fun discoverGATT(myPeripheralKey: Long, callback: (Result) -> Unit) + fun getServices(myPeripheralKey: Long): List + fun getCharacteristics(myServiceKey: Long): List + fun getDescriptors(myCharacteristicKey: Long): List + fun readCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, callback: (Result) -> Unit) + fun writeCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, value: ByteArray, myTypeNumber: Long, callback: (Result) -> Unit) + fun notifyCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, state: Boolean, callback: (Result) -> Unit) + fun readDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, callback: (Result) -> Unit) + fun writeDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, value: ByteArray, callback: (Result) -> Unit) + + companion object { + /** The codec used by MyCentralControllerHostApi. */ + val codec: MessageCodec by lazy { + MyCentralControllerHostApiCodec + } + /** Sets up an instance of `MyCentralControllerHostApi` to handle messages through the `binaryMessenger`. */ + @Suppress("UNCHECKED_CAST") + fun setUp(binaryMessenger: BinaryMessenger, api: MyCentralControllerHostApi?) { + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.setUp", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.setUp() { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.tearDown", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + var wrapped: List + try { + api.tearDown() + wrapped = listOf(null) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.startDiscovery", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.startDiscovery() { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.stopDiscovery", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + var wrapped: List + try { + api.stopDiscovery() + wrapped = listOf(null) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.connect", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + api.connect(myPeripheralKeyArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.disconnect", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + api.disconnect(myPeripheralKeyArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.discoverGATT", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + api.discoverGATT(myPeripheralKeyArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getServices", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + var wrapped: List + try { + wrapped = listOf(api.getServices(myPeripheralKeyArg)) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getCharacteristics", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myServiceKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + var wrapped: List + try { + wrapped = listOf(api.getCharacteristics(myServiceKeyArg)) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getDescriptors", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myCharacteristicKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + var wrapped: List + try { + wrapped = listOf(api.getDescriptors(myCharacteristicKeyArg)) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.readCharacteristic", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.readCharacteristic(myPeripheralKeyArg, myCharacteristicKeyArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.writeCharacteristic", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long } + val valueArg = args[2] as ByteArray + val myTypeNumberArg = args[3].let { if (it is Int) it.toLong() else it as Long } + api.writeCharacteristic(myPeripheralKeyArg, myCharacteristicKeyArg, valueArg, myTypeNumberArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.notifyCharacteristic", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long } + val stateArg = args[2] as Boolean + api.notifyCharacteristic(myPeripheralKeyArg, myCharacteristicKeyArg, stateArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.readDescriptor", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + val myDescriptorKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.readDescriptor(myPeripheralKeyArg, myDescriptorKeyArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.writeDescriptor", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + val myDescriptorKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long } + val valueArg = args[2] as ByteArray + api.writeDescriptor(myPeripheralKeyArg, myDescriptorKeyArg, valueArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} +@Suppress("UNCHECKED_CAST") +private object MyCentralControllerFlutterApiCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 128.toByte() -> { + return (readValue(buffer) as? List)?.let { + MyAdvertisementArgs.fromList(it) + } + } + 129.toByte() -> { + return (readValue(buffer) as? List)?.let { + MyPeripheralArgs.fromList(it) + } + } + else -> super.readValueOfType(type, buffer) + } + } + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + when (value) { + is MyAdvertisementArgs -> { + stream.write(128) + writeValue(stream, value.toList()) + } + is MyPeripheralArgs -> { + stream.write(129) + writeValue(stream, value.toList()) + } + else -> super.writeValue(stream, value) + } + } +} + +/** Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. */ +@Suppress("UNCHECKED_CAST") +class MyCentralControllerFlutterApi(private val binaryMessenger: BinaryMessenger) { + companion object { + /** The codec used by MyCentralControllerFlutterApi. */ + val codec: MessageCodec by lazy { + MyCentralControllerFlutterApiCodec + } + } + fun onStateChanged(myStateNumberArg: Long, callback: () -> Unit) { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onStateChanged", codec) + channel.send(listOf(myStateNumberArg)) { + callback() + } + } + fun onDiscovered(myPeripheralArgsArg: MyPeripheralArgs, rssiArg: Long, myAdvertisementArgsArg: MyAdvertisementArgs, callback: () -> Unit) { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onDiscovered", codec) + channel.send(listOf(myPeripheralArgsArg, rssiArg, myAdvertisementArgsArg)) { + callback() + } + } + fun onPeripheralStateChanged(myPeripheralKeyArg: Long, stateArg: Boolean, callback: () -> Unit) { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onPeripheralStateChanged", codec) + channel.send(listOf(myPeripheralKeyArg, stateArg)) { + callback() + } + } + fun onCharacteristicValueChanged(myCharacteristicKeyArg: Long, valueArg: ByteArray, callback: () -> Unit) { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onCharacteristicValueChanged", codec) + channel.send(listOf(myCharacteristicKeyArg, valueArg)) { + callback() + } + } +} diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt new file mode 100644 index 0000000..a416fb2 --- /dev/null +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBluetoothGattCallback.kt @@ -0,0 +1,57 @@ +package dev.yanshouwang.bluetooth_low_energy + +import android.bluetooth.BluetoothGatt +import android.bluetooth.BluetoothGattCallback +import android.bluetooth.BluetoothGattCharacteristic +import android.bluetooth.BluetoothGattDescriptor +import java.util.concurrent.Executor + +class MyBluetoothGattCallback(private val myCentralController: MyCentralController, private val executor: Executor) : BluetoothGattCallback() { + override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { + super.onConnectionStateChange(gatt, status, newState) + executor.execute { + myCentralController.onConnectionStateChange(gatt, status, newState) + } + } + + override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { + super.onServicesDiscovered(gatt, status) + executor.execute { + myCentralController.onServicesDiscovered(gatt, status) + } + } + + override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) { + super.onCharacteristicRead(gatt, characteristic, status) + executor.execute { + myCentralController.onCharacteristicRead(characteristic, status) + } + } + + override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) { + super.onCharacteristicWrite(gatt, characteristic, status) + executor.execute { + myCentralController.onCharacteristicWrite(characteristic, status) + } + } + + override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) { + executor.execute { + myCentralController.onCharacteristicChanged(characteristic) + } + } + + override fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) { + super.onDescriptorRead(gatt, descriptor, status) + executor.execute { + myCentralController.onDescriptorRead(descriptor, status) + } + } + + override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) { + super.onDescriptorWrite(gatt, descriptor, status) + executor.execute { + myCentralController.onDescriptorWrite(descriptor, status) + } + } +} \ No newline at end of file diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt new file mode 100644 index 0000000..c2ddded --- /dev/null +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyBroadcastReceiver.kt @@ -0,0 +1,11 @@ +package dev.yanshouwang.bluetooth_low_energy + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class MyBroadcastReceiver(private val myCentralController: MyCentralController) : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + myCentralController.onReceive(intent) + } +} diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralController.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralController.kt new file mode 100644 index 0000000..3dc32e7 --- /dev/null +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyCentralController.kt @@ -0,0 +1,685 @@ +package dev.yanshouwang.bluetooth_low_energy + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothGatt +import android.bluetooth.BluetoothGattCharacteristic +import android.bluetooth.BluetoothGattDescriptor +import android.bluetooth.BluetoothGattService +import android.bluetooth.BluetoothManager +import android.bluetooth.BluetoothProfile +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanResult +import android.bluetooth.le.ScanSettings +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.pm.PackageManager +import android.os.Build +import android.util.SparseArray +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.BinaryMessenger +import java.util.UUID + +class MyCentralController(private val context: Context, binaryMessenger: BinaryMessenger) : MyCentralControllerHostApi { + companion object { + // const val DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xff.toByte() + private const val REQUEST_CODE = 443 +// private val UUID_HEART_RATE_MEASUREMENT = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb") + private val UUID_CLIENT_CHARACTERISTIC_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") + } + + private lateinit var binding: ActivityPluginBinding + + private val manager = ContextCompat.getSystemService(context, BluetoothManager::class.java) as BluetoothManager + private val adapter = manager.adapter + private val scanner = adapter.bluetoothLeScanner + private val executor = ContextCompat.getMainExecutor(context) + + private val myApi = MyCentralControllerFlutterApi(binaryMessenger) + private val myRequestPermissionResultListener = MyRequestPermissionResultListener(this) + private val myReceiver = MyBroadcastReceiver(this) + private val myScanCallback = MyScanCallback(this) + private val myGattCallback = MyBluetoothGattCallback(this, executor) + + private val devices = mutableMapOf() + private val gatts = mutableMapOf() + private val services = mutableMapOf() + private val characteristics = mutableMapOf() + private val descriptors = mutableMapOf() + + private var registered = false + private var discovering = false + + private var setUpCallback: ((Result) -> Unit)? = null + private var startDiscoveryCallback: ((Result) -> Unit)? = null + private val connectCallbacks = mutableMapOf) -> Unit>() + private val disconnectCallbacks = mutableMapOf) -> Unit>() + private val discoverGattCallbacks = mutableMapOf) -> Unit>() + private val readCharacteristicCallbacks = mutableMapOf) -> Unit>() + private val writeCharacteristicCallbacks = mutableMapOf) -> Unit>() + private val readDescriptorCallbacks = mutableMapOf) -> Unit>() + private val writeDescriptorCallbacks = mutableMapOf) -> Unit>() + + override fun setUp(callback: (Result) -> Unit) { + try { + val available = context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) + if (!available) { + val stateNumber = MyCentralStateArgs.UNSUPPORTED.raw.toLong() + val args = MyCentralControllerArgs(stateNumber) + callback(Result.success(args)) + } + val unfinishedCallback = setUpCallback + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_CONNECT) + } else { + arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION) + } + val activity = binding.activity + ActivityCompat.requestPermissions(activity, permissions, REQUEST_CODE) + setUpCallback = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun tearDown() { + if (registered) { + unregister() + } + if (discovering) { + stopDiscovery() + } + for (gatt in gatts.values) { + gatt.disconnect() + } + devices.clear() + gatts.clear() + services.clear() + characteristics.clear() + descriptors.clear() + } + + private fun register() { + val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) + context.registerReceiver(myReceiver, filter) + registered = true + } + + private fun unregister() { + context.unregisterReceiver(myReceiver) + registered = false + } + + override fun startDiscovery(callback: (Result) -> Unit) { + try { + val unfinishedCallback = startDiscoveryCallback + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val filters = emptyList() + val settings = ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build() + scanner.startScan(filters, settings, myScanCallback) + executor.execute { + val finishedCallback = startDiscoveryCallback ?: return@execute + startDiscoveryCallback = null + finishedCallback(Result.success(Unit)) + } + startDiscoveryCallback = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun stopDiscovery() { + scanner.stopScan(myScanCallback) + discovering = false + } + + override fun connect(myPeripheralKey: Long, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val unfinishedCallback = connectCallbacks[deviceKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val device = devices[deviceKey] as BluetoothDevice + val autoConnect = false + gatts[deviceKey] = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + val transport = BluetoothDevice.TRANSPORT_LE + device.connectGatt(context, autoConnect, myGattCallback, transport) + } else { + device.connectGatt(context, autoConnect, myGattCallback) + } + connectCallbacks[deviceKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun disconnect(myPeripheralKey: Long, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val unfinishedCallback = disconnectCallbacks[deviceKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val gatt = gatts[deviceKey] as BluetoothGatt + gatt.disconnect() + disconnectCallbacks[deviceKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun discoverGATT(myPeripheralKey: Long, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val unfinishedCallback = discoverGattCallbacks[deviceKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val gatt = gatts[deviceKey] as BluetoothGatt + val discovering = gatt.discoverServices() + if (!discovering) { + throw IllegalStateException() + } + discoverGattCallbacks[deviceKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun getServices(myPeripheralKey: Long): List { + val deviceKey = myPeripheralKey.toInt() + val gatt = gatts[deviceKey] as BluetoothGatt + val services = gatt.services + return services.map { service -> + val serviceKey = service.hashCode() + if (this.services[serviceKey] == null) { + this.services[serviceKey] = service + } + return@map service.toMyArgs() + } + } + + override fun getCharacteristics(myServiceKey: Long): List { + val serviceKey = myServiceKey.toInt() + val service = services[serviceKey] as BluetoothGattService + val characteristics = service.characteristics + return characteristics.map { characteristic -> + val characteristicKey = characteristic.hashCode() + if (this.characteristics[characteristicKey] == null) { + this.characteristics[characteristicKey] = characteristic + } + return@map characteristic.toMyArgs() + } + } + + override fun getDescriptors(myCharacteristicKey: Long): List { + val characteristicKey = myCharacteristicKey.toInt() + val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic + val descriptors = characteristic.descriptors + return descriptors.map { descriptor -> + val descriptorKey = descriptor.hashCode() + if (this.descriptors[descriptorKey] == null) { + this.descriptors[descriptorKey] = descriptor + } + return@map descriptor.toMyArgs() + } + } + + override fun readCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val characteristicKey = myCharacteristicKey.toInt() + val unfinishedCallback = readCharacteristicCallbacks[characteristicKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val gatt = gatts[deviceKey] as BluetoothGatt + val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic + val reading = gatt.readCharacteristic(characteristic) + if (!reading) { + throw IllegalStateException() + } + readCharacteristicCallbacks[characteristicKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun writeCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, value: ByteArray, myTypeNumber: Long, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val characteristicKey = myCharacteristicKey.toInt() + val unfinishedCallback = writeCharacteristicCallbacks[characteristicKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val gatt = gatts[deviceKey] as BluetoothGatt + val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic + val myTypeArgs = myTypeNumber.toMyGattCharacteristicTypeArgs() + val writeType = myTypeArgs.toType() + characteristic.value = value + characteristic.writeType = writeType + val writing = gatt.writeCharacteristic(characteristic) + if (!writing) { + throw IllegalStateException() + } + writeCharacteristicCallbacks[characteristicKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun notifyCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, state: Boolean, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val characteristicKey = myCharacteristicKey.toInt() + val gatt = gatts[deviceKey] as BluetoothGatt + val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic + val notifying = gatt.setCharacteristicNotification(characteristic, state) + if (!notifying) { + throw IllegalStateException() + } + // TODO: Seems the docs is not correct, this operation is necessary for all characteristics. + // https://developer.android.com/guide/topics/connectivity/bluetooth/transfer-ble-data#notification + // This is specific to Heart Rate Measurement. +// if (characteristic.uuid == UUID_HEART_RATE_MEASUREMENT) { + val descriptor = characteristic.getDescriptor(UUID_CLIENT_CHARACTERISTIC_CONFIG) + val descriptorKey = descriptor.hashCode() + val unfinishedCallback = writeDescriptorCallbacks[descriptorKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val value = if (state) BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE + else BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE + descriptor.value = value + val writing = gatt.writeDescriptor(descriptor) + if (!writing) { + throw IllegalStateException() + } + writeDescriptorCallbacks[descriptorKey] = callback +// } else { +// callback(Result.success(Unit)) +// } + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun readDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val descriptorKey = myDescriptorKey.toInt() + val unfinishedCallback = readDescriptorCallbacks[descriptorKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val gatt = gatts[deviceKey] as BluetoothGatt + val descriptor = descriptors[descriptorKey] as BluetoothGattDescriptor + val reading = gatt.readDescriptor(descriptor) + if (!reading) { + throw IllegalStateException() + } + readDescriptorCallbacks[descriptorKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + override fun writeDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, value: ByteArray, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val descriptorKey = myDescriptorKey.toInt() + val unfinishedCallback = writeDescriptorCallbacks[descriptorKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val gatt = gatts[deviceKey] as BluetoothGatt + val descriptor = descriptors[descriptorKey] as BluetoothGattDescriptor + descriptor.value = value + val writing = gatt.writeDescriptor(descriptor) + if (!writing) { + throw IllegalStateException() + } + writeDescriptorCallbacks[descriptorKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + + fun onAttachedToActivity(binding: ActivityPluginBinding) { + binding.addRequestPermissionsResultListener(myRequestPermissionResultListener) + this.binding = binding + } + + fun onDetachedFromActivity() { + binding.removeRequestPermissionsResultListener(myRequestPermissionResultListener) + } + + fun onRequestPermissionsResult(requestCode: Int, results: IntArray): Boolean { + if (requestCode != REQUEST_CODE) { + return false + } + val callback = setUpCallback ?: return false + val isGranted = results.all { r -> r == PackageManager.PERMISSION_GRANTED } + if (isGranted) { + register() + } + val myStateArgs = if (isGranted) adapter.myStateArgs + else MyCentralStateArgs.UNAUTHORIZED + val myStateNumber = myStateArgs.raw.toLong() + val myArgs = MyCentralControllerArgs(myStateNumber) + callback(Result.success(myArgs)) + return true + } + + fun onReceive(intent: Intent) { + val action = intent.action + if (action != BluetoothAdapter.ACTION_STATE_CHANGED) { + return + } +// val previousState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.STATE_OFF) + val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF) +// val myPreviousStateArgs = previousState.toMyCentralStateArgs() + val myStateArgs = state.toMyCentralStateArgs() +// if (myStateArgs == myPreviousStateArgs) { +// return +// } + val myStateNumber = myStateArgs.raw.toLong() + myApi.onStateChanged(myStateNumber) {} + } + + fun onScanFailed(errorCode: Int) { + val callback = startDiscoveryCallback ?: return + startDiscoveryCallback = null + val error = IllegalStateException("Start discovery failed with error code: $errorCode") + callback(Result.failure(error)) + } + + fun onScanResult(result: ScanResult) { + val device = result.device + val deviceKey = device.hashCode() + if (devices[deviceKey] == null) { + devices[deviceKey] = device + } + val myPeripheralArgs = device.toMyArgs() + val rssi = result.rssi.toLong() + val myAdvertisementArgs = result.myAdvertisementArgs + myApi.onDiscovered(myPeripheralArgs, rssi, myAdvertisementArgs) {} + } + + fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { + val device = gatt.device + val deviceKey = device.hashCode() + val myPeripheralKey = deviceKey.toLong() + if (newState != BluetoothProfile.STATE_CONNECTED) { + gatt.close() + gatts.remove(deviceKey) + val error = IllegalStateException("GATT is disconnected with status: $status") + val discoverGattCallback = discoverGattCallbacks.remove(deviceKey) + if (discoverGattCallback != null) { + discoverGattCallback(Result.failure(error)) + } + for (service in gatt.services) { + for (characteristic in service.characteristics) { + val characteristicKey = characteristic.hashCode() + val readCharacteristicCallback = readCharacteristicCallbacks.remove(characteristicKey) + val writeCharacteristicCallback = writeCharacteristicCallbacks.remove(characteristicKey) + if (readCharacteristicCallback != null) { + readCharacteristicCallback(Result.failure(error)) + } + if (writeCharacteristicCallback != null) { + writeCharacteristicCallback(Result.failure(error)) + } + for (descriptor in characteristic.descriptors) { + val descriptorKey = descriptor.hashCode() + val readDescriptorCallback = readDescriptorCallbacks.remove(descriptorKey) + val writeDescriptorCallback = writeDescriptorCallbacks.remove(descriptorKey) + if (readDescriptorCallback != null) { + readDescriptorCallback(Result.failure(error)) + } + if (writeDescriptorCallback != null) { + writeDescriptorCallback(Result.failure(error)) + } + } + } + } + } + val connectCallback = connectCallbacks.remove(deviceKey) + val disconnectCallback = disconnectCallbacks.remove(deviceKey) + if (connectCallback == null && disconnectCallback == null) { + // State changed. + val state = newState == BluetoothProfile.STATE_CONNECTED + myApi.onPeripheralStateChanged(myPeripheralKey, state) {} + } else { + if (connectCallback != null) { + if (status == BluetoothGatt.GATT_SUCCESS) { + // Connect succeed. + connectCallback(Result.success(Unit)) + myApi.onPeripheralStateChanged(myPeripheralKey, true) {} + } else { + // Connect failed. + val error = IllegalStateException("Connect failed with status: $status") + connectCallback(Result.failure(error)) + } + } + if (disconnectCallback != null) { + if (status == BluetoothGatt.GATT_SUCCESS) { + // Disconnect succeed. + disconnectCallback(Result.success(Unit)) + myApi.onPeripheralStateChanged(myPeripheralKey, false) {} + } else { + // Disconnect failed. + val error = IllegalStateException("Connect failed with status: $status") + disconnectCallback(Result.failure(error)) + } + } + } + } + + fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { + val device = gatt.device + val deviceKey = device.hashCode() + val callback = discoverGattCallbacks.remove(deviceKey) ?: return + if (status == BluetoothGatt.GATT_SUCCESS) { + callback(Result.success(Unit)) + } else { + val error = IllegalStateException("Discover GATT failed with status: $status") + callback(Result.failure(error)) + } + } + + fun onCharacteristicRead(characteristic: BluetoothGattCharacteristic, status: Int) { + val characteristicKey = characteristic.hashCode() + val callback = readCharacteristicCallbacks.remove(characteristicKey) ?: return + if (status == BluetoothGatt.GATT_SUCCESS) { + val value = characteristic.value + callback(Result.success(value)) + } else { + val error = IllegalStateException("Read characteristic failed with status: $status.") + callback(Result.failure(error)) + } + } + + fun onCharacteristicWrite(characteristic: BluetoothGattCharacteristic, status: Int) { + val characteristicKey = characteristic.hashCode() + val callback = writeCharacteristicCallbacks.remove(characteristicKey) ?: return + if (status == BluetoothGatt.GATT_SUCCESS) { + callback(Result.success(Unit)) + } else { + val error = IllegalStateException("Write characteristic failed with status: $status.") + callback(Result.failure(error)) + } + } + + fun onCharacteristicChanged(characteristic: BluetoothGattCharacteristic) { + val characteristicKey = characteristic.hashCode() + val myCharacteristicKey = characteristicKey.toLong() + val value = characteristic.value + myApi.onCharacteristicValueChanged(myCharacteristicKey, value) {} + } + + fun onDescriptorRead(descriptor: BluetoothGattDescriptor, status: Int) { + val descriptorKey = descriptor.hashCode() + val callback = readDescriptorCallbacks.remove(descriptorKey) ?: return + if (status == BluetoothGatt.GATT_SUCCESS) { + val value = descriptor.value + callback(Result.success(value)) + } else { + val error = IllegalStateException("Read descriptor failed with status: $status.") + callback(Result.failure(error)) + } + } + + fun onDescriptorWrite(descriptor: BluetoothGattDescriptor, status: Int) { + val descriptorKey = descriptor.hashCode() + val callback = writeDescriptorCallbacks.remove(descriptorKey) ?: return + if (status == BluetoothGatt.GATT_SUCCESS) { + callback(Result.success(Unit)) + } else { + val error = IllegalStateException("Write descriptor failed with status: $status.") + callback(Result.failure(error)) + } + } +} + +private val BluetoothAdapter.myStateArgs: MyCentralStateArgs + get() = state.toMyCentralStateArgs() + +private fun Int.toMyCentralStateArgs(): MyCentralStateArgs { + return when (this) { + BluetoothAdapter.STATE_ON -> MyCentralStateArgs.POWEREDON + else -> MyCentralStateArgs.POWEREDOFF + } +} + +private fun BluetoothDevice.toMyArgs(): MyPeripheralArgs { + val key = hashCode().toLong() + val uuid = this.uuid.toString() + return MyPeripheralArgs(key, uuid) +} + +private val BluetoothDevice.uuid: UUID + get() { + val node = address.filter { char -> char != ':' } + // We don't know the timestamp of the bluetooth device, use nil UUID as prefix. + return UUID.fromString("00000000-0000-0000-0000-$node") + } + +private val ScanResult.myAdvertisementArgs: MyAdvertisementArgs + get() { + val record = scanRecord + return if (record == null) { + val name = null + val manufacturerSpecificData = emptyMap() + val serviceUUIDs = emptyList() + val serviceData = emptyMap() + MyAdvertisementArgs(name, manufacturerSpecificData, serviceUUIDs, serviceData) + } else { + val name = record.deviceName + val manufacturerSpecificData = record.manufacturerSpecificData.toMyArgs() + val serviceUUIDs = record.serviceUuids?.map { uuid -> uuid.toString() } ?: emptyList() + val pairs = record.serviceData.entries.map { (uuid, value) -> + val key = uuid.toString() + return@map Pair(key, value) + }.toTypedArray() + val serviceData = mapOf(*pairs) + MyAdvertisementArgs(name, manufacturerSpecificData, serviceUUIDs, serviceData) + } + } + +private fun SparseArray.toMyArgs(): Map { + var index = 0 + val size = size() + val values = mutableMapOf() + while (index < size) { + val key = keyAt(index).toLong() + val value = valueAt(index) + values[key] = value + index++ + } + return values +} + +//private val ScanRecord.rawValues: Map +// get() { +// val rawValues = mutableMapOf() +// var index = 0 +// val size = bytes.size +// while (index < size) { +// val length = bytes[index++].toInt() and 0xff +// if (length == 0) { +// break +// } +// val end = index + length +// val type = bytes[index++] +// val value = bytes.slice(index until end).toByteArray() +// rawValues[type] = value +// index = end +// } +// return rawValues.toMap() +// } + +private fun BluetoothGattService.toMyArgs(): MyGattServiceArgs { + val key = hashCode().toLong() + val uuid = this.uuid.toString() + return MyGattServiceArgs(key, uuid) +} + +private fun BluetoothGattCharacteristic.toMyArgs(): MyGattCharacteristicArgs { + val key = hashCode().toLong() + val uuid = this.uuid.toString() + return MyGattCharacteristicArgs(key, uuid, myPropertyNumbers) +} + +private val BluetoothGattCharacteristic.myPropertyNumbers: List + get() { + val numbers = mutableListOf() + if (properties and BluetoothGattCharacteristic.PROPERTY_READ != 0) { + val number = MyGattCharacteristicPropertyArgs.READ.raw.toLong() + numbers.add(number) + } + if (properties and BluetoothGattCharacteristic.PROPERTY_WRITE != 0) { + val number = MyGattCharacteristicPropertyArgs.WRITE.raw.toLong() + numbers.add(number) + } + if (properties and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE != 0) { + val number = MyGattCharacteristicPropertyArgs.WRITEWITHOUTRESPONSE.raw.toLong() + numbers.add(number) + } + if (properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY != 0) { + val number = MyGattCharacteristicPropertyArgs.NOTIFY.raw.toLong() + numbers.add(number) + } + if (properties and BluetoothGattCharacteristic.PROPERTY_INDICATE != 0) { + val number = MyGattCharacteristicPropertyArgs.INDICATE.raw.toLong() + numbers.add(number) + } + return numbers + } + +private fun BluetoothGattDescriptor.toMyArgs(): MyGattDescriptorArgs { + val key = hashCode().toLong() + val uuid = this.uuid.toString() + return MyGattDescriptorArgs(key, uuid) +} + +private fun Long.toMyGattCharacteristicTypeArgs(): MyGattCharacteristicWriteTypeArgs { + val raw = toInt() + return MyGattCharacteristicWriteTypeArgs.ofRaw(raw) ?: throw IllegalArgumentException() +} + +private fun MyGattCharacteristicWriteTypeArgs.toType(): Int { + return when (this) { + MyGattCharacteristicWriteTypeArgs.WITHRESPONSE -> BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT + MyGattCharacteristicWriteTypeArgs.WITHOUTRESPONSE -> BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE + } +} \ No newline at end of file diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionResultListener.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionResultListener.kt new file mode 100644 index 0000000..d3c0e99 --- /dev/null +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyRequestPermissionResultListener.kt @@ -0,0 +1,9 @@ +package dev.yanshouwang.bluetooth_low_energy + +import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener + +class MyRequestPermissionResultListener(private val myCentralController: MyCentralController) : RequestPermissionsResultListener { + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, results: IntArray): Boolean { + return myCentralController.onRequestPermissionsResult(requestCode, results) + } +} \ No newline at end of file diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt new file mode 100644 index 0000000..0a0e8bd --- /dev/null +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyScanCallback.kt @@ -0,0 +1,14 @@ +package dev.yanshouwang.bluetooth_low_energy + +import android.bluetooth.le.ScanCallback +import android.bluetooth.le.ScanResult + +class MyScanCallback(private val myCentralController: MyCentralController) : ScanCallback() { + override fun onScanFailed(errorCode: Int) { + myCentralController.onScanFailed(errorCode) + } + + override fun onScanResult(callbackType: Int, result: ScanResult) { + myCentralController.onScanResult(result) + } +} \ No newline at end of file diff --git a/bluetooth_low_energy_android/android/src/test/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPluginTest.kt b/bluetooth_low_energy_android/android/src/test/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPluginTest.kt new file mode 100644 index 0000000..f41b4be --- /dev/null +++ b/bluetooth_low_energy_android/android/src/test/kotlin/dev/yanshouwang/bluetooth_low_energy/BluetoothLowEnergyPluginTest.kt @@ -0,0 +1,27 @@ +package dev.yanshouwang.bluetooth_low_energy + +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import kotlin.test.Test +import org.mockito.Mockito + +/* + * This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation. + * + * Once you have built the plugin's example app, you can run these tests from the command + * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or + * you can run them directly from IDEs that support JUnit such as Android Studio. + */ + +internal class BluetoothLowEnergyPluginTest { + @Test + fun onMethodCall_getPlatformVersion_returnsExpectedValue() { + val plugin = BluetoothLowEnergyAndroid() + + val call = MethodCall("getPlatformVersion", null) + val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java) + plugin.onMethodCall(call, mockResult) + + Mockito.verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE) + } +} diff --git a/bluetooth_low_energy_android/lib/bluetooth_low_energy_android.dart b/bluetooth_low_energy_android/lib/bluetooth_low_energy_android.dart new file mode 100644 index 0000000..59e70e3 --- /dev/null +++ b/bluetooth_low_energy_android/lib/bluetooth_low_energy_android.dart @@ -0,0 +1,9 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'src/my_central_controller.dart'; + +abstract class BluetoothLowEnergyAndroid { + static void registerWith() { + CentralController.instance = MyCentralController(); + } +} diff --git a/bluetooth_low_energy_android/lib/src/my_api.g.dart b/bluetooth_low_energy_android/lib/src/my_api.g.dart new file mode 100644 index 0000000..63d43d9 --- /dev/null +++ b/bluetooth_low_energy_android/lib/src/my_api.g.dart @@ -0,0 +1,736 @@ +// Autogenerated from Pigeon (v10.1.6), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +enum MyCentralStateArgs { + unknown, + unsupported, + unauthorized, + poweredOff, + poweredOn, +} + +enum MyGattCharacteristicPropertyArgs { + read, + write, + writeWithoutResponse, + notify, + indicate, +} + +enum MyGattCharacteristicWriteTypeArgs { + withResponse, + withoutResponse, +} + +class MyCentralControllerArgs { + MyCentralControllerArgs({ + required this.myStateNumber, + }); + + int myStateNumber; + + Object encode() { + return [ + myStateNumber, + ]; + } + + static MyCentralControllerArgs decode(Object result) { + result as List; + return MyCentralControllerArgs( + myStateNumber: result[0]! as int, + ); + } +} + +class MyPeripheralArgs { + MyPeripheralArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyPeripheralArgs decode(Object result) { + result as List; + return MyPeripheralArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class MyAdvertisementArgs { + MyAdvertisementArgs({ + this.name, + required this.manufacturerSpecificData, + required this.serviceUUIDs, + required this.serviceData, + }); + + String? name; + + Map manufacturerSpecificData; + + List serviceUUIDs; + + Map serviceData; + + Object encode() { + return [ + name, + manufacturerSpecificData, + serviceUUIDs, + serviceData, + ]; + } + + static MyAdvertisementArgs decode(Object result) { + result as List; + return MyAdvertisementArgs( + name: result[0] as String?, + manufacturerSpecificData: (result[1] as Map?)!.cast(), + serviceUUIDs: (result[2] as List?)!.cast(), + serviceData: (result[3] as Map?)!.cast(), + ); + } +} + +class MyGattServiceArgs { + MyGattServiceArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyGattServiceArgs decode(Object result) { + result as List; + return MyGattServiceArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class MyGattCharacteristicArgs { + MyGattCharacteristicArgs({ + required this.key, + required this.uuid, + required this.myPropertyNumbers, + }); + + int key; + + String uuid; + + List myPropertyNumbers; + + Object encode() { + return [ + key, + uuid, + myPropertyNumbers, + ]; + } + + static MyGattCharacteristicArgs decode(Object result) { + result as List; + return MyGattCharacteristicArgs( + key: result[0]! as int, + uuid: result[1]! as String, + myPropertyNumbers: (result[2] as List?)!.cast(), + ); + } +} + +class MyGattDescriptorArgs { + MyGattDescriptorArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyGattDescriptorArgs decode(Object result) { + result as List; + return MyGattDescriptorArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class _MyCentralControllerHostApiCodec extends StandardMessageCodec { + const _MyCentralControllerHostApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is MyCentralControllerArgs) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else if (value is MyGattCharacteristicArgs) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else if (value is MyGattDescriptorArgs) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is MyGattServiceArgs) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return MyCentralControllerArgs.decode(readValue(buffer)!); + case 129: + return MyGattCharacteristicArgs.decode(readValue(buffer)!); + case 130: + return MyGattDescriptorArgs.decode(readValue(buffer)!); + case 131: + return MyGattServiceArgs.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class MyCentralControllerHostApi { + /// Constructor for [MyCentralControllerHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + MyCentralControllerHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _MyCentralControllerHostApiCodec(); + + Future setUp() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.setUp', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as MyCentralControllerArgs?)!; + } + } + + Future tearDown() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.tearDown', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future startDiscovery() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.startDiscovery', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future stopDiscovery() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.stopDiscovery', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future connect(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.connect', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future disconnect(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.disconnect', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future discoverGATT(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.discoverGATT', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future> getServices(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getServices', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getCharacteristics(int arg_myServiceKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getCharacteristics', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myServiceKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getDescriptors(int arg_myCharacteristicKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getDescriptors', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myCharacteristicKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future readCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.readCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as Uint8List?)!; + } + } + + Future writeCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, Uint8List arg_value, int arg_myTypeNumber) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.writeCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey, arg_value, arg_myTypeNumber]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future notifyCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, bool arg_state) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.notifyCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey, arg_state]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future readDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.readDescriptor', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myDescriptorKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as Uint8List?)!; + } + } + + Future writeDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey, Uint8List arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.writeDescriptor', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myDescriptorKey, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } +} + +class _MyCentralControllerFlutterApiCodec extends StandardMessageCodec { + const _MyCentralControllerFlutterApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is MyAdvertisementArgs) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else if (value is MyPeripheralArgs) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return MyAdvertisementArgs.decode(readValue(buffer)!); + case 129: + return MyPeripheralArgs.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class MyCentralControllerFlutterApi { + static const MessageCodec codec = _MyCentralControllerFlutterApiCodec(); + + void onStateChanged(int myStateNumber); + + void onDiscovered(MyPeripheralArgs myPeripheralArgs, int rssi, MyAdvertisementArgs myAdvertisementArgs); + + void onPeripheralStateChanged(int myPeripheralKey, bool state); + + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value); + + static void setup(MyCentralControllerFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onStateChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onStateChanged was null.'); + final List args = (message as List?)!; + final int? arg_myStateNumber = (args[0] as int?); + assert(arg_myStateNumber != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onStateChanged was null, expected non-null int.'); + api.onStateChanged(arg_myStateNumber!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onDiscovered', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onDiscovered was null.'); + final List args = (message as List?)!; + final MyPeripheralArgs? arg_myPeripheralArgs = (args[0] as MyPeripheralArgs?); + assert(arg_myPeripheralArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyPeripheralArgs.'); + final int? arg_rssi = (args[1] as int?); + assert(arg_rssi != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null int.'); + final MyAdvertisementArgs? arg_myAdvertisementArgs = (args[2] as MyAdvertisementArgs?); + assert(arg_myAdvertisementArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyAdvertisementArgs.'); + api.onDiscovered(arg_myPeripheralArgs!, arg_rssi!, arg_myAdvertisementArgs!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onPeripheralStateChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onPeripheralStateChanged was null.'); + final List args = (message as List?)!; + final int? arg_myPeripheralKey = (args[0] as int?); + assert(arg_myPeripheralKey != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null int.'); + final bool? arg_state = (args[1] as bool?); + assert(arg_state != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null bool.'); + api.onPeripheralStateChanged(arg_myPeripheralKey!, arg_state!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onCharacteristicValueChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null.'); + final List args = (message as List?)!; + final int? arg_myCharacteristicKey = (args[0] as int?); + assert(arg_myCharacteristicKey != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null int.'); + final Uint8List? arg_value = (args[1] as Uint8List?); + assert(arg_value != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null Uint8List.'); + api.onCharacteristicValueChanged(arg_myCharacteristicKey!, arg_value!); + return; + }); + } + } + } +} diff --git a/bluetooth_low_energy_android/lib/src/my_central_controller.dart b/bluetooth_low_energy_android/lib/src/my_central_controller.dart new file mode 100644 index 0000000..ba60583 --- /dev/null +++ b/bluetooth_low_energy_android/lib/src/my_central_controller.dart @@ -0,0 +1,356 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_characteristic.dart'; +import 'my_gatt_descriptor.dart'; +import 'my_gatt_service.dart'; +import 'my_peripheral.dart'; + +class MyCentralController extends CentralController + implements MyCentralControllerFlutterApi { + MyCentralController() + : _myApi = MyCentralControllerHostApi(), + _stateChangedController = StreamController.broadcast(), + _discoveredController = StreamController.broadcast(), + _peripheralStateChangedController = StreamController.broadcast(), + _characteristicValueChangedController = StreamController.broadcast(), + _myPeripherals = {}, + _myServices = {}, + _myCharacteristics = {}, + _myDescriptors = {}, + _state = CentralState.unknown; + + final MyCentralControllerHostApi _myApi; + final StreamController _stateChangedController; + final StreamController _discoveredController; + final StreamController + _peripheralStateChangedController; + final StreamController + _characteristicValueChangedController; + final Map _myPeripherals; + final Map _myServices; + final Map _myCharacteristics; + final Map _myDescriptors; + + CentralState _state; + @override + CentralState get state => _state; + + @override + Stream get stateChanged => + _stateChangedController.stream; + @override + Stream get discovered => + _discoveredController.stream; + @override + Stream get peripheralStateChanged => + _peripheralStateChangedController.stream; + @override + Stream + get characteristicValueChanged => + _characteristicValueChangedController.stream; + + Future _throwWithState(CentralState state) async { + if (this.state == state) { + throw BluetoothLowEnergyError('$state is unexpected.'); + } + } + + Future _throwWithoutState(CentralState state) async { + if (this.state != state) { + throw BluetoothLowEnergyError( + '$state is expected, but current state is ${this.state}.', + ); + } + } + + @override + Future setUp() async { + await _throwWithoutState(CentralState.unknown); + final args = await _myApi.setUp(); + final myStateArgs = MyCentralStateArgs.values[args.myStateNumber]; + _state = myStateArgs.toState(); + MyCentralControllerFlutterApi.setup(this); + } + + @override + Future tearDown() async { + await _throwWithState(CentralState.unknown); + await _myApi.tearDown(); + MyCentralControllerFlutterApi.setup(null); + _myPeripherals.clear(); + _myServices.clear(); + _myCharacteristics.clear(); + _myDescriptors.clear(); + _state = CentralState.unknown; + } + + @override + Future startDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _myApi.startDiscovery(); + } + + @override + Future stopDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _myApi.stopDiscovery(); + } + + @override + Future connect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.connect(myPeripheral.hashCode); + } + + @override + Future disconnect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.disconnect(myPeripheral.hashCode); + } + + @override + Future discoverGATT(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.discoverGATT(myPeripheral.hashCode); + } + + @override + Future> getServices(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final myServiceArgses = await _myApi.getServices(myPeripheral.hashCode); + return myServiceArgses + .cast() + .map( + (myServiceArgs) => _myServices.putIfAbsent( + myServiceArgs.key, + () => MyGattService.fromMyArgs( + myPeripheral, + myServiceArgs, + ), + ), + ) + .toList(); + } + + @override + Future> getCharacteristics( + GattService service, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myService = service as MyGattService; + final myCharactersiticArgses = await _myApi.getCharacteristics( + myService.hashCode, + ); + return myCharactersiticArgses + .cast() + .map( + (myCharacteristicArgs) => _myCharacteristics.putIfAbsent( + myCharacteristicArgs.key, + () => MyGattCharacteristic.fromMyArgs( + myService, + myCharacteristicArgs, + ), + ), + ) + .toList(); + } + + @override + Future> getDescriptors( + GattCharacteristic characteristic, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myDescriptorArgses = await _myApi.getDescriptors( + myCharacteristic.hashCode, + ); + return myDescriptorArgses + .cast() + .map( + (myDescriptorArgs) => _myDescriptors.putIfAbsent( + myDescriptorArgs.key, + () => MyGattDescriptor.fromMyArgs( + myCharacteristic, + myDescriptorArgs, + ), + ), + ) + .toList(); + } + + @override + Future readCharacteristic( + GattCharacteristic characteristic) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final value = await _myApi.readCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + ); + return value; + } + + @override + Future writeCharacteristic( + GattCharacteristic characteristic, { + required Uint8List value, + required GattCharacteristicWriteType type, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final typeArgs = type.toMyArgs(); + final typeNumber = typeArgs.index; + await _myApi.writeCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + value, + typeNumber, + ); + } + + @override + Future notifyCharacteristic( + GattCharacteristic characteristic, { + required bool state, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + await _myApi.notifyCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + state, + ); + } + + @override + Future readDescriptor(GattDescriptor descriptor) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final myCharacteristic = myDescriptor.myCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final value = await _myApi.readDescriptor( + myPeripheral.hashCode, + myDescriptor.hashCode, + ); + return value; + } + + @override + Future writeDescriptor( + GattDescriptor descriptor, { + required Uint8List value, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final myCharacteristic = myDescriptor.myCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + await _myApi.writeDescriptor( + myPeripheral.hashCode, + myDescriptor.hashCode, + value, + ); + } + + @override + void onStateChanged(int myStateNumber) { + final myStateArgs = MyCentralStateArgs.values[myStateNumber]; + final state = myStateArgs.toState(); + if (_state == state) { + return; + } + _state = state; + final eventArgs = CentralStateChangedEventArgs(state); + _stateChangedController.add(eventArgs); + } + + @override + void onDiscovered( + MyPeripheralArgs myPeripheralArgs, + int rssi, + MyAdvertisementArgs myAdvertisementArgs, + ) { + final myPeripheral = _myPeripherals.putIfAbsent( + myPeripheralArgs.key, + () => MyPeripheral.fromMyArgs(myPeripheralArgs), + ); + final advertisement = myAdvertisementArgs.toAdvertisement(); + final eventArgs = CentralDiscoveredEventArgs( + myPeripheral, + rssi, + advertisement, + ); + _discoveredController.add(eventArgs); + } + + @override + void onPeripheralStateChanged(int myPeripheralKey, bool state) { + final myPeripheral = _myPeripherals[myPeripheralKey]; + if (myPeripheral == null) { + return; + } + final eventArgs = PeripheralStateChangedEventArgs(myPeripheral, state); + _peripheralStateChangedController.add(eventArgs); + } + + @override + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value) { + final myCharacteristic = + _myCharacteristics[myCharacteristicKey] as MyGattCharacteristic; + final eventArgs = GattCharacteristicValueChangedEventArgs( + myCharacteristic, + value, + ); + _characteristicValueChangedController.add(eventArgs); + } +} + +extension on MyAdvertisementArgs { + Advertisement toAdvertisement() { + final serviceUUIDs = this + .serviceUUIDs + .cast() + .map((uuid) => UUID.fromString(uuid)) + .toList(); + final serviceData = this.serviceData.cast().map( + (uuid, data) { + final key = UUID.fromString(uuid); + final value = data; + return MapEntry(key, value); + }, + ); + return Advertisement( + name: name, + manufacturerSpecificData: manufacturerSpecificData.cast(), + serviceUUIDs: serviceUUIDs, + serviceData: serviceData, + ); + } +} + +extension on MyCentralStateArgs { + CentralState toState() { + return CentralState.values[index]; + } +} + +extension on GattCharacteristicWriteType { + MyGattCharacteristicWriteTypeArgs toMyArgs() { + return MyGattCharacteristicWriteTypeArgs.values[index]; + } +} diff --git a/bluetooth_low_energy_android/lib/src/my_gatt_characteristic.dart b/bluetooth_low_energy_android/lib/src/my_gatt_characteristic.dart new file mode 100644 index 0000000..811fb23 --- /dev/null +++ b/bluetooth_low_energy_android/lib/src/my_gatt_characteristic.dart @@ -0,0 +1,42 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_service.dart'; +import 'my_object.dart'; + +class MyGattCharacteristic extends MyObject implements GattCharacteristic { + final MyGattService myService; + @override + final UUID uuid; + @override + final List properties; + + MyGattCharacteristic( + super.hashCode, + this.myService, + this.uuid, + this.properties, + ); + + factory MyGattCharacteristic.fromMyArgs( + MyGattService myService, + MyGattCharacteristicArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + final properties = myArgs.myPropertyNumbers.cast().map( + (myPropertyNumber) { + final myPropertyArgs = + MyGattCharacteristicPropertyArgs.values[myPropertyNumber]; + return myPropertyArgs.toProperty(); + }, + ).toList(); + return MyGattCharacteristic(hashCode, myService, uuid, properties); + } +} + +extension on MyGattCharacteristicPropertyArgs { + GattCharacteristicProperty toProperty() { + return GattCharacteristicProperty.values[index]; + } +} diff --git a/bluetooth_low_energy_android/lib/src/my_gatt_descriptor.dart b/bluetooth_low_energy_android/lib/src/my_gatt_descriptor.dart new file mode 100644 index 0000000..6798f4a --- /dev/null +++ b/bluetooth_low_energy_android/lib/src/my_gatt_descriptor.dart @@ -0,0 +1,22 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_characteristic.dart'; +import 'my_object.dart'; + +class MyGattDescriptor extends MyObject implements GattDescriptor { + final MyGattCharacteristic myCharacteristic; + @override + final UUID uuid; + + MyGattDescriptor(super.hashCode, this.myCharacteristic, this.uuid); + + factory MyGattDescriptor.fromMyArgs( + MyGattCharacteristic myCharacteristic, + MyGattDescriptorArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyGattDescriptor(hashCode, myCharacteristic, uuid); + } +} diff --git a/bluetooth_low_energy_android/lib/src/my_gatt_service.dart b/bluetooth_low_energy_android/lib/src/my_gatt_service.dart new file mode 100644 index 0000000..37babdb --- /dev/null +++ b/bluetooth_low_energy_android/lib/src/my_gatt_service.dart @@ -0,0 +1,22 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_object.dart'; +import 'my_peripheral.dart'; + +class MyGattService extends MyObject implements GattService { + final MyPeripheral myPeripheral; + @override + final UUID uuid; + + MyGattService(super.hashCode, this.myPeripheral, this.uuid); + + factory MyGattService.fromMyArgs( + MyPeripheral myPeripheral, + MyGattServiceArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyGattService(hashCode, myPeripheral, uuid); + } +} diff --git a/bluetooth_low_energy_android/lib/src/my_object.dart b/bluetooth_low_energy_android/lib/src/my_object.dart new file mode 100644 index 0000000..2b33805 --- /dev/null +++ b/bluetooth_low_energy_android/lib/src/my_object.dart @@ -0,0 +1,11 @@ +abstract class MyObject { + @override + final int hashCode; + + MyObject(this.hashCode); + + @override + bool operator ==(Object other) { + return other is MyObject && other.hashCode == hashCode; + } +} diff --git a/bluetooth_low_energy_android/lib/src/my_peripheral.dart b/bluetooth_low_energy_android/lib/src/my_peripheral.dart new file mode 100644 index 0000000..7be1bd3 --- /dev/null +++ b/bluetooth_low_energy_android/lib/src/my_peripheral.dart @@ -0,0 +1,17 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_object.dart'; + +class MyPeripheral extends MyObject implements Peripheral { + @override + final UUID uuid; + + MyPeripheral(super.hashCode, this.uuid); + + factory MyPeripheral.fromMyArgs(MyPeripheralArgs myArgs) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyPeripheral(hashCode, uuid); + } +} diff --git a/bluetooth_low_energy_android/my_api.dart b/bluetooth_low_energy_android/my_api.dart new file mode 100644 index 0000000..6a42a40 --- /dev/null +++ b/bluetooth_low_energy_android/my_api.dart @@ -0,0 +1,144 @@ +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/src/my_api.g.dart', + dartOptions: DartOptions(), + kotlinOut: + 'android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/MyApi.g.kt', + kotlinOptions: KotlinOptions( + package: 'dev.yanshouwang.bluetooth_low_energy', + ), + ), +) +@HostApi() +abstract class MyCentralControllerHostApi { + @async + MyCentralControllerArgs setUp(); + void tearDown(); + @async + void startDiscovery(); + void stopDiscovery(); + @async + void connect(int myPeripheralKey); + @async + void disconnect(int myPeripheralKey); + @async + void discoverGATT(int myPeripheralKey); + List getServices(int myPeripheralKey); + List getCharacteristics(int myServiceKey); + List getDescriptors(int myCharacteristicKey); + @async + Uint8List readCharacteristic(int myPeripheralKey, int myCharacteristicKey); + @async + void writeCharacteristic( + int myPeripheralKey, + int myCharacteristicKey, + Uint8List value, + int myTypeNumber, + ); + @async + void notifyCharacteristic( + int myPeripheralKey, + int myCharacteristicKey, + bool state, + ); + @async + Uint8List readDescriptor(int myPeripheralKey, int myDescriptorKey); + @async + void writeDescriptor( + int myPeripheralKey, + int myDescriptorKey, + Uint8List value, + ); +} + +@FlutterApi() +abstract class MyCentralControllerFlutterApi { + void onStateChanged(int myStateNumber); + void onDiscovered( + MyPeripheralArgs myPeripheralArgs, + int rssi, + MyAdvertisementArgs myAdvertisementArgs, + ); + void onPeripheralStateChanged(int myPeripheralKey, bool state); + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value); +} + +class MyCentralControllerArgs { + final int myStateNumber; + + MyCentralControllerArgs(this.myStateNumber); +} + +class MyPeripheralArgs { + final int key; + final String uuid; + + MyPeripheralArgs(this.key, this.uuid); +} + +class MyAdvertisementArgs { + final String? name; + final Map manufacturerSpecificData; + final List serviceUUIDs; + final Map serviceData; + + MyAdvertisementArgs( + this.name, + this.manufacturerSpecificData, + this.serviceUUIDs, + this.serviceData, + ); +} + +class MyGattServiceArgs { + final int key; + final String uuid; + + MyGattServiceArgs(this.key, this.uuid); +} + +class MyGattCharacteristicArgs { + final int key; + final String uuid; + final List myPropertyNumbers; + + MyGattCharacteristicArgs( + this.key, + this.uuid, + this.myPropertyNumbers, + ); +} + +class MyGattDescriptorArgs { + final int key; + final String uuid; + + MyGattDescriptorArgs(this.key, this.uuid); +} + +enum MyCentralStateArgs { + unknown, + unsupported, + unauthorized, + poweredOff, + poweredOn, +} + +enum MyGattCharacteristicPropertyArgs { + read, + write, + writeWithoutResponse, + notify, + indicate, +} + +enum MyGattCharacteristicWriteTypeArgs { + // Write with response + withResponse, + // Write without response + withoutResponse, + // Write with response and waiting for confirmation + // reliable, +} diff --git a/bluetooth_low_energy_android/pubspec.yaml b/bluetooth_low_energy_android/pubspec.yaml new file mode 100644 index 0000000..4d00077 --- /dev/null +++ b/bluetooth_low_energy_android/pubspec.yaml @@ -0,0 +1,29 @@ +name: bluetooth_low_energy_android +description: Android implementation of the bluetooth_low_energy plugin. +version: 2.0.0 +homepage: https://github.com/yanshouwang/bluetooth_low_energy + +environment: + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + bluetooth_low_energy_platform_interface: + path: ../bluetooth_low_energy_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + pigeon: ^10.1.6 + +flutter: + plugin: + implements: bluetooth_low_energy + platforms: + android: + package: dev.yanshouwang.bluetooth_low_energy + pluginClass: BluetoothLowEnergyAndroid + dartPluginClass: BluetoothLowEnergyAndroid diff --git a/bluetooth_low_energy_ios/.gitignore b/bluetooth_low_energy_ios/.gitignore new file mode 100644 index 0000000..96486fd --- /dev/null +++ b/bluetooth_low_energy_ios/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/bluetooth_low_energy_ios/.metadata b/bluetooth_low_energy_ios/.metadata new file mode 100644 index 0000000..b3231e1 --- /dev/null +++ b/bluetooth_low_energy_ios/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: ios + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/bluetooth_low_energy_ios/CHANGELOG.md b/bluetooth_low_energy_ios/CHANGELOG.md new file mode 100644 index 0000000..e510273 --- /dev/null +++ b/bluetooth_low_energy_ios/CHANGELOG.md @@ -0,0 +1,4 @@ +## 2.0.0 + +- Rewrite the whole project with federated plugins. +- Support macOS and Linux. diff --git a/bluetooth_low_energy_ios/LICENSE b/bluetooth_low_energy_ios/LICENSE new file mode 100644 index 0000000..515ed4b --- /dev/null +++ b/bluetooth_low_energy_ios/LICENSE @@ -0,0 +1,21 @@ +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. \ No newline at end of file diff --git a/bluetooth_low_energy_ios/README.md b/bluetooth_low_energy_ios/README.md new file mode 100644 index 0000000..9b7853e --- /dev/null +++ b/bluetooth_low_energy_ios/README.md @@ -0,0 +1,15 @@ +# bluetooth_low_energy_ios + +The iOS implementation of [`bluetooth_low_energy`][1]. + +## Usage + +This package is [endorsed][2], which means you can simply use `bluetooth_low_energy` +normally. This package will be automatically included in your app when you do, +so you do not need to add it to your `pubspec.yaml`. + +However, if you `import` this package to use any of its APIs directly, you +should add it to your `pubspec.yaml` as usual. + +[1]: https://pub.dev/packages/bluetooth_low_energy +[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin diff --git a/bluetooth_low_energy_ios/analysis_options.yaml b/bluetooth_low_energy_ios/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/bluetooth_low_energy_ios/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/bluetooth_low_energy_ios/ios/.gitignore b/bluetooth_low_energy_ios/ios/.gitignore new file mode 100644 index 0000000..0c88507 --- /dev/null +++ b/bluetooth_low_energy_ios/ios/.gitignore @@ -0,0 +1,38 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig +/Flutter/ephemeral/ +/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/MessagesKt.kt b/bluetooth_low_energy_ios/ios/Assets/.gitkeep similarity index 100% rename from android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy/proto/MessagesKt.kt rename to bluetooth_low_energy_ios/ios/Assets/.gitkeep diff --git a/bluetooth_low_energy_ios/ios/Classes/BluetoothLowEnergyiOS.swift b/bluetooth_low_energy_ios/ios/Classes/BluetoothLowEnergyiOS.swift new file mode 100644 index 0000000..a80f325 --- /dev/null +++ b/bluetooth_low_energy_ios/ios/Classes/BluetoothLowEnergyiOS.swift @@ -0,0 +1,10 @@ +import Flutter +import UIKit + +public class BluetoothLowEnergyiOS: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let binaryMessenger = registrar.messenger() + let centralController = MyCentralController(binaryMessenger) + MyCentralControllerHostApiSetup.setUp(binaryMessenger: binaryMessenger, api: centralController) + } +} diff --git a/bluetooth_low_energy_ios/ios/Classes/MyApi.g.swift b/bluetooth_low_energy_ios/ios/Classes/MyApi.g.swift new file mode 100644 index 0000000..e5754e5 --- /dev/null +++ b/bluetooth_low_energy_ios/ios/Classes/MyApi.g.swift @@ -0,0 +1,594 @@ +// Autogenerated from Pigeon (v10.1.6), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation +#if os(iOS) +import Flutter +#elseif os(macOS) +import FlutterMacOS +#else +#error("Unsupported platform.") +#endif + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)" + ] +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +enum MyCentralStateArgs: Int { + case unknown = 0 + case unsupported = 1 + case unauthorized = 2 + case poweredOff = 3 + case poweredOn = 4 +} + +enum MyGattCharacteristicPropertyArgs: Int { + case read = 0 + case write = 1 + case writeWithoutResponse = 2 + case notify = 3 + case indicate = 4 +} + +enum MyGattCharacteristicWriteTypeArgs: Int { + case withResponse = 0 + case withoutResponse = 1 +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyCentralControllerArgs { + var myStateNumber: Int64 + + static func fromList(_ list: [Any?]) -> MyCentralControllerArgs? { + let myStateNumber = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + + return MyCentralControllerArgs( + myStateNumber: myStateNumber + ) + } + func toList() -> [Any?] { + return [ + myStateNumber, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyPeripheralArgs { + var key: Int64 + var uuid: String + + static func fromList(_ list: [Any?]) -> MyPeripheralArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + + return MyPeripheralArgs( + key: key, + uuid: uuid + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyAdvertisementArgs { + var name: String? = nil + var manufacturerSpecificData: [Int64?: FlutterStandardTypedData?] + var serviceUUIDs: [String?] + var serviceData: [String?: FlutterStandardTypedData?] + + static func fromList(_ list: [Any?]) -> MyAdvertisementArgs? { + let name: String? = nilOrValue(list[0]) + let manufacturerSpecificData = list[1] as! [Int64?: FlutterStandardTypedData?] + let serviceUUIDs = list[2] as! [String?] + let serviceData = list[3] as! [String?: FlutterStandardTypedData?] + + return MyAdvertisementArgs( + name: name, + manufacturerSpecificData: manufacturerSpecificData, + serviceUUIDs: serviceUUIDs, + serviceData: serviceData + ) + } + func toList() -> [Any?] { + return [ + name, + manufacturerSpecificData, + serviceUUIDs, + serviceData, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyGattServiceArgs { + var key: Int64 + var uuid: String + + static func fromList(_ list: [Any?]) -> MyGattServiceArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + + return MyGattServiceArgs( + key: key, + uuid: uuid + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyGattCharacteristicArgs { + var key: Int64 + var uuid: String + var myPropertyNumbers: [Int64?] + + static func fromList(_ list: [Any?]) -> MyGattCharacteristicArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + let myPropertyNumbers = list[2] as! [Int64?] + + return MyGattCharacteristicArgs( + key: key, + uuid: uuid, + myPropertyNumbers: myPropertyNumbers + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + myPropertyNumbers, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyGattDescriptorArgs { + var key: Int64 + var uuid: String + + static func fromList(_ list: [Any?]) -> MyGattDescriptorArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + + return MyGattDescriptorArgs( + key: key, + uuid: uuid + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + ] + } +} + +private class MyCentralControllerHostApiCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + return MyCentralControllerArgs.fromList(self.readValue() as! [Any?]) + case 129: + return MyGattCharacteristicArgs.fromList(self.readValue() as! [Any?]) + case 130: + return MyGattDescriptorArgs.fromList(self.readValue() as! [Any?]) + case 131: + return MyGattServiceArgs.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class MyCentralControllerHostApiCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? MyCentralControllerArgs { + super.writeByte(128) + super.writeValue(value.toList()) + } else if let value = value as? MyGattCharacteristicArgs { + super.writeByte(129) + super.writeValue(value.toList()) + } else if let value = value as? MyGattDescriptorArgs { + super.writeByte(130) + super.writeValue(value.toList()) + } else if let value = value as? MyGattServiceArgs { + super.writeByte(131) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class MyCentralControllerHostApiCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return MyCentralControllerHostApiCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return MyCentralControllerHostApiCodecWriter(data: data) + } +} + +class MyCentralControllerHostApiCodec: FlutterStandardMessageCodec { + static let shared = MyCentralControllerHostApiCodec(readerWriter: MyCentralControllerHostApiCodecReaderWriter()) +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol MyCentralControllerHostApi { + func setUp(completion: @escaping (Result) -> Void) + func tearDown() throws + func startDiscovery() throws + func stopDiscovery() throws + func connect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) + func disconnect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) + func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) + func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs] + func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs] + func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs] + func readCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result) -> Void) + func writeCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result) -> Void) + func notifyCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result) -> Void) + func readDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result) -> Void) + func writeDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result) -> Void) +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class MyCentralControllerHostApiSetup { + /// The codec used by MyCentralControllerHostApi. + static var codec: FlutterStandardMessageCodec { MyCentralControllerHostApiCodec.shared } + /// Sets up an instance of `MyCentralControllerHostApi` to handle messages through the `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: MyCentralControllerHostApi?) { + let setUpChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.setUp", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setUpChannel.setMessageHandler { _, reply in + api.setUp() { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + setUpChannel.setMessageHandler(nil) + } + let tearDownChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.tearDown", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + tearDownChannel.setMessageHandler { _, reply in + do { + try api.tearDown() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + tearDownChannel.setMessageHandler(nil) + } + let startDiscoveryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.startDiscovery", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + startDiscoveryChannel.setMessageHandler { _, reply in + do { + try api.startDiscovery() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + startDiscoveryChannel.setMessageHandler(nil) + } + let stopDiscoveryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.stopDiscovery", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + stopDiscoveryChannel.setMessageHandler { _, reply in + do { + try api.stopDiscovery() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + stopDiscoveryChannel.setMessageHandler(nil) + } + let connectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.connect", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + connectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + api.connect(myPeripheralKey: myPeripheralKeyArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + connectChannel.setMessageHandler(nil) + } + let disconnectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.disconnect", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + disconnectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + api.disconnect(myPeripheralKey: myPeripheralKeyArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + disconnectChannel.setMessageHandler(nil) + } + let discoverGATTChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.discoverGATT", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + discoverGATTChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + api.discoverGATT(myPeripheralKey: myPeripheralKeyArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + discoverGATTChannel.setMessageHandler(nil) + } + let getServicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.getServices", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getServicesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + do { + let result = try api.getServices(myPeripheralKey: myPeripheralKeyArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getServicesChannel.setMessageHandler(nil) + } + let getCharacteristicsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.getCharacteristics", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getCharacteristicsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myServiceKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + do { + let result = try api.getCharacteristics(myServiceKey: myServiceKeyArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getCharacteristicsChannel.setMessageHandler(nil) + } + let getDescriptorsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.getDescriptors", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getDescriptorsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myCharacteristicKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + do { + let result = try api.getDescriptors(myCharacteristicKey: myCharacteristicKeyArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getDescriptorsChannel.setMessageHandler(nil) + } + let readCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.readCharacteristic", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + readCharacteristicChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.readCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + readCharacteristicChannel.setMessageHandler(nil) + } + let writeCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.writeCharacteristic", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + writeCharacteristicChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + let valueArg = args[2] as! FlutterStandardTypedData + let myTypeNumberArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32) + api.writeCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, value: valueArg, myTypeNumber: myTypeNumberArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + writeCharacteristicChannel.setMessageHandler(nil) + } + let notifyCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.notifyCharacteristic", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + notifyCharacteristicChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + let stateArg = args[2] as! Bool + api.notifyCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, state: stateArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + notifyCharacteristicChannel.setMessageHandler(nil) + } + let readDescriptorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.readDescriptor", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + readDescriptorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myDescriptorKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.readDescriptor(myPeripheralKey: myPeripheralKeyArg, myDescriptorKey: myDescriptorKeyArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + readDescriptorChannel.setMessageHandler(nil) + } + let writeDescriptorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.writeDescriptor", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + writeDescriptorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myDescriptorKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + let valueArg = args[2] as! FlutterStandardTypedData + api.writeDescriptor(myPeripheralKey: myPeripheralKeyArg, myDescriptorKey: myDescriptorKeyArg, value: valueArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + writeDescriptorChannel.setMessageHandler(nil) + } + } +} +private class MyCentralControllerFlutterApiCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + return MyAdvertisementArgs.fromList(self.readValue() as! [Any?]) + case 129: + return MyPeripheralArgs.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class MyCentralControllerFlutterApiCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? MyAdvertisementArgs { + super.writeByte(128) + super.writeValue(value.toList()) + } else if let value = value as? MyPeripheralArgs { + super.writeByte(129) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class MyCentralControllerFlutterApiCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return MyCentralControllerFlutterApiCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return MyCentralControllerFlutterApiCodecWriter(data: data) + } +} + +class MyCentralControllerFlutterApiCodec: FlutterStandardMessageCodec { + static let shared = MyCentralControllerFlutterApiCodec(readerWriter: MyCentralControllerFlutterApiCodecReaderWriter()) +} + +/// Generated class from Pigeon that represents Flutter messages that can be called from Swift. +class MyCentralControllerFlutterApi { + private let binaryMessenger: FlutterBinaryMessenger + init(binaryMessenger: FlutterBinaryMessenger){ + self.binaryMessenger = binaryMessenger + } + var codec: FlutterStandardMessageCodec { + return MyCentralControllerFlutterApiCodec.shared + } + func onStateChanged(myStateNumber myStateNumberArg: Int64, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onStateChanged", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myStateNumberArg] as [Any?]) { _ in + completion() + } + } + func onDiscovered(myPeripheralArgs myPeripheralArgsArg: MyPeripheralArgs, rssi rssiArg: Int64, myAdvertisementArgs myAdvertisementArgsArg: MyAdvertisementArgs, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onDiscovered", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myPeripheralArgsArg, rssiArg, myAdvertisementArgsArg] as [Any?]) { _ in + completion() + } + } + func onPeripheralStateChanged(myPeripheralKey myPeripheralKeyArg: Int64, state stateArg: Bool, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onPeripheralStateChanged", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myPeripheralKeyArg, stateArg] as [Any?]) { _ in + completion() + } + } + func onCharacteristicValueChanged(myCharacteristicKey myCharacteristicKeyArg: Int64, value valueArg: FlutterStandardTypedData, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onCharacteristicValueChanged", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myCharacteristicKeyArg, valueArg] as [Any?]) { _ in + completion() + } + } +} diff --git a/bluetooth_low_energy_ios/ios/Classes/MyCentralController.swift b/bluetooth_low_energy_ios/ios/Classes/MyCentralController.swift new file mode 100644 index 0000000..8aa06a1 --- /dev/null +++ b/bluetooth_low_energy_ios/ios/Classes/MyCentralController.swift @@ -0,0 +1,696 @@ +// +// MyCentralController.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation +import Flutter +import CoreBluetooth + +class MyCentralController: MyCentralControllerHostApi { + init(_ binaryMessenger: FlutterBinaryMessenger) { + myApi = MyCentralControllerFlutterApi(binaryMessenger: binaryMessenger) + } + + private let myApi: MyCentralControllerFlutterApi + private lazy var myCentralManagerDelegate = MyCentralManagerDelegate(self) + private lazy var myPeripheralDelegate = MyPeripheralDelegate(self) + private let centralManager = CBCentralManager() + + private var peripherals = [Int: CBPeripheral]() + private var services = [Int: CBService]() + private var characteristics = [Int: CBCharacteristic]() + private var descriptors = [Int: CBDescriptor]() + + var setUpCompletion: ((Result) -> Void)? + var connectCompletions = [Int: (Result) -> Void]() + var disconnectCompletions = [Int: (Result) -> Void]() + var discoverGattCompletions = [Int: (Result) -> Void]() + var unfinishedServices = [Int: [CBService]]() + var unfinishedCharacteristics = [Int: [CBCharacteristic]]() + var readCharacteristicCompletions = [Int: (Result) -> Void]() + var writeCharacteristicCompletions = [Int: (Result) -> Void]() + var notifyCharacteristicCompletions = [Int: (Result) -> Void]() + var readDescriptorCompletions = [Int: (Result) -> Void]() + var writeDescriptorCompletions = [Int: (Result) -> Void]() + + func setUp(completion: @escaping (Result) -> Void) { + do { + let unfinishedCompletion = setUpCompletion + if unfinishedCompletion != nil { + throw MyError.illegalState + } + centralManager.delegate = myCentralManagerDelegate + if centralManager.state == .unknown { + setUpCompletion = completion + } else { + let myStateArgs = centralManager.state.toMyArgs() + let myStateNumber = Int64(myStateArgs.rawValue) + let myArgs = MyCentralControllerArgs(myStateNumber: myStateNumber) + completion(.success(myArgs)) + } + } catch { + completion(.failure(error)) + } + } + + func tearDown() throws { + centralManager.delegate = nil + if(centralManager.isScanning) { + centralManager.stopScan() + } + for peripheral in peripherals.values { + peripheral.delegate = nil + if peripheral.state != .disconnected { + centralManager.cancelPeripheralConnection(peripheral) + } + } + peripherals.removeAll() + services.removeAll() + characteristics.removeAll() + descriptors.removeAll() + } + + func startDiscovery() throws { + let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true] + centralManager.scanForPeripherals(withServices: nil, options: options) + } + + func stopDiscovery() throws { + centralManager.stopScan() + } + + func connect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + let unfinishedCompletion = connectCompletions[peripheralKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + centralManager.connect(peripheral) + connectCompletions[peripheralKey] = completion + } catch { + completion(.failure(error)) + } + } + + func disconnect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + let unfinishedCompletion = disconnectCompletions[peripheralKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + centralManager.cancelPeripheralConnection(peripheral) + disconnectCompletions[peripheralKey] = completion + } catch { + completion(.failure(error)) + } + } + + func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + let unfinishedCompletion = discoverGattCompletions[peripheralKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + peripheral.discoverServices(nil) + discoverGattCompletions[peripheralKey] = completion + } catch { + completion(.failure(error)) + } + } + + func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs] { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let services = peripheral.services ?? [] + return services.map { service in + let serviceKey = service.hash + if self.services[serviceKey] == nil { + self.services[serviceKey] = service + } + return service.toMyArgs() + } + } + + func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs] { + let serviceKey = Int(myServiceKey) + guard let service = services[serviceKey] else { + throw MyError.illegalArgument + } + let characteristics = service.characteristics ?? [] + return characteristics.map { characteristic in + let characteristicKey = characteristic.hash + if self.characteristics[characteristicKey] == nil { + self.characteristics[characteristicKey] = characteristic + } + return characteristic.toMyArgs() + } + } + + func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs] { + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let descritors = characteristic.descriptors ?? [] + return descritors.map { descriptor in + let descriptorKey = descriptor.hash + if self.descriptors[descriptorKey] == nil { + self.descriptors[descriptorKey] = descriptor + } + return descriptor.toMyArgs() + } + } + + func readCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let unfinishedCompletion = readCharacteristicCompletions[characteristicKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.readValue(for: characteristic) + readCharacteristicCompletions[characteristicKey] = completion + } catch { + completion(.failure(error)) + } + } + + func writeCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let data = value.data + let myTypeRawValue = Int(myTypeNumber) + guard let myTypeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: myTypeRawValue) else { + throw MyError.illegalArgument + } + let type = myTypeArgs.toType() + let unfinishedCompletion = writeCharacteristicCompletions[characteristicKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.writeValue(data, for: characteristic, type: type) + writeCharacteristicCompletions[characteristicKey] = completion + } catch { + completion(.failure(error)) + } + } + + func notifyCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let unfinishedCompletion = notifyCharacteristicCompletions[characteristicKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.setNotifyValue(state, for: characteristic) + notifyCharacteristicCompletions[characteristicKey] = completion + } catch { + completion(.failure(error)) + } + } + + func readDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let descriptorKey = Int(myDescriptorKey) + guard let descriptor = descriptors[descriptorKey] else { + throw MyError.illegalArgument + } + let unfinishedCompletion = readDescriptorCompletions[descriptorKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.readValue(for: descriptor) + readDescriptorCompletions[descriptorKey] = completion + } catch { + completion(.failure(error)) + } + } + + func writeDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let descriptorKey = Int(myDescriptorKey) + guard let descriptor = descriptors[descriptorKey] else { + throw MyError.illegalArgument + } + let data = value.data + let unfinishedCompletion = writeDescriptorCompletions[descriptorKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.writeValue(data, for: descriptor) + writeDescriptorCompletions[descriptorKey] = completion + } catch { + completion(.failure(error)) + } + } + + func didUpdateState(_ state: CBManagerState) { + let completion = setUpCompletion + if state != .unknown && completion != nil { + let myStateArgs = state.toMyArgs() + let myStateNumber = Int64(myStateArgs.rawValue) + let myArgs = MyCentralControllerArgs(myStateNumber: myStateNumber) + completion!(.success(myArgs)) + setUpCompletion = nil + } + let myStateArgs = state.toMyArgs() + let myStateNumber = Int64(myStateArgs.rawValue) + myApi.onStateChanged(myStateNumber: myStateNumber) {} + } + + + func didDiscover(_ peripheral: CBPeripheral, _ advertisementData: [String : Any], _ rssiNumber: NSNumber) { + let peripheralKey = peripheral.hash + if peripherals[peripheralKey] == nil { + peripheral.delegate = myPeripheralDelegate + peripherals[peripheralKey] = peripheral + } + let myPeripheralArgs = peripheral.toMyArgs() + let rssi = rssiNumber.int64Value + let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String + let rawManufacturerSpecificData = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data + var manufacturerSpecificData = [Int64: FlutterStandardTypedData]() + if rawManufacturerSpecificData != nil { + do { + guard let data = rawManufacturerSpecificData else { + throw MyError.illegalArgument + } + guard data.count >= 2 else { + throw MyError.illegalArgument + } + let key = Int64(data[0]) | (Int64(data[1]) << 8) + let bytes = data.count > 2 ? data[2...data.count-1] : Data() + let value = FlutterStandardTypedData(bytes: bytes) + manufacturerSpecificData[key] = value + } catch { + manufacturerSpecificData = [:] + } + } + let rawServiceUUIDs = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID] ?? [] + let serviceUUIDs = rawServiceUUIDs.map { uuid in uuid.uuidString } + let rawServiceData = advertisementData[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] ?? [:] + let elements = rawServiceData.map { (uuid, data) in + let key = uuid.uuidString + let value = FlutterStandardTypedData(bytes: data) + return (key, value) + } + let serviceData = [String?: FlutterStandardTypedData?](uniqueKeysWithValues: elements) + let myAdvertisementArgs = MyAdvertisementArgs(name: name, manufacturerSpecificData: manufacturerSpecificData, serviceUUIDs: serviceUUIDs, serviceData: serviceData) + myApi.onDiscovered(myPeripheralArgs: myPeripheralArgs, rssi: rssi, myAdvertisementArgs: myAdvertisementArgs) {} + } + + func didConnect(_ peripheral: CBPeripheral) { + let peripheralKey = peripheral.hash + let myPeripheralKey = Int64(peripheralKey) + myApi.onPeripheralStateChanged(myPeripheralKey: myPeripheralKey, state: true) {} + guard let completion = connectCompletions.removeValue(forKey: peripheralKey) else { + return + } + completion(.success(())) + } + + func didFailToConnect(_ peripheral: CBPeripheral, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = connectCompletions.removeValue(forKey: peripheralKey) else { + return + } + completion(.failure(error ?? MyError.unknown)) + } + + func didDisconnectPeripheral(_ peripheral: CBPeripheral, _ error: Error?) { + let peripheralKey = peripheral.hash + let myPeripheralKey = Int64(peripheralKey) + let discoverGattCompletion = discoverGattCompletions.removeValue(forKey: peripheralKey) + if discoverGattCompletion != nil { + discoverGattCompletion!(.failure(error ?? MyError.illegalState)) + } + let services = peripheral.services ?? [] + for service in services { + let characteristics = service.characteristics ?? [] + for characteristic in characteristics { + let characteristicKey = characteristic.hash + let readCharacteristicCompletion = readCharacteristicCompletions.removeValue(forKey: characteristicKey) + let writeCharacteristicCompletion = writeCharacteristicCompletions.removeValue(forKey: characteristicKey) + if readCharacteristicCompletion != nil { + readCharacteristicCompletion!(.failure(MyError.illegalState)) + } + if writeCharacteristicCompletion != nil { + writeCharacteristicCompletion!(.failure(MyError.illegalState)) + } + let descriptors = characteristic.descriptors ?? [] + for descriptor in descriptors { + let descriptorKey = descriptor.hash + let readDescriptorCompletion = readDescriptorCompletions.removeValue(forKey: descriptorKey) + let writeDescriptorCompletion = writeDescriptorCompletions.removeValue(forKey: descriptorKey) + if readDescriptorCompletion != nil { + readDescriptorCompletion!(.failure(MyError.illegalState)) + } + if writeDescriptorCompletion != nil { + writeDescriptorCompletion!(.failure(MyError.illegalState)) + } + } + } + } + myApi.onPeripheralStateChanged(myPeripheralKey: myPeripheralKey, state: false) {} + guard let completion = disconnectCompletions.removeValue(forKey: peripheralKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } + + + func didDiscoverServices(_ peripheral: CBPeripheral, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = discoverGattCompletions[peripheralKey] else { + return + } + if error == nil { + var services = peripheral.services ?? [] + if services.isEmpty { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.success(())) + } else { + let service = services.removeFirst() + unfinishedServices[peripheralKey] = services + peripheral.discoverCharacteristics(nil, for: service) + } + } else { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.failure(error!)) + } + } + + func didDiscoverCharacteristics(_ peripheral: CBPeripheral, _ service: CBService, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = discoverGattCompletions[peripheralKey] else { + return + } + if error == nil { + var characteristics = service.characteristics ?? [] + if characteristics.isEmpty { + var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? [] + if services.isEmpty { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.success(())) + } else { + let service = services.removeFirst() + unfinishedServices[peripheralKey] = services + peripheral.discoverCharacteristics(nil, for: service) + } + } else { + let characteristic = characteristics.removeFirst() + unfinishedCharacteristics[peripheralKey] = characteristics + peripheral.discoverDescriptors(for: characteristic) + } + } else { + discoverGattCompletions.removeValue(forKey: peripheralKey) + unfinishedServices.removeValue(forKey: peripheralKey) + completion(.failure(error!)) + } + } + + func didDiscoverDescriptors(_ peripheral: CBPeripheral, _ characteristic: CBCharacteristic, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = discoverGattCompletions[peripheralKey] else { + return + } + if error == nil { + var characteristics = unfinishedCharacteristics.removeValue(forKey: peripheralKey) ?? [] + if (characteristics.isEmpty) { + var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? [] + if services.isEmpty { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.success(())) + } else { + let service = services.removeFirst() + unfinishedServices[peripheralKey] = services + peripheral.discoverCharacteristics(nil, for: service) + } + } else { + let characteristic = characteristics.removeFirst() + unfinishedCharacteristics[peripheralKey] = characteristics + peripheral.discoverDescriptors(for: characteristic) + } + } else { + discoverGattCompletions.removeValue(forKey: peripheralKey) + unfinishedServices.removeValue(forKey: peripheralKey) + unfinishedCharacteristics.removeValue(forKey: peripheralKey) + completion(.failure(error!)) + } + } + + func didUpdateCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) { + let characteristicKey = characteristic.hash + guard let completion = readCharacteristicCompletions.removeValue(forKey: characteristicKey) else { + let myCharacteristicKey = Int64(characteristicKey) + let rawValue = characteristic.value ?? Data() + let value = FlutterStandardTypedData(bytes: rawValue) + myApi.onCharacteristicValueChanged(myCharacteristicKey: myCharacteristicKey, value: value) {} + return + } + if error == nil { + let rawValue = characteristic.value ?? Data() + let value = FlutterStandardTypedData(bytes: rawValue) + completion(.success(value)) + } else { + completion(.failure(error!)) + } + } + + func didWriteCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) { + let characteristicKey = characteristic.hash + guard let completion = writeCharacteristicCompletions.removeValue(forKey: characteristicKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } + + func didUpdateNotificationState(_ characteristic: CBCharacteristic, _ error: Error?) { + let characteristicKey = characteristic.hash + guard let completion = notifyCharacteristicCompletions.removeValue(forKey: characteristicKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } + + func didUpdateDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) { + let descriptorKey = descriptor.hash + guard let completion = readDescriptorCompletions.removeValue(forKey: descriptorKey) else { + return + } + if error == nil { + // TODO: Need to confirm wheather the corresponding descriptor type and value is correct. + let value: FlutterStandardTypedData + let rawValue = descriptor.value + do { + switch descriptor.uuid.uuidString { + case CBUUIDCharacteristicExtendedPropertiesString: + fallthrough + case CBUUIDClientCharacteristicConfigurationString: + fallthrough + case CBUUIDServerCharacteristicConfigurationString: + guard let rawNumber = rawValue as? NSNumber else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawNumber.data) + case CBUUIDCharacteristicUserDescriptionString: + fallthrough + case CBUUIDCharacteristicAggregateFormatString: + guard let rawString = rawValue as? String else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawString.data) + case CBUUIDCharacteristicFormatString: + guard let rawData = rawValue as? Data else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawData) + case CBUUIDL2CAPPSMCharacteristicString: + guard let rawU16 = rawValue as? UInt16 else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawU16.data) + default: + throw MyError.illegalArgument + } + } catch { + value = FlutterStandardTypedData() + } + completion(.success((value))) + } else { + completion(.failure(error!)) + } + } + + func didWriteDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) { + let descriptorKey = descriptor.hash + guard let completion = writeDescriptorCompletions.removeValue(forKey: descriptorKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } +} + +extension CBManagerState { + func toMyArgs() -> MyCentralStateArgs { + switch self { + case .unauthorized: + return .unauthorized + case .poweredOff: + return .poweredOff + case .poweredOn: + return .poweredOn + default: + return .unsupported + } + } +} + +extension CBPeripheral { + func toMyArgs() -> MyPeripheralArgs { + let key = Int64(hash) + let uuid = identifier.uuidString + return MyPeripheralArgs(key: key, uuid: uuid) + } +} + +extension CBService { + func toMyArgs() -> MyGattServiceArgs { + let key = Int64(hash) + let uuid = uuid.uuidString + return MyGattServiceArgs(key: key, uuid: uuid) + } +} + +extension CBCharacteristic { + func toMyArgs() -> MyGattCharacteristicArgs { + let key = Int64(hash) + let uuid = uuid.uuidString + let myPropertyArgses = properties.toMyArgses() + let myPropertyNumbers = myPropertyArgses.map { myPropertyArgs in Int64(myPropertyArgs.rawValue) } + return MyGattCharacteristicArgs(key: key, uuid: uuid, myPropertyNumbers: myPropertyNumbers) + } +} + +extension CBDescriptor { + func toMyArgs() -> MyGattDescriptorArgs { + let key = Int64(hash) + let uuid = uuid.uuidString + return MyGattDescriptorArgs(key: key, uuid: uuid) + } +} + +extension CBCharacteristicProperties { + func toMyArgses() -> [MyGattCharacteristicPropertyArgs] { + var myPropertyArgs = [MyGattCharacteristicPropertyArgs]() + if contains(.read) { + myPropertyArgs.append(.read) + } + if contains(.write) { + myPropertyArgs.append(.write) + } + if contains(.writeWithoutResponse) { + myPropertyArgs.append(.writeWithoutResponse) + } + if contains(.notify) { + myPropertyArgs.append(.notify) + } + if contains(.indicate) { + myPropertyArgs.append(.indicate) + } + return myPropertyArgs + } +} + +extension MyGattCharacteristicWriteTypeArgs { + func toType() -> CBCharacteristicWriteType { + switch self { + case .withResponse: + return .withResponse + case .withoutResponse: + return .withoutResponse + } + } +} + +extension NSNumber { + var data: Data { + var source = self + return Data(bytes: &source, count: MemoryLayout.size) + } +} + +extension String { + var data: Data { + return data(using: String.Encoding.utf8)! + } +} + +extension UInt16 { + var data: Data { + var source = self + return Data(bytes: &source, count: MemoryLayout.size) + } +} diff --git a/bluetooth_low_energy_ios/ios/Classes/MyCentralManagerDelegate.swift b/bluetooth_low_energy_ios/ios/Classes/MyCentralManagerDelegate.swift new file mode 100644 index 0000000..377137d --- /dev/null +++ b/bluetooth_low_energy_ios/ios/Classes/MyCentralManagerDelegate.swift @@ -0,0 +1,38 @@ +// +// MyCentralManagerDelegate.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation +import CoreBluetooth + +class MyCentralManagerDelegate: NSObject, CBCentralManagerDelegate { + private let myCentralController: MyCentralController + + init(_ myCentralController: MyCentralController) { + self.myCentralController = myCentralController + } + + func centralManagerDidUpdateState(_ central: CBCentralManager) { + let state = central.state + myCentralController.didUpdateState(state) + } + + func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { + myCentralController.didDiscover(peripheral, advertisementData, RSSI) + } + + func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { + myCentralController.didConnect(peripheral) + } + + func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { + myCentralController.didFailToConnect(peripheral, error) + } + + func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { + myCentralController.didDisconnectPeripheral(peripheral, error) + } +} diff --git a/bluetooth_low_energy_ios/ios/Classes/MyError.swift b/bluetooth_low_energy_ios/ios/Classes/MyError.swift new file mode 100644 index 0000000..12068c0 --- /dev/null +++ b/bluetooth_low_energy_ios/ios/Classes/MyError.swift @@ -0,0 +1,14 @@ +// +// MyError.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation + +enum MyError: Error { + case illegalArgument + case illegalState + case unknown +} diff --git a/bluetooth_low_energy_ios/ios/Classes/MyPeripheralDelegate.swift b/bluetooth_low_energy_ios/ios/Classes/MyPeripheralDelegate.swift new file mode 100644 index 0000000..5915d9b --- /dev/null +++ b/bluetooth_low_energy_ios/ios/Classes/MyPeripheralDelegate.swift @@ -0,0 +1,49 @@ +// +// MyPeripheralDelegate.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation +import CoreBluetooth + +class MyPeripheralDelegate: NSObject, CBPeripheralDelegate { + private let myCentralController: MyCentralController + + init(_ myCentralController: MyCentralController) { + self.myCentralController = myCentralController + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { + myCentralController.didDiscoverServices(peripheral, error) + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { + myCentralController.didDiscoverCharacteristics(peripheral, service, error) + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didDiscoverDescriptors(peripheral, characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didUpdateCharacteristicValue(characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didWriteCharacteristicValue(characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didUpdateNotificationState(characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) { + myCentralController.didUpdateDescriptorValue(descriptor, error) + } + + func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) { + myCentralController.didWriteDescriptorValue(descriptor, error) + } +} diff --git a/bluetooth_low_energy_ios/ios/bluetooth_low_energy_ios.podspec b/bluetooth_low_energy_ios/ios/bluetooth_low_energy_ios.podspec new file mode 100644 index 0000000..398e1e1 --- /dev/null +++ b/bluetooth_low_energy_ios/ios/bluetooth_low_energy_ios.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint bluetooth_low_energy_ios.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'bluetooth_low_energy_ios' + s.version = '0.0.1' + s.summary = 'A new Flutter plugin project.' + s.description = <<-DESC +A new Flutter plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '9.0' + + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } + s.swift_version = '5.0' +end diff --git a/bluetooth_low_energy_ios/lib/bluetooth_low_energy_ios.dart b/bluetooth_low_energy_ios/lib/bluetooth_low_energy_ios.dart new file mode 100644 index 0000000..f7244f1 --- /dev/null +++ b/bluetooth_low_energy_ios/lib/bluetooth_low_energy_ios.dart @@ -0,0 +1,9 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'src/my_central_controller.dart'; + +abstract class BluetoothLowEnergyiOS { + static void registerWith() { + CentralController.instance = MyCentralController(); + } +} diff --git a/bluetooth_low_energy_ios/lib/src/my_api.g.dart b/bluetooth_low_energy_ios/lib/src/my_api.g.dart new file mode 100644 index 0000000..a0717a6 --- /dev/null +++ b/bluetooth_low_energy_ios/lib/src/my_api.g.dart @@ -0,0 +1,736 @@ +// Autogenerated from Pigeon (v10.1.6), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +enum MyCentralStateArgs { + unknown, + unsupported, + unauthorized, + poweredOff, + poweredOn, +} + +enum MyGattCharacteristicPropertyArgs { + read, + write, + writeWithoutResponse, + notify, + indicate, +} + +enum MyGattCharacteristicWriteTypeArgs { + withResponse, + withoutResponse, +} + +class MyCentralControllerArgs { + MyCentralControllerArgs({ + required this.myStateNumber, + }); + + int myStateNumber; + + Object encode() { + return [ + myStateNumber, + ]; + } + + static MyCentralControllerArgs decode(Object result) { + result as List; + return MyCentralControllerArgs( + myStateNumber: result[0]! as int, + ); + } +} + +class MyPeripheralArgs { + MyPeripheralArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyPeripheralArgs decode(Object result) { + result as List; + return MyPeripheralArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class MyAdvertisementArgs { + MyAdvertisementArgs({ + this.name, + required this.manufacturerSpecificData, + required this.serviceUUIDs, + required this.serviceData, + }); + + String? name; + + Map manufacturerSpecificData; + + List serviceUUIDs; + + Map serviceData; + + Object encode() { + return [ + name, + manufacturerSpecificData, + serviceUUIDs, + serviceData, + ]; + } + + static MyAdvertisementArgs decode(Object result) { + result as List; + return MyAdvertisementArgs( + name: result[0] as String?, + manufacturerSpecificData: (result[1] as Map?)!.cast(), + serviceUUIDs: (result[2] as List?)!.cast(), + serviceData: (result[3] as Map?)!.cast(), + ); + } +} + +class MyGattServiceArgs { + MyGattServiceArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyGattServiceArgs decode(Object result) { + result as List; + return MyGattServiceArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class MyGattCharacteristicArgs { + MyGattCharacteristicArgs({ + required this.key, + required this.uuid, + required this.myPropertyNumbers, + }); + + int key; + + String uuid; + + List myPropertyNumbers; + + Object encode() { + return [ + key, + uuid, + myPropertyNumbers, + ]; + } + + static MyGattCharacteristicArgs decode(Object result) { + result as List; + return MyGattCharacteristicArgs( + key: result[0]! as int, + uuid: result[1]! as String, + myPropertyNumbers: (result[2] as List?)!.cast(), + ); + } +} + +class MyGattDescriptorArgs { + MyGattDescriptorArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyGattDescriptorArgs decode(Object result) { + result as List; + return MyGattDescriptorArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class _MyCentralControllerHostApiCodec extends StandardMessageCodec { + const _MyCentralControllerHostApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is MyCentralControllerArgs) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else if (value is MyGattCharacteristicArgs) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else if (value is MyGattDescriptorArgs) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is MyGattServiceArgs) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return MyCentralControllerArgs.decode(readValue(buffer)!); + case 129: + return MyGattCharacteristicArgs.decode(readValue(buffer)!); + case 130: + return MyGattDescriptorArgs.decode(readValue(buffer)!); + case 131: + return MyGattServiceArgs.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class MyCentralControllerHostApi { + /// Constructor for [MyCentralControllerHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + MyCentralControllerHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _MyCentralControllerHostApiCodec(); + + Future setUp() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.setUp', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as MyCentralControllerArgs?)!; + } + } + + Future tearDown() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.tearDown', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future startDiscovery() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.startDiscovery', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future stopDiscovery() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.stopDiscovery', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future connect(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.connect', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future disconnect(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.disconnect', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future discoverGATT(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.discoverGATT', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future> getServices(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.getServices', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getCharacteristics(int arg_myServiceKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.getCharacteristics', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myServiceKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getDescriptors(int arg_myCharacteristicKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.getDescriptors', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myCharacteristicKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future readCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.readCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as Uint8List?)!; + } + } + + Future writeCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, Uint8List arg_value, int arg_myTypeNumber) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.writeCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey, arg_value, arg_myTypeNumber]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future notifyCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, bool arg_state) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.notifyCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey, arg_state]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future readDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.readDescriptor', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myDescriptorKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as Uint8List?)!; + } + } + + Future writeDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey, Uint8List arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.writeDescriptor', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myDescriptorKey, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } +} + +class _MyCentralControllerFlutterApiCodec extends StandardMessageCodec { + const _MyCentralControllerFlutterApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is MyAdvertisementArgs) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else if (value is MyPeripheralArgs) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return MyAdvertisementArgs.decode(readValue(buffer)!); + case 129: + return MyPeripheralArgs.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class MyCentralControllerFlutterApi { + static const MessageCodec codec = _MyCentralControllerFlutterApiCodec(); + + void onStateChanged(int myStateNumber); + + void onDiscovered(MyPeripheralArgs myPeripheralArgs, int rssi, MyAdvertisementArgs myAdvertisementArgs); + + void onPeripheralStateChanged(int myPeripheralKey, bool state); + + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value); + + static void setup(MyCentralControllerFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onStateChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onStateChanged was null.'); + final List args = (message as List?)!; + final int? arg_myStateNumber = (args[0] as int?); + assert(arg_myStateNumber != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onStateChanged was null, expected non-null int.'); + api.onStateChanged(arg_myStateNumber!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onDiscovered', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onDiscovered was null.'); + final List args = (message as List?)!; + final MyPeripheralArgs? arg_myPeripheralArgs = (args[0] as MyPeripheralArgs?); + assert(arg_myPeripheralArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyPeripheralArgs.'); + final int? arg_rssi = (args[1] as int?); + assert(arg_rssi != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null int.'); + final MyAdvertisementArgs? arg_myAdvertisementArgs = (args[2] as MyAdvertisementArgs?); + assert(arg_myAdvertisementArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyAdvertisementArgs.'); + api.onDiscovered(arg_myPeripheralArgs!, arg_rssi!, arg_myAdvertisementArgs!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onPeripheralStateChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onPeripheralStateChanged was null.'); + final List args = (message as List?)!; + final int? arg_myPeripheralKey = (args[0] as int?); + assert(arg_myPeripheralKey != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null int.'); + final bool? arg_state = (args[1] as bool?); + assert(arg_state != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null bool.'); + api.onPeripheralStateChanged(arg_myPeripheralKey!, arg_state!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onCharacteristicValueChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null.'); + final List args = (message as List?)!; + final int? arg_myCharacteristicKey = (args[0] as int?); + assert(arg_myCharacteristicKey != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null int.'); + final Uint8List? arg_value = (args[1] as Uint8List?); + assert(arg_value != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null Uint8List.'); + api.onCharacteristicValueChanged(arg_myCharacteristicKey!, arg_value!); + return; + }); + } + } + } +} diff --git a/bluetooth_low_energy_ios/lib/src/my_central_controller.dart b/bluetooth_low_energy_ios/lib/src/my_central_controller.dart new file mode 100644 index 0000000..6444c3a --- /dev/null +++ b/bluetooth_low_energy_ios/lib/src/my_central_controller.dart @@ -0,0 +1,357 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_characteristic.dart'; +import 'my_gatt_descriptor.dart'; +import 'my_gatt_service.dart'; +import 'my_peripheral.dart'; + +class MyCentralController extends CentralController + implements MyCentralControllerFlutterApi { + MyCentralController() + : _myApi = MyCentralControllerHostApi(), + _stateChangedController = StreamController.broadcast(), + _discoveredController = StreamController.broadcast(), + _peripheralStateChangedController = StreamController.broadcast(), + _characteristicValueChangedController = StreamController.broadcast(), + _myPeripherals = {}, + _myServices = {}, + _myCharacteristics = {}, + _myDescriptors = {}, + _state = CentralState.unknown; + + final MyCentralControllerHostApi _myApi; + final StreamController _stateChangedController; + final StreamController _discoveredController; + final StreamController + _peripheralStateChangedController; + final StreamController + _characteristicValueChangedController; + final Map _myPeripherals; + final Map _myServices; + final Map _myCharacteristics; + final Map _myDescriptors; + + CentralState _state; + @override + CentralState get state => _state; + + @override + Stream get stateChanged => + _stateChangedController.stream; + @override + Stream get discovered => + _discoveredController.stream; + @override + Stream get peripheralStateChanged => + _peripheralStateChangedController.stream; + @override + Stream + get characteristicValueChanged => + _characteristicValueChangedController.stream; + + Future _throwWithState(CentralState state) async { + if (this.state == state) { + throw BluetoothLowEnergyError('$state is unexpected.'); + } + } + + Future _throwWithoutState(CentralState state) async { + if (this.state != state) { + throw BluetoothLowEnergyError( + '$state is expected, but current state is ${this.state}.', + ); + } + } + + @override + Future setUp() async { + await _throwWithoutState(CentralState.unknown); + final args = await _myApi.setUp(); + final myStateArgs = MyCentralStateArgs.values[args.myStateNumber]; + _state = myStateArgs.toState(); + MyCentralControllerFlutterApi.setup(this); + } + + @override + Future tearDown() async { + await _throwWithState(CentralState.unknown); + await _myApi.tearDown(); + MyCentralControllerFlutterApi.setup(null); + _myPeripherals.clear(); + _myServices.clear(); + _myCharacteristics.clear(); + _myDescriptors.clear(); + _state = CentralState.unknown; + } + + @override + Future startDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _myApi.startDiscovery(); + } + + @override + Future stopDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _myApi.stopDiscovery(); + } + + @override + Future connect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.connect(myPeripheral.hashCode); + } + + @override + Future disconnect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.disconnect(myPeripheral.hashCode); + } + + @override + Future discoverGATT(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.discoverGATT(myPeripheral.hashCode); + } + + @override + Future> getServices(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final myServiceArgses = await _myApi.getServices(myPeripheral.hashCode); + return myServiceArgses + .cast() + .map( + (myServiceArgs) => _myServices.putIfAbsent( + myServiceArgs.key, + () => MyGattService.fromMyArgs( + myPeripheral, + myServiceArgs, + ), + ), + ) + .toList(); + } + + @override + Future> getCharacteristics( + GattService service, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myService = service as MyGattService; + final myCharactersiticArgses = await _myApi.getCharacteristics( + myService.hashCode, + ); + return myCharactersiticArgses + .cast() + .map( + (myCharacteristicArgs) => _myCharacteristics.putIfAbsent( + myCharacteristicArgs.key, + () => MyGattCharacteristic.fromMyArgs( + myService, + myCharacteristicArgs, + ), + ), + ) + .toList(); + } + + @override + Future> getDescriptors( + GattCharacteristic characteristic, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myDescriptorArgses = await _myApi.getDescriptors( + myCharacteristic.hashCode, + ); + return myDescriptorArgses + .cast() + .map( + (myDescriptorArgs) => _myDescriptors.putIfAbsent( + myDescriptorArgs.key, + () => MyGattDescriptor.fromMyArgs( + myCharacteristic, + myDescriptorArgs, + ), + ), + ) + .toList(); + } + + @override + Future readCharacteristic( + GattCharacteristic characteristic, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final value = await _myApi.readCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + ); + return value; + } + + @override + Future writeCharacteristic( + GattCharacteristic characteristic, { + required Uint8List value, + required GattCharacteristicWriteType type, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final typeArgs = type.toMyArgs(); + final typeNumber = typeArgs.index; + await _myApi.writeCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + value, + typeNumber, + ); + } + + @override + Future notifyCharacteristic( + GattCharacteristic characteristic, { + required bool state, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + await _myApi.notifyCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + state, + ); + } + + @override + Future readDescriptor(GattDescriptor descriptor) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final myCharacteristic = myDescriptor.myCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final value = await _myApi.readDescriptor( + myPeripheral.hashCode, + myDescriptor.hashCode, + ); + return value; + } + + @override + Future writeDescriptor( + GattDescriptor descriptor, { + required Uint8List value, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final myCharacteristic = myDescriptor.myCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + await _myApi.writeDescriptor( + myPeripheral.hashCode, + myDescriptor.hashCode, + value, + ); + } + + @override + void onStateChanged(int myStateNumber) { + final myStateArgs = MyCentralStateArgs.values[myStateNumber]; + final state = myStateArgs.toState(); + if (_state == state) { + return; + } + _state = state; + final eventArgs = CentralStateChangedEventArgs(state); + _stateChangedController.add(eventArgs); + } + + @override + void onDiscovered( + MyPeripheralArgs myPeripheralArgs, + int rssi, + MyAdvertisementArgs myAdvertisementArgs, + ) { + final myPeripheral = _myPeripherals.putIfAbsent( + myPeripheralArgs.key, + () => MyPeripheral.fromMyArgs(myPeripheralArgs), + ); + final advertisement = myAdvertisementArgs.toAdvertisement(); + final eventArgs = CentralDiscoveredEventArgs( + myPeripheral, + rssi, + advertisement, + ); + _discoveredController.add(eventArgs); + } + + @override + void onPeripheralStateChanged(int myPeripheralKey, bool state) { + final myPeripheral = _myPeripherals[myPeripheralKey]; + if (myPeripheral == null) { + return; + } + final eventArgs = PeripheralStateChangedEventArgs(myPeripheral, state); + _peripheralStateChangedController.add(eventArgs); + } + + @override + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value) { + final myCharacteristic = + _myCharacteristics[myCharacteristicKey] as MyGattCharacteristic; + final eventArgs = GattCharacteristicValueChangedEventArgs( + myCharacteristic, + value, + ); + _characteristicValueChangedController.add(eventArgs); + } +} + +extension on MyAdvertisementArgs { + Advertisement toAdvertisement() { + final serviceUUIDs = this + .serviceUUIDs + .cast() + .map((uuid) => UUID.fromString(uuid)) + .toList(); + final serviceData = this.serviceData.cast().map( + (uuid, data) { + final key = UUID.fromString(uuid); + final value = data; + return MapEntry(key, value); + }, + ); + return Advertisement( + name: name, + manufacturerSpecificData: manufacturerSpecificData.cast(), + serviceUUIDs: serviceUUIDs, + serviceData: serviceData, + ); + } +} + +extension on MyCentralStateArgs { + CentralState toState() { + return CentralState.values[index]; + } +} + +extension on GattCharacteristicWriteType { + MyGattCharacteristicWriteTypeArgs toMyArgs() { + return MyGattCharacteristicWriteTypeArgs.values[index]; + } +} diff --git a/bluetooth_low_energy_ios/lib/src/my_gatt_characteristic.dart b/bluetooth_low_energy_ios/lib/src/my_gatt_characteristic.dart new file mode 100644 index 0000000..811fb23 --- /dev/null +++ b/bluetooth_low_energy_ios/lib/src/my_gatt_characteristic.dart @@ -0,0 +1,42 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_service.dart'; +import 'my_object.dart'; + +class MyGattCharacteristic extends MyObject implements GattCharacteristic { + final MyGattService myService; + @override + final UUID uuid; + @override + final List properties; + + MyGattCharacteristic( + super.hashCode, + this.myService, + this.uuid, + this.properties, + ); + + factory MyGattCharacteristic.fromMyArgs( + MyGattService myService, + MyGattCharacteristicArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + final properties = myArgs.myPropertyNumbers.cast().map( + (myPropertyNumber) { + final myPropertyArgs = + MyGattCharacteristicPropertyArgs.values[myPropertyNumber]; + return myPropertyArgs.toProperty(); + }, + ).toList(); + return MyGattCharacteristic(hashCode, myService, uuid, properties); + } +} + +extension on MyGattCharacteristicPropertyArgs { + GattCharacteristicProperty toProperty() { + return GattCharacteristicProperty.values[index]; + } +} diff --git a/bluetooth_low_energy_ios/lib/src/my_gatt_descriptor.dart b/bluetooth_low_energy_ios/lib/src/my_gatt_descriptor.dart new file mode 100644 index 0000000..6798f4a --- /dev/null +++ b/bluetooth_low_energy_ios/lib/src/my_gatt_descriptor.dart @@ -0,0 +1,22 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_characteristic.dart'; +import 'my_object.dart'; + +class MyGattDescriptor extends MyObject implements GattDescriptor { + final MyGattCharacteristic myCharacteristic; + @override + final UUID uuid; + + MyGattDescriptor(super.hashCode, this.myCharacteristic, this.uuid); + + factory MyGattDescriptor.fromMyArgs( + MyGattCharacteristic myCharacteristic, + MyGattDescriptorArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyGattDescriptor(hashCode, myCharacteristic, uuid); + } +} diff --git a/bluetooth_low_energy_ios/lib/src/my_gatt_service.dart b/bluetooth_low_energy_ios/lib/src/my_gatt_service.dart new file mode 100644 index 0000000..37babdb --- /dev/null +++ b/bluetooth_low_energy_ios/lib/src/my_gatt_service.dart @@ -0,0 +1,22 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_object.dart'; +import 'my_peripheral.dart'; + +class MyGattService extends MyObject implements GattService { + final MyPeripheral myPeripheral; + @override + final UUID uuid; + + MyGattService(super.hashCode, this.myPeripheral, this.uuid); + + factory MyGattService.fromMyArgs( + MyPeripheral myPeripheral, + MyGattServiceArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyGattService(hashCode, myPeripheral, uuid); + } +} diff --git a/bluetooth_low_energy_ios/lib/src/my_object.dart b/bluetooth_low_energy_ios/lib/src/my_object.dart new file mode 100644 index 0000000..2b33805 --- /dev/null +++ b/bluetooth_low_energy_ios/lib/src/my_object.dart @@ -0,0 +1,11 @@ +abstract class MyObject { + @override + final int hashCode; + + MyObject(this.hashCode); + + @override + bool operator ==(Object other) { + return other is MyObject && other.hashCode == hashCode; + } +} diff --git a/bluetooth_low_energy_ios/lib/src/my_peripheral.dart b/bluetooth_low_energy_ios/lib/src/my_peripheral.dart new file mode 100644 index 0000000..7be1bd3 --- /dev/null +++ b/bluetooth_low_energy_ios/lib/src/my_peripheral.dart @@ -0,0 +1,17 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_object.dart'; + +class MyPeripheral extends MyObject implements Peripheral { + @override + final UUID uuid; + + MyPeripheral(super.hashCode, this.uuid); + + factory MyPeripheral.fromMyArgs(MyPeripheralArgs myArgs) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyPeripheral(hashCode, uuid); + } +} diff --git a/bluetooth_low_energy_ios/my_api.dart b/bluetooth_low_energy_ios/my_api.dart new file mode 100644 index 0000000..ad48f71 --- /dev/null +++ b/bluetooth_low_energy_ios/my_api.dart @@ -0,0 +1,140 @@ +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/src/my_api.g.dart', + dartOptions: DartOptions(), + swiftOut: 'ios/Classes/MyApi.g.swift', + swiftOptions: SwiftOptions(), + ), +) +@HostApi() +abstract class MyCentralControllerHostApi { + @async + MyCentralControllerArgs setUp(); + void tearDown(); + void startDiscovery(); + void stopDiscovery(); + @async + void connect(int myPeripheralKey); + @async + void disconnect(int myPeripheralKey); + @async + void discoverGATT(int myPeripheralKey); + List getServices(int myPeripheralKey); + List getCharacteristics(int myServiceKey); + List getDescriptors(int myCharacteristicKey); + @async + Uint8List readCharacteristic(int myPeripheralKey, int myCharacteristicKey); + @async + void writeCharacteristic( + int myPeripheralKey, + int myCharacteristicKey, + Uint8List value, + int myTypeNumber, + ); + @async + void notifyCharacteristic( + int myPeripheralKey, + int myCharacteristicKey, + bool state, + ); + @async + Uint8List readDescriptor(int myPeripheralKey, int myDescriptorKey); + @async + void writeDescriptor( + int myPeripheralKey, + int myDescriptorKey, + Uint8List value, + ); +} + +@FlutterApi() +abstract class MyCentralControllerFlutterApi { + void onStateChanged(int myStateNumber); + void onDiscovered( + MyPeripheralArgs myPeripheralArgs, + int rssi, + MyAdvertisementArgs myAdvertisementArgs, + ); + void onPeripheralStateChanged(int myPeripheralKey, bool state); + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value); +} + +class MyCentralControllerArgs { + final int myStateNumber; + + MyCentralControllerArgs(this.myStateNumber); +} + +class MyPeripheralArgs { + final int key; + final String uuid; + + MyPeripheralArgs(this.key, this.uuid); +} + +class MyAdvertisementArgs { + final String? name; + final Map manufacturerSpecificData; + final List serviceUUIDs; + final Map serviceData; + + MyAdvertisementArgs( + this.name, + this.manufacturerSpecificData, + this.serviceUUIDs, + this.serviceData, + ); +} + +class MyGattServiceArgs { + final int key; + final String uuid; + + MyGattServiceArgs(this.key, this.uuid); +} + +class MyGattCharacteristicArgs { + final int key; + final String uuid; + final List myPropertyNumbers; + + MyGattCharacteristicArgs( + this.key, + this.uuid, + this.myPropertyNumbers, + ); +} + +class MyGattDescriptorArgs { + final int key; + final String uuid; + + MyGattDescriptorArgs(this.key, this.uuid); +} + +enum MyCentralStateArgs { + unknown, + unsupported, + unauthorized, + poweredOff, + poweredOn, +} + +enum MyGattCharacteristicPropertyArgs { + read, + write, + writeWithoutResponse, + notify, + indicate, +} + +enum MyGattCharacteristicWriteTypeArgs { + // Write with response + withResponse, + // Write without response + withoutResponse, + // Write with response and waiting for confirmation + // reliable, +} diff --git a/bluetooth_low_energy_ios/pubspec.yaml b/bluetooth_low_energy_ios/pubspec.yaml new file mode 100644 index 0000000..b13fd33 --- /dev/null +++ b/bluetooth_low_energy_ios/pubspec.yaml @@ -0,0 +1,27 @@ +name: bluetooth_low_energy_ios +description: iOS implementation of the bluetooth_low_energy plugin. +version: 2.0.0 +homepage: https://github.com/yanshouwang/bluetooth_low_energy + +environment: + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + bluetooth_low_energy_platform_interface: + path: ../bluetooth_low_energy_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + pigeon: ^10.1.6 + +flutter: + plugin: + platforms: + ios: + pluginClass: BluetoothLowEnergyiOS + dartPluginClass: BluetoothLowEnergyiOS diff --git a/bluetooth_low_energy_linux/.gitignore b/bluetooth_low_energy_linux/.gitignore new file mode 100644 index 0000000..96486fd --- /dev/null +++ b/bluetooth_low_energy_linux/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/bluetooth_low_energy_linux/.metadata b/bluetooth_low_energy_linux/.metadata new file mode 100644 index 0000000..7df7b20 --- /dev/null +++ b/bluetooth_low_energy_linux/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: linux + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/bluetooth_low_energy_linux/CHANGELOG.md b/bluetooth_low_energy_linux/CHANGELOG.md new file mode 100644 index 0000000..e510273 --- /dev/null +++ b/bluetooth_low_energy_linux/CHANGELOG.md @@ -0,0 +1,4 @@ +## 2.0.0 + +- Rewrite the whole project with federated plugins. +- Support macOS and Linux. diff --git a/bluetooth_low_energy_linux/LICENSE b/bluetooth_low_energy_linux/LICENSE new file mode 100644 index 0000000..515ed4b --- /dev/null +++ b/bluetooth_low_energy_linux/LICENSE @@ -0,0 +1,21 @@ +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. \ No newline at end of file diff --git a/bluetooth_low_energy_linux/README.md b/bluetooth_low_energy_linux/README.md new file mode 100644 index 0000000..f305006 --- /dev/null +++ b/bluetooth_low_energy_linux/README.md @@ -0,0 +1,15 @@ +# bluetooth_low_energy_linux + +The Linux implementation of [`bluetooth_low_energy`][1]. + +## Usage + +This package is [endorsed][2], which means you can simply use `bluetooth_low_energy` +normally. This package will be automatically included in your app when you do, +so you do not need to add it to your `pubspec.yaml`. + +However, if you `import` this package to use any of its APIs directly, you +should add it to your `pubspec.yaml` as usual. + +[1]: https://pub.dev/packages/bluetooth_low_energy +[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin diff --git a/bluetooth_low_energy_linux/analysis_options.yaml b/bluetooth_low_energy_linux/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/bluetooth_low_energy_linux/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/bluetooth_low_energy_linux/lib/bluetooth_low_energy_linux.dart b/bluetooth_low_energy_linux/lib/bluetooth_low_energy_linux.dart new file mode 100644 index 0000000..4d0ee64 --- /dev/null +++ b/bluetooth_low_energy_linux/lib/bluetooth_low_energy_linux.dart @@ -0,0 +1,9 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'src/my_central_controller.dart'; + +abstract class BluetoothLowEnergyLinux { + static void registerWith() { + CentralController.instance = MyCentralController(); + } +} diff --git a/bluetooth_low_energy_linux/lib/src/my_bluez.dart b/bluetooth_low_energy_linux/lib/src/my_bluez.dart new file mode 100644 index 0000000..30de865 --- /dev/null +++ b/bluetooth_low_energy_linux/lib/src/my_bluez.dart @@ -0,0 +1,81 @@ +import 'dart:typed_data'; + +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; +import 'package:bluez/bluez.dart'; + +extension MyBlueZAdapter on BlueZAdapter { + CentralState get state { + return powered ? CentralState.poweredOn : CentralState.poweredOff; + } +} + +extension MyBlueZDevice on BlueZDevice { + BlueZUUID get uuid { + final node = address.replaceAll(':', ''); + // We don't know the timestamp of the bluetooth device, use nil UUID as prefix. + return BlueZUUID.fromString("00000000-0000-0000-$node"); + } + + Advertisement get advertisement { + final manufacturerSpecificData = manufacturerData.map((key, value) { + final id = key.id; + final data = Uint8List.fromList(value); + return MapEntry(id, data); + }); + final serviceUUIDs = uuids.map((uuid) => uuid.toUUID()).toList(); + final serviceData = this.serviceData.map((uuid, data) { + final key = uuid.toUUID(); + final value = Uint8List.fromList(data); + return MapEntry(key, value); + }); + return Advertisement( + name: name, + manufacturerSpecificData: manufacturerSpecificData, + serviceUUIDs: serviceUUIDs, + serviceData: serviceData, + ); + } +} + +extension MyBlueZUUID on BlueZUUID { + UUID toUUID() => UUID(value); +} + +extension MyBlueZGattCharacteristic on BlueZGattCharacteristic { + List get properties => flags + .map((e) => e.toProperty()) + .whereType() + .toList(); +} + +extension MyBlueZGattCharacteristicFlag on BlueZGattCharacteristicFlag { + GattCharacteristicProperty? toProperty() { + switch (this) { + case BlueZGattCharacteristicFlag.read: + return GattCharacteristicProperty.read; + case BlueZGattCharacteristicFlag.write: + return GattCharacteristicProperty.write; + case BlueZGattCharacteristicFlag.writeWithoutResponse: + return GattCharacteristicProperty.writeWithoutResponse; + case BlueZGattCharacteristicFlag.notify: + return GattCharacteristicProperty.notify; + case BlueZGattCharacteristicFlag.indicate: + return GattCharacteristicProperty.indicate; + default: + return null; + } + } +} + +extension MyGattCharacteristicWriteType on GattCharacteristicWriteType { + BlueZGattCharacteristicWriteType toBlueZ() { + switch (this) { + case GattCharacteristicWriteType.withResponse: + return BlueZGattCharacteristicWriteType.request; + case GattCharacteristicWriteType.withoutResponse: + return BlueZGattCharacteristicWriteType.command; + default: + throw UnimplementedError(); + } + } +} diff --git a/bluetooth_low_energy_linux/lib/src/my_central_controller.dart b/bluetooth_low_energy_linux/lib/src/my_central_controller.dart new file mode 100644 index 0000000..d71f663 --- /dev/null +++ b/bluetooth_low_energy_linux/lib/src/my_central_controller.dart @@ -0,0 +1,426 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; +import 'package:bluez/bluez.dart'; + +import 'my_bluez.dart'; +import 'my_gatt_characteristic.dart'; +import 'my_gatt_descriptor.dart'; +import 'my_gatt_service.dart'; +import 'my_peripheral.dart'; + +class MyCentralController extends CentralController { + MyCentralController() + : _client = BlueZClient(), + _stateChangedController = StreamController.broadcast(), + _discoveredController = StreamController.broadcast(), + _peripheralStateChangedController = StreamController.broadcast(), + _characteristicValueChangedController = StreamController.broadcast(), + _servicesResolvedController = StreamController.broadcast(), + _devicePropertiesChangedSubscriptions = {}, + _characteristicPropertiesChangedSubscriptions = {}, + _myPeripherals = {}, + _myServices = {}, + _myCharacteristics = {}, + _myDescriptors = {}, + _state = CentralState.unknown; + + final BlueZClient _client; + final StreamController _stateChangedController; + final StreamController _discoveredController; + final StreamController + _peripheralStateChangedController; + final StreamController + _characteristicValueChangedController; + final StreamController _servicesResolvedController; + final Map>> + _devicePropertiesChangedSubscriptions; + final Map>> + _characteristicPropertiesChangedSubscriptions; + final Map _myPeripherals; + final Map _myServices; + final Map _myCharacteristics; + final Map _myDescriptors; + + BlueZAdapter get _adapter => _client.adapters.first; + CentralState _state; + @override + CentralState get state => _state; + + @override + Stream get stateChanged => + _stateChangedController.stream; + @override + Stream get discovered => + _discoveredController.stream; + @override + Stream get peripheralStateChanged => + _peripheralStateChangedController.stream; + @override + Stream + get characteristicValueChanged => + _characteristicValueChangedController.stream; + Stream get _servicesResolved => _servicesResolvedController.stream; + + late StreamSubscription> _adapterPropertiesChangedSubscription; + late StreamSubscription _deviceAddedSubscription; + late StreamSubscription _deviceRemovedSubscription; + + Future _throwWithState(CentralState state) async { + if (this.state == state) { + throw BluetoothLowEnergyError('$state is unexpected.'); + } + } + + Future _throwWithoutState(CentralState state) async { + if (this.state != state) { + throw BluetoothLowEnergyError( + '$state is expected, but current state is ${this.state}.', + ); + } + } + + @override + Future setUp() async { + await _throwWithoutState(CentralState.unknown); + await _client.connect(); + _state = + _client.adapters.isEmpty ? CentralState.unsupported : _adapter.state; + if (_state == CentralState.unsupported) { + return; + } + for (var device in _client.devices) { + if (device.adapter != _adapter) { + continue; + } + _beginDevicePropertiesChangedListener(device); + } + _adapterPropertiesChangedSubscription = _adapter.propertiesChanged.listen( + _onAdapterPropertiesChanged, + ); + _deviceAddedSubscription = _client.deviceAdded.listen(_onDeviceAdded); + _deviceRemovedSubscription = _client.deviceRemoved.listen(_onDeviceRemoved); + } + + @override + Future tearDown() async { + await _throwWithState(CentralState.unknown); + if (_state != CentralState.unsupported && _adapter.discovering) { + await _adapter.stopDiscovery(); + } + for (var myPeripheral in _myPeripherals.values) { + final device = myPeripheral.device; + if (device.connected) { + await device.disconnect(); + } + } + _myPeripherals.clear(); + _myServices.clear(); + _myCharacteristics.clear(); + _myDescriptors.clear(); + for (var device in _client.devices) { + if (device.adapter != _adapter) { + continue; + } + _endDevicePropertiesChangedListener(device); + } + _adapterPropertiesChangedSubscription.cancel(); + _deviceAddedSubscription.cancel(); + _deviceRemovedSubscription.cancel(); + await _client.close(); + _state = CentralState.unknown; + } + + @override + Future startDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _adapter.startDiscovery(); + } + + @override + Future stopDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _adapter.stopDiscovery(); + } + + @override + Future connect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final device = myPeripheral.device; + await device.connect(); + } + + @override + Future disconnect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final device = myPeripheral.device; + await device.disconnect(); + } + + @override + Future discoverGATT(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final device = myPeripheral.device; + if (!device.connected) { + throw BluetoothLowEnergyError('Peripheral is disconnected.'); + } + if (device.servicesResolved) { + return; + } + await _servicesResolved.firstWhere( + (hashCode) => hashCode == peripheral.hashCode, + ); + } + + @override + Future> getServices(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final blueZDevice = myPeripheral.device; + return blueZDevice.gattServices + .map( + (service) => _myServices.putIfAbsent( + service.hashCode, + () => MyGattService(service), + ), + ) + .toList(); + } + + @override + Future> getCharacteristics( + GattService service, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myService = service as MyGattService; + final blueZService = myService.service; + return blueZService.characteristics + .map( + (characteristic) => _myCharacteristics.putIfAbsent( + characteristic.hashCode, + () => MyGattCharacteristic(characteristic), + ), + ) + .toList(); + } + + @override + Future> getDescriptors( + GattCharacteristic characteristic, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final blueZCharacteristic = myCharacteristic.characteristic; + return blueZCharacteristic.descriptors + .map( + (descriptor) => _myDescriptors.putIfAbsent( + descriptor.hashCode, + () => MyGattDescriptor(descriptor), + ), + ) + .toList(); + } + + @override + Future readCharacteristic( + GattCharacteristic characteristic, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final blueZCharacteristic = myCharacteristic.characteristic; + final blueZValue = await blueZCharacteristic.readValue(); + return Uint8List.fromList(blueZValue); + } + + @override + Future writeCharacteristic( + GattCharacteristic characteristic, { + required Uint8List value, + required GattCharacteristicWriteType type, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final blueZCharacteristic = myCharacteristic.characteristic; + await blueZCharacteristic.writeValue( + value, + type: type.toBlueZ(), + ); + } + + @override + Future notifyCharacteristic( + GattCharacteristic characteristic, { + required bool state, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final blueZCharacteristic = myCharacteristic.characteristic; + if (state) { + await blueZCharacteristic.startNotify(); + } else { + await blueZCharacteristic.stopNotify(); + } + } + + @override + Future readDescriptor(GattDescriptor descriptor) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final blueZDescriptor = myDescriptor.descriptor; + final blueZValue = await blueZDescriptor.readValue(); + return Uint8List.fromList(blueZValue); + } + + @override + Future writeDescriptor( + GattDescriptor descriptor, { + required Uint8List value, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final blueZDescriptor = myDescriptor.descriptor; + await blueZDescriptor.writeValue(value); + } + + void _onAdapterPropertiesChanged(List properties) { + for (var property in properties) { + switch (property) { + case 'Powered': + final state = _adapter.state; + if (_state == state) { + return; + } + _state = state; + final eventArgs = CentralStateChangedEventArgs(state); + _stateChangedController.add(eventArgs); + break; + default: + break; + } + } + } + + void _onDeviceAdded(BlueZDevice device) { + if (device.adapter != _adapter) { + return; + } + _onDiscovered(device); + _beginDevicePropertiesChangedListener(device); + } + + void _onDeviceRemoved(BlueZDevice device) { + if (device.adapter != _adapter) { + return; + } + _endDevicePropertiesChangedListener(device); + } + + void _onDiscovered(BlueZDevice device) { + final myPeripheral = _myPeripherals.putIfAbsent( + device.hashCode, + () => MyPeripheral(device), + ); + final rssi = device.rssi; + final advertisement = device.advertisement; + final eventArgs = CentralDiscoveredEventArgs( + myPeripheral, + rssi, + advertisement, + ); + _discoveredController.add(eventArgs); + } + + void _beginDevicePropertiesChangedListener(BlueZDevice device) { + for (var service in device.gattServices) { + for (var characteristic in service.characteristics) { + _beginCharacteristicPropertiesChangedListener(characteristic); + } + } + final subscription = device.propertiesChanged.listen((properties) { + for (var property in properties) { + switch (property) { + case 'RSSI': + _onDiscovered(device); + break; + case 'Connected': + final myPeripheral = + _myPeripherals[device.hashCode] as MyPeripheral; + final state = device.connected; + final eventArgs = PeripheralStateChangedEventArgs( + myPeripheral, + state, + ); + _peripheralStateChangedController.add(eventArgs); + break; + case 'UUIDs': + break; + case 'ServicesResolved': + if (device.servicesResolved) { + for (var service in device.gattServices) { + for (var characteristic in service.characteristics) { + _beginCharacteristicPropertiesChangedListener(characteristic); + } + } + _servicesResolvedController.add(device.hashCode); + } + break; + default: + break; + } + } + }); + _devicePropertiesChangedSubscriptions[device.hashCode] = subscription; + } + + void _endDevicePropertiesChangedListener(BlueZDevice device) { + for (var service in device.gattServices) { + for (var characteristic in service.characteristics) { + _endCharacteristicPropertiesChangedListener(characteristic); + } + } + final subscription = _devicePropertiesChangedSubscriptions.remove( + device.address, + ); + subscription?.cancel(); + } + + void _beginCharacteristicPropertiesChangedListener( + BlueZGattCharacteristic characteristic, + ) { + final subscription = characteristic.propertiesChanged.listen((properties) { + for (var property in properties) { + switch (property) { + case 'Value': + final instance = _myCharacteristics[characteristic.hashCode]; + final myCharacteristic = instance is MyGattCharacteristic + ? instance + : MyGattCharacteristic(characteristic); + final value = Uint8List.fromList(characteristic.value); + final eventArgs = GattCharacteristicValueChangedEventArgs( + myCharacteristic, + value, + ); + _characteristicValueChangedController.add(eventArgs); + break; + default: + break; + } + } + }); + _characteristicPropertiesChangedSubscriptions[characteristic.hashCode] = + subscription; + } + + void _endCharacteristicPropertiesChangedListener( + BlueZGattCharacteristic characteristic, + ) { + final subscription = _characteristicPropertiesChangedSubscriptions.remove( + characteristic.hashCode, + ); + subscription?.cancel(); + } +} diff --git a/bluetooth_low_energy_linux/lib/src/my_gatt_characteristic.dart b/bluetooth_low_energy_linux/lib/src/my_gatt_characteristic.dart new file mode 100644 index 0000000..b441c52 --- /dev/null +++ b/bluetooth_low_energy_linux/lib/src/my_gatt_characteristic.dart @@ -0,0 +1,17 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; +import 'package:bluez/bluez.dart'; + +import 'my_bluez.dart'; +import 'my_object.dart'; + +class MyGattCharacteristic extends MyObject implements GattCharacteristic { + final BlueZGattCharacteristic characteristic; + + MyGattCharacteristic(this.characteristic) : super(characteristic); + + @override + UUID get uuid => characteristic.uuid.toUUID(); + + @override + List get properties => characteristic.properties; +} diff --git a/bluetooth_low_energy_linux/lib/src/my_gatt_descriptor.dart b/bluetooth_low_energy_linux/lib/src/my_gatt_descriptor.dart new file mode 100644 index 0000000..7b55aae --- /dev/null +++ b/bluetooth_low_energy_linux/lib/src/my_gatt_descriptor.dart @@ -0,0 +1,14 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; +import 'package:bluez/bluez.dart'; + +import 'my_bluez.dart'; +import 'my_object.dart'; + +class MyGattDescriptor extends MyObject implements GattDescriptor { + final BlueZGattDescriptor descriptor; + + MyGattDescriptor(this.descriptor) : super(descriptor); + + @override + UUID get uuid => descriptor.uuid.toUUID(); +} diff --git a/bluetooth_low_energy_linux/lib/src/my_gatt_service.dart b/bluetooth_low_energy_linux/lib/src/my_gatt_service.dart new file mode 100644 index 0000000..023fda7 --- /dev/null +++ b/bluetooth_low_energy_linux/lib/src/my_gatt_service.dart @@ -0,0 +1,14 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; +import 'package:bluez/bluez.dart'; + +import 'my_bluez.dart'; +import 'my_object.dart'; + +class MyGattService extends MyObject implements GattService { + final BlueZGattService service; + + MyGattService(this.service) : super(service); + + @override + UUID get uuid => service.uuid.toUUID(); +} diff --git a/bluetooth_low_energy_linux/lib/src/my_object.dart b/bluetooth_low_energy_linux/lib/src/my_object.dart new file mode 100644 index 0000000..d553fe6 --- /dev/null +++ b/bluetooth_low_energy_linux/lib/src/my_object.dart @@ -0,0 +1,11 @@ +abstract class MyObject { + @override + final int hashCode; + + MyObject(Object instance) : hashCode = instance.hashCode; + + @override + bool operator ==(Object other) { + return other is MyObject && other.hashCode == hashCode; + } +} diff --git a/bluetooth_low_energy_linux/lib/src/my_peripheral.dart b/bluetooth_low_energy_linux/lib/src/my_peripheral.dart new file mode 100644 index 0000000..0a6964a --- /dev/null +++ b/bluetooth_low_energy_linux/lib/src/my_peripheral.dart @@ -0,0 +1,14 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; +import 'package:bluez/bluez.dart'; + +import 'my_bluez.dart'; +import 'my_object.dart'; + +class MyPeripheral extends MyObject implements Peripheral { + final BlueZDevice device; + + MyPeripheral(this.device) : super(device); + + @override + UUID get uuid => device.uuid.toUUID(); +} diff --git a/bluetooth_low_energy_linux/pubspec.yaml b/bluetooth_low_energy_linux/pubspec.yaml new file mode 100644 index 0000000..cb7f63b --- /dev/null +++ b/bluetooth_low_energy_linux/pubspec.yaml @@ -0,0 +1,27 @@ +name: bluetooth_low_energy_linux +description: Linux implementation of the bluetooth_low_energy plugin. +version: 2.0.0 +homepage: https://github.com/yanshouwang/bluetooth_low_energy + +environment: + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + bluetooth_low_energy_platform_interface: + path: ../bluetooth_low_energy_platform_interface + bluez: ^0.8.1 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + +flutter: + plugin: + implements: bluetooth_low_energy + platforms: + linux: + dartPluginClass: BluetoothLowEnergyLinux diff --git a/bluetooth_low_energy_macos/.gitignore b/bluetooth_low_energy_macos/.gitignore new file mode 100644 index 0000000..96486fd --- /dev/null +++ b/bluetooth_low_energy_macos/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/bluetooth_low_energy_macos/.metadata b/bluetooth_low_energy_macos/.metadata new file mode 100644 index 0000000..cbd8a9c --- /dev/null +++ b/bluetooth_low_energy_macos/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: macos + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/bluetooth_low_energy_macos/CHANGELOG.md b/bluetooth_low_energy_macos/CHANGELOG.md new file mode 100644 index 0000000..e510273 --- /dev/null +++ b/bluetooth_low_energy_macos/CHANGELOG.md @@ -0,0 +1,4 @@ +## 2.0.0 + +- Rewrite the whole project with federated plugins. +- Support macOS and Linux. diff --git a/bluetooth_low_energy_macos/LICENSE b/bluetooth_low_energy_macos/LICENSE new file mode 100644 index 0000000..515ed4b --- /dev/null +++ b/bluetooth_low_energy_macos/LICENSE @@ -0,0 +1,21 @@ +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. \ No newline at end of file diff --git a/bluetooth_low_energy_macos/README.md b/bluetooth_low_energy_macos/README.md new file mode 100644 index 0000000..7836cda --- /dev/null +++ b/bluetooth_low_energy_macos/README.md @@ -0,0 +1,15 @@ +# bluetooth_low_energy_macos + +The macOS implementation of [`bluetooth_low_energy`][1]. + +## Usage + +This package is [endorsed][2], which means you can simply use `bluetooth_low_energy` +normally. This package will be automatically included in your app when you do, +so you do not need to add it to your `pubspec.yaml`. + +However, if you `import` this package to use any of its APIs directly, you +should add it to your `pubspec.yaml` as usual. + +[1]: https://pub.dev/packages/bluetooth_low_energy +[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin diff --git a/bluetooth_low_energy_macos/analysis_options.yaml b/bluetooth_low_energy_macos/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/bluetooth_low_energy_macos/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/bluetooth_low_energy_macos/lib/bluetooth_low_energy_macos.dart b/bluetooth_low_energy_macos/lib/bluetooth_low_energy_macos.dart new file mode 100644 index 0000000..24dc29e --- /dev/null +++ b/bluetooth_low_energy_macos/lib/bluetooth_low_energy_macos.dart @@ -0,0 +1,9 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'src/my_central_controller.dart'; + +abstract class BluetoothLowEnergymacOS { + static void registerWith() { + CentralController.instance = MyCentralController(); + } +} diff --git a/bluetooth_low_energy_macos/lib/src/my_api.g.dart b/bluetooth_low_energy_macos/lib/src/my_api.g.dart new file mode 100644 index 0000000..248235a --- /dev/null +++ b/bluetooth_low_energy_macos/lib/src/my_api.g.dart @@ -0,0 +1,736 @@ +// Autogenerated from Pigeon (v10.1.6), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +enum MyCentralStateArgs { + unknown, + unsupported, + unauthorized, + poweredOff, + poweredOn, +} + +enum MyGattCharacteristicPropertyArgs { + read, + write, + writeWithoutResponse, + notify, + indicate, +} + +enum MyGattCharacteristicWriteTypeArgs { + withResponse, + withoutResponse, +} + +class MyCentralControllerArgs { + MyCentralControllerArgs({ + required this.myStateNumber, + }); + + int myStateNumber; + + Object encode() { + return [ + myStateNumber, + ]; + } + + static MyCentralControllerArgs decode(Object result) { + result as List; + return MyCentralControllerArgs( + myStateNumber: result[0]! as int, + ); + } +} + +class MyPeripheralArgs { + MyPeripheralArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyPeripheralArgs decode(Object result) { + result as List; + return MyPeripheralArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class MyAdvertisementArgs { + MyAdvertisementArgs({ + this.name, + required this.manufacturerSpecificData, + required this.serviceUUIDs, + required this.serviceData, + }); + + String? name; + + Map manufacturerSpecificData; + + List serviceUUIDs; + + Map serviceData; + + Object encode() { + return [ + name, + manufacturerSpecificData, + serviceUUIDs, + serviceData, + ]; + } + + static MyAdvertisementArgs decode(Object result) { + result as List; + return MyAdvertisementArgs( + name: result[0] as String?, + manufacturerSpecificData: (result[1] as Map?)!.cast(), + serviceUUIDs: (result[2] as List?)!.cast(), + serviceData: (result[3] as Map?)!.cast(), + ); + } +} + +class MyGattServiceArgs { + MyGattServiceArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyGattServiceArgs decode(Object result) { + result as List; + return MyGattServiceArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class MyGattCharacteristicArgs { + MyGattCharacteristicArgs({ + required this.key, + required this.uuid, + required this.myPropertyNumbers, + }); + + int key; + + String uuid; + + List myPropertyNumbers; + + Object encode() { + return [ + key, + uuid, + myPropertyNumbers, + ]; + } + + static MyGattCharacteristicArgs decode(Object result) { + result as List; + return MyGattCharacteristicArgs( + key: result[0]! as int, + uuid: result[1]! as String, + myPropertyNumbers: (result[2] as List?)!.cast(), + ); + } +} + +class MyGattDescriptorArgs { + MyGattDescriptorArgs({ + required this.key, + required this.uuid, + }); + + int key; + + String uuid; + + Object encode() { + return [ + key, + uuid, + ]; + } + + static MyGattDescriptorArgs decode(Object result) { + result as List; + return MyGattDescriptorArgs( + key: result[0]! as int, + uuid: result[1]! as String, + ); + } +} + +class _MyCentralControllerHostApiCodec extends StandardMessageCodec { + const _MyCentralControllerHostApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is MyCentralControllerArgs) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else if (value is MyGattCharacteristicArgs) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else if (value is MyGattDescriptorArgs) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is MyGattServiceArgs) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return MyCentralControllerArgs.decode(readValue(buffer)!); + case 129: + return MyGattCharacteristicArgs.decode(readValue(buffer)!); + case 130: + return MyGattDescriptorArgs.decode(readValue(buffer)!); + case 131: + return MyGattServiceArgs.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class MyCentralControllerHostApi { + /// Constructor for [MyCentralControllerHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + MyCentralControllerHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _MyCentralControllerHostApiCodec(); + + Future setUp() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.setUp', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as MyCentralControllerArgs?)!; + } + } + + Future tearDown() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.tearDown', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future startDiscovery() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.startDiscovery', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future stopDiscovery() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.stopDiscovery', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future connect(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.connect', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future disconnect(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.disconnect', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future discoverGATT(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.discoverGATT', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future> getServices(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.getServices', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getCharacteristics(int arg_myServiceKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.getCharacteristics', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myServiceKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getDescriptors(int arg_myCharacteristicKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.getDescriptors', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myCharacteristicKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future readCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.readCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as Uint8List?)!; + } + } + + Future writeCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, Uint8List arg_value, int arg_myTypeNumber) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.writeCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey, arg_value, arg_myTypeNumber]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future notifyCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, bool arg_state) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.notifyCharacteristic', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myCharacteristicKey, arg_state]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future readDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.readDescriptor', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myDescriptorKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as Uint8List?)!; + } + } + + Future writeDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey, Uint8List arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.writeDescriptor', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myDescriptorKey, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } +} + +class _MyCentralControllerFlutterApiCodec extends StandardMessageCodec { + const _MyCentralControllerFlutterApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is MyAdvertisementArgs) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else if (value is MyPeripheralArgs) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return MyAdvertisementArgs.decode(readValue(buffer)!); + case 129: + return MyPeripheralArgs.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class MyCentralControllerFlutterApi { + static const MessageCodec codec = _MyCentralControllerFlutterApiCodec(); + + void onStateChanged(int myStateNumber); + + void onDiscovered(MyPeripheralArgs myPeripheralArgs, int rssi, MyAdvertisementArgs myAdvertisementArgs); + + void onPeripheralStateChanged(int myPeripheralKey, bool state); + + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value); + + static void setup(MyCentralControllerFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onStateChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onStateChanged was null.'); + final List args = (message as List?)!; + final int? arg_myStateNumber = (args[0] as int?); + assert(arg_myStateNumber != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onStateChanged was null, expected non-null int.'); + api.onStateChanged(arg_myStateNumber!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onDiscovered', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onDiscovered was null.'); + final List args = (message as List?)!; + final MyPeripheralArgs? arg_myPeripheralArgs = (args[0] as MyPeripheralArgs?); + assert(arg_myPeripheralArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyPeripheralArgs.'); + final int? arg_rssi = (args[1] as int?); + assert(arg_rssi != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null int.'); + final MyAdvertisementArgs? arg_myAdvertisementArgs = (args[2] as MyAdvertisementArgs?); + assert(arg_myAdvertisementArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyAdvertisementArgs.'); + api.onDiscovered(arg_myPeripheralArgs!, arg_rssi!, arg_myAdvertisementArgs!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onPeripheralStateChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onPeripheralStateChanged was null.'); + final List args = (message as List?)!; + final int? arg_myPeripheralKey = (args[0] as int?); + assert(arg_myPeripheralKey != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null int.'); + final bool? arg_state = (args[1] as bool?); + assert(arg_state != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null bool.'); + api.onPeripheralStateChanged(arg_myPeripheralKey!, arg_state!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onCharacteristicValueChanged', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null.'); + final List args = (message as List?)!; + final int? arg_myCharacteristicKey = (args[0] as int?); + assert(arg_myCharacteristicKey != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null int.'); + final Uint8List? arg_value = (args[1] as Uint8List?); + assert(arg_value != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null Uint8List.'); + api.onCharacteristicValueChanged(arg_myCharacteristicKey!, arg_value!); + return; + }); + } + } + } +} diff --git a/bluetooth_low_energy_macos/lib/src/my_central_controller.dart b/bluetooth_low_energy_macos/lib/src/my_central_controller.dart new file mode 100644 index 0000000..6444c3a --- /dev/null +++ b/bluetooth_low_energy_macos/lib/src/my_central_controller.dart @@ -0,0 +1,357 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_characteristic.dart'; +import 'my_gatt_descriptor.dart'; +import 'my_gatt_service.dart'; +import 'my_peripheral.dart'; + +class MyCentralController extends CentralController + implements MyCentralControllerFlutterApi { + MyCentralController() + : _myApi = MyCentralControllerHostApi(), + _stateChangedController = StreamController.broadcast(), + _discoveredController = StreamController.broadcast(), + _peripheralStateChangedController = StreamController.broadcast(), + _characteristicValueChangedController = StreamController.broadcast(), + _myPeripherals = {}, + _myServices = {}, + _myCharacteristics = {}, + _myDescriptors = {}, + _state = CentralState.unknown; + + final MyCentralControllerHostApi _myApi; + final StreamController _stateChangedController; + final StreamController _discoveredController; + final StreamController + _peripheralStateChangedController; + final StreamController + _characteristicValueChangedController; + final Map _myPeripherals; + final Map _myServices; + final Map _myCharacteristics; + final Map _myDescriptors; + + CentralState _state; + @override + CentralState get state => _state; + + @override + Stream get stateChanged => + _stateChangedController.stream; + @override + Stream get discovered => + _discoveredController.stream; + @override + Stream get peripheralStateChanged => + _peripheralStateChangedController.stream; + @override + Stream + get characteristicValueChanged => + _characteristicValueChangedController.stream; + + Future _throwWithState(CentralState state) async { + if (this.state == state) { + throw BluetoothLowEnergyError('$state is unexpected.'); + } + } + + Future _throwWithoutState(CentralState state) async { + if (this.state != state) { + throw BluetoothLowEnergyError( + '$state is expected, but current state is ${this.state}.', + ); + } + } + + @override + Future setUp() async { + await _throwWithoutState(CentralState.unknown); + final args = await _myApi.setUp(); + final myStateArgs = MyCentralStateArgs.values[args.myStateNumber]; + _state = myStateArgs.toState(); + MyCentralControllerFlutterApi.setup(this); + } + + @override + Future tearDown() async { + await _throwWithState(CentralState.unknown); + await _myApi.tearDown(); + MyCentralControllerFlutterApi.setup(null); + _myPeripherals.clear(); + _myServices.clear(); + _myCharacteristics.clear(); + _myDescriptors.clear(); + _state = CentralState.unknown; + } + + @override + Future startDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _myApi.startDiscovery(); + } + + @override + Future stopDiscovery() async { + await _throwWithoutState(CentralState.poweredOn); + await _myApi.stopDiscovery(); + } + + @override + Future connect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.connect(myPeripheral.hashCode); + } + + @override + Future disconnect(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.disconnect(myPeripheral.hashCode); + } + + @override + Future discoverGATT(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + await _myApi.discoverGATT(myPeripheral.hashCode); + } + + @override + Future> getServices(Peripheral peripheral) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final myServiceArgses = await _myApi.getServices(myPeripheral.hashCode); + return myServiceArgses + .cast() + .map( + (myServiceArgs) => _myServices.putIfAbsent( + myServiceArgs.key, + () => MyGattService.fromMyArgs( + myPeripheral, + myServiceArgs, + ), + ), + ) + .toList(); + } + + @override + Future> getCharacteristics( + GattService service, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myService = service as MyGattService; + final myCharactersiticArgses = await _myApi.getCharacteristics( + myService.hashCode, + ); + return myCharactersiticArgses + .cast() + .map( + (myCharacteristicArgs) => _myCharacteristics.putIfAbsent( + myCharacteristicArgs.key, + () => MyGattCharacteristic.fromMyArgs( + myService, + myCharacteristicArgs, + ), + ), + ) + .toList(); + } + + @override + Future> getDescriptors( + GattCharacteristic characteristic, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myDescriptorArgses = await _myApi.getDescriptors( + myCharacteristic.hashCode, + ); + return myDescriptorArgses + .cast() + .map( + (myDescriptorArgs) => _myDescriptors.putIfAbsent( + myDescriptorArgs.key, + () => MyGattDescriptor.fromMyArgs( + myCharacteristic, + myDescriptorArgs, + ), + ), + ) + .toList(); + } + + @override + Future readCharacteristic( + GattCharacteristic characteristic, + ) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final value = await _myApi.readCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + ); + return value; + } + + @override + Future writeCharacteristic( + GattCharacteristic characteristic, { + required Uint8List value, + required GattCharacteristicWriteType type, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final typeArgs = type.toMyArgs(); + final typeNumber = typeArgs.index; + await _myApi.writeCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + value, + typeNumber, + ); + } + + @override + Future notifyCharacteristic( + GattCharacteristic characteristic, { + required bool state, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myCharacteristic = characteristic as MyGattCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + await _myApi.notifyCharacteristic( + myPeripheral.hashCode, + myCharacteristic.hashCode, + state, + ); + } + + @override + Future readDescriptor(GattDescriptor descriptor) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final myCharacteristic = myDescriptor.myCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + final value = await _myApi.readDescriptor( + myPeripheral.hashCode, + myDescriptor.hashCode, + ); + return value; + } + + @override + Future writeDescriptor( + GattDescriptor descriptor, { + required Uint8List value, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myDescriptor = descriptor as MyGattDescriptor; + final myCharacteristic = myDescriptor.myCharacteristic; + final myService = myCharacteristic.myService; + final myPeripheral = myService.myPeripheral; + await _myApi.writeDescriptor( + myPeripheral.hashCode, + myDescriptor.hashCode, + value, + ); + } + + @override + void onStateChanged(int myStateNumber) { + final myStateArgs = MyCentralStateArgs.values[myStateNumber]; + final state = myStateArgs.toState(); + if (_state == state) { + return; + } + _state = state; + final eventArgs = CentralStateChangedEventArgs(state); + _stateChangedController.add(eventArgs); + } + + @override + void onDiscovered( + MyPeripheralArgs myPeripheralArgs, + int rssi, + MyAdvertisementArgs myAdvertisementArgs, + ) { + final myPeripheral = _myPeripherals.putIfAbsent( + myPeripheralArgs.key, + () => MyPeripheral.fromMyArgs(myPeripheralArgs), + ); + final advertisement = myAdvertisementArgs.toAdvertisement(); + final eventArgs = CentralDiscoveredEventArgs( + myPeripheral, + rssi, + advertisement, + ); + _discoveredController.add(eventArgs); + } + + @override + void onPeripheralStateChanged(int myPeripheralKey, bool state) { + final myPeripheral = _myPeripherals[myPeripheralKey]; + if (myPeripheral == null) { + return; + } + final eventArgs = PeripheralStateChangedEventArgs(myPeripheral, state); + _peripheralStateChangedController.add(eventArgs); + } + + @override + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value) { + final myCharacteristic = + _myCharacteristics[myCharacteristicKey] as MyGattCharacteristic; + final eventArgs = GattCharacteristicValueChangedEventArgs( + myCharacteristic, + value, + ); + _characteristicValueChangedController.add(eventArgs); + } +} + +extension on MyAdvertisementArgs { + Advertisement toAdvertisement() { + final serviceUUIDs = this + .serviceUUIDs + .cast() + .map((uuid) => UUID.fromString(uuid)) + .toList(); + final serviceData = this.serviceData.cast().map( + (uuid, data) { + final key = UUID.fromString(uuid); + final value = data; + return MapEntry(key, value); + }, + ); + return Advertisement( + name: name, + manufacturerSpecificData: manufacturerSpecificData.cast(), + serviceUUIDs: serviceUUIDs, + serviceData: serviceData, + ); + } +} + +extension on MyCentralStateArgs { + CentralState toState() { + return CentralState.values[index]; + } +} + +extension on GattCharacteristicWriteType { + MyGattCharacteristicWriteTypeArgs toMyArgs() { + return MyGattCharacteristicWriteTypeArgs.values[index]; + } +} diff --git a/bluetooth_low_energy_macos/lib/src/my_gatt_characteristic.dart b/bluetooth_low_energy_macos/lib/src/my_gatt_characteristic.dart new file mode 100644 index 0000000..811fb23 --- /dev/null +++ b/bluetooth_low_energy_macos/lib/src/my_gatt_characteristic.dart @@ -0,0 +1,42 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_service.dart'; +import 'my_object.dart'; + +class MyGattCharacteristic extends MyObject implements GattCharacteristic { + final MyGattService myService; + @override + final UUID uuid; + @override + final List properties; + + MyGattCharacteristic( + super.hashCode, + this.myService, + this.uuid, + this.properties, + ); + + factory MyGattCharacteristic.fromMyArgs( + MyGattService myService, + MyGattCharacteristicArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + final properties = myArgs.myPropertyNumbers.cast().map( + (myPropertyNumber) { + final myPropertyArgs = + MyGattCharacteristicPropertyArgs.values[myPropertyNumber]; + return myPropertyArgs.toProperty(); + }, + ).toList(); + return MyGattCharacteristic(hashCode, myService, uuid, properties); + } +} + +extension on MyGattCharacteristicPropertyArgs { + GattCharacteristicProperty toProperty() { + return GattCharacteristicProperty.values[index]; + } +} diff --git a/bluetooth_low_energy_macos/lib/src/my_gatt_descriptor.dart b/bluetooth_low_energy_macos/lib/src/my_gatt_descriptor.dart new file mode 100644 index 0000000..6798f4a --- /dev/null +++ b/bluetooth_low_energy_macos/lib/src/my_gatt_descriptor.dart @@ -0,0 +1,22 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_gatt_characteristic.dart'; +import 'my_object.dart'; + +class MyGattDescriptor extends MyObject implements GattDescriptor { + final MyGattCharacteristic myCharacteristic; + @override + final UUID uuid; + + MyGattDescriptor(super.hashCode, this.myCharacteristic, this.uuid); + + factory MyGattDescriptor.fromMyArgs( + MyGattCharacteristic myCharacteristic, + MyGattDescriptorArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyGattDescriptor(hashCode, myCharacteristic, uuid); + } +} diff --git a/bluetooth_low_energy_macos/lib/src/my_gatt_service.dart b/bluetooth_low_energy_macos/lib/src/my_gatt_service.dart new file mode 100644 index 0000000..37babdb --- /dev/null +++ b/bluetooth_low_energy_macos/lib/src/my_gatt_service.dart @@ -0,0 +1,22 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_object.dart'; +import 'my_peripheral.dart'; + +class MyGattService extends MyObject implements GattService { + final MyPeripheral myPeripheral; + @override + final UUID uuid; + + MyGattService(super.hashCode, this.myPeripheral, this.uuid); + + factory MyGattService.fromMyArgs( + MyPeripheral myPeripheral, + MyGattServiceArgs myArgs, + ) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyGattService(hashCode, myPeripheral, uuid); + } +} diff --git a/bluetooth_low_energy_macos/lib/src/my_object.dart b/bluetooth_low_energy_macos/lib/src/my_object.dart new file mode 100644 index 0000000..2b33805 --- /dev/null +++ b/bluetooth_low_energy_macos/lib/src/my_object.dart @@ -0,0 +1,11 @@ +abstract class MyObject { + @override + final int hashCode; + + MyObject(this.hashCode); + + @override + bool operator ==(Object other) { + return other is MyObject && other.hashCode == hashCode; + } +} diff --git a/bluetooth_low_energy_macos/lib/src/my_peripheral.dart b/bluetooth_low_energy_macos/lib/src/my_peripheral.dart new file mode 100644 index 0000000..7be1bd3 --- /dev/null +++ b/bluetooth_low_energy_macos/lib/src/my_peripheral.dart @@ -0,0 +1,17 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'my_api.g.dart'; +import 'my_object.dart'; + +class MyPeripheral extends MyObject implements Peripheral { + @override + final UUID uuid; + + MyPeripheral(super.hashCode, this.uuid); + + factory MyPeripheral.fromMyArgs(MyPeripheralArgs myArgs) { + final hashCode = myArgs.key; + final uuid = UUID.fromString(myArgs.uuid); + return MyPeripheral(hashCode, uuid); + } +} diff --git a/bluetooth_low_energy_macos/macos/Classes/BluetoothLowEnergymacOS.swift b/bluetooth_low_energy_macos/macos/Classes/BluetoothLowEnergymacOS.swift new file mode 100644 index 0000000..25ac7fc --- /dev/null +++ b/bluetooth_low_energy_macos/macos/Classes/BluetoothLowEnergymacOS.swift @@ -0,0 +1,10 @@ +import Cocoa +import FlutterMacOS + +public class BluetoothLowEnergymacOS: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let binaryMessenger = registrar.messenger + let centralController = MyCentralController(binaryMessenger) + MyCentralControllerHostApiSetup.setUp(binaryMessenger: binaryMessenger, api: centralController) + } +} diff --git a/bluetooth_low_energy_macos/macos/Classes/MyApi.g.swift b/bluetooth_low_energy_macos/macos/Classes/MyApi.g.swift new file mode 100644 index 0000000..2347a9f --- /dev/null +++ b/bluetooth_low_energy_macos/macos/Classes/MyApi.g.swift @@ -0,0 +1,594 @@ +// Autogenerated from Pigeon (v10.1.6), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation +#if os(iOS) +import Flutter +#elseif os(macOS) +import FlutterMacOS +#else +#error("Unsupported platform.") +#endif + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)" + ] +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +enum MyCentralStateArgs: Int { + case unknown = 0 + case unsupported = 1 + case unauthorized = 2 + case poweredOff = 3 + case poweredOn = 4 +} + +enum MyGattCharacteristicPropertyArgs: Int { + case read = 0 + case write = 1 + case writeWithoutResponse = 2 + case notify = 3 + case indicate = 4 +} + +enum MyGattCharacteristicWriteTypeArgs: Int { + case withResponse = 0 + case withoutResponse = 1 +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyCentralControllerArgs { + var myStateNumber: Int64 + + static func fromList(_ list: [Any?]) -> MyCentralControllerArgs? { + let myStateNumber = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + + return MyCentralControllerArgs( + myStateNumber: myStateNumber + ) + } + func toList() -> [Any?] { + return [ + myStateNumber, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyPeripheralArgs { + var key: Int64 + var uuid: String + + static func fromList(_ list: [Any?]) -> MyPeripheralArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + + return MyPeripheralArgs( + key: key, + uuid: uuid + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyAdvertisementArgs { + var name: String? = nil + var manufacturerSpecificData: [Int64?: FlutterStandardTypedData?] + var serviceUUIDs: [String?] + var serviceData: [String?: FlutterStandardTypedData?] + + static func fromList(_ list: [Any?]) -> MyAdvertisementArgs? { + let name: String? = nilOrValue(list[0]) + let manufacturerSpecificData = list[1] as! [Int64?: FlutterStandardTypedData?] + let serviceUUIDs = list[2] as! [String?] + let serviceData = list[3] as! [String?: FlutterStandardTypedData?] + + return MyAdvertisementArgs( + name: name, + manufacturerSpecificData: manufacturerSpecificData, + serviceUUIDs: serviceUUIDs, + serviceData: serviceData + ) + } + func toList() -> [Any?] { + return [ + name, + manufacturerSpecificData, + serviceUUIDs, + serviceData, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyGattServiceArgs { + var key: Int64 + var uuid: String + + static func fromList(_ list: [Any?]) -> MyGattServiceArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + + return MyGattServiceArgs( + key: key, + uuid: uuid + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyGattCharacteristicArgs { + var key: Int64 + var uuid: String + var myPropertyNumbers: [Int64?] + + static func fromList(_ list: [Any?]) -> MyGattCharacteristicArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + let myPropertyNumbers = list[2] as! [Int64?] + + return MyGattCharacteristicArgs( + key: key, + uuid: uuid, + myPropertyNumbers: myPropertyNumbers + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + myPropertyNumbers, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct MyGattDescriptorArgs { + var key: Int64 + var uuid: String + + static func fromList(_ list: [Any?]) -> MyGattDescriptorArgs? { + let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let uuid = list[1] as! String + + return MyGattDescriptorArgs( + key: key, + uuid: uuid + ) + } + func toList() -> [Any?] { + return [ + key, + uuid, + ] + } +} + +private class MyCentralControllerHostApiCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + return MyCentralControllerArgs.fromList(self.readValue() as! [Any?]) + case 129: + return MyGattCharacteristicArgs.fromList(self.readValue() as! [Any?]) + case 130: + return MyGattDescriptorArgs.fromList(self.readValue() as! [Any?]) + case 131: + return MyGattServiceArgs.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class MyCentralControllerHostApiCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? MyCentralControllerArgs { + super.writeByte(128) + super.writeValue(value.toList()) + } else if let value = value as? MyGattCharacteristicArgs { + super.writeByte(129) + super.writeValue(value.toList()) + } else if let value = value as? MyGattDescriptorArgs { + super.writeByte(130) + super.writeValue(value.toList()) + } else if let value = value as? MyGattServiceArgs { + super.writeByte(131) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class MyCentralControllerHostApiCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return MyCentralControllerHostApiCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return MyCentralControllerHostApiCodecWriter(data: data) + } +} + +class MyCentralControllerHostApiCodec: FlutterStandardMessageCodec { + static let shared = MyCentralControllerHostApiCodec(readerWriter: MyCentralControllerHostApiCodecReaderWriter()) +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol MyCentralControllerHostApi { + func setUp(completion: @escaping (Result) -> Void) + func tearDown() throws + func startDiscovery() throws + func stopDiscovery() throws + func connect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) + func disconnect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) + func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) + func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs] + func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs] + func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs] + func readCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result) -> Void) + func writeCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result) -> Void) + func notifyCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result) -> Void) + func readDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result) -> Void) + func writeDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result) -> Void) +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class MyCentralControllerHostApiSetup { + /// The codec used by MyCentralControllerHostApi. + static var codec: FlutterStandardMessageCodec { MyCentralControllerHostApiCodec.shared } + /// Sets up an instance of `MyCentralControllerHostApi` to handle messages through the `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: MyCentralControllerHostApi?) { + let setUpChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.setUp", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setUpChannel.setMessageHandler { _, reply in + api.setUp() { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + setUpChannel.setMessageHandler(nil) + } + let tearDownChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.tearDown", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + tearDownChannel.setMessageHandler { _, reply in + do { + try api.tearDown() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + tearDownChannel.setMessageHandler(nil) + } + let startDiscoveryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.startDiscovery", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + startDiscoveryChannel.setMessageHandler { _, reply in + do { + try api.startDiscovery() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + startDiscoveryChannel.setMessageHandler(nil) + } + let stopDiscoveryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.stopDiscovery", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + stopDiscoveryChannel.setMessageHandler { _, reply in + do { + try api.stopDiscovery() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + stopDiscoveryChannel.setMessageHandler(nil) + } + let connectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.connect", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + connectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + api.connect(myPeripheralKey: myPeripheralKeyArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + connectChannel.setMessageHandler(nil) + } + let disconnectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.disconnect", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + disconnectChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + api.disconnect(myPeripheralKey: myPeripheralKeyArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + disconnectChannel.setMessageHandler(nil) + } + let discoverGATTChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.discoverGATT", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + discoverGATTChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + api.discoverGATT(myPeripheralKey: myPeripheralKeyArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + discoverGATTChannel.setMessageHandler(nil) + } + let getServicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.getServices", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getServicesChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + do { + let result = try api.getServices(myPeripheralKey: myPeripheralKeyArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getServicesChannel.setMessageHandler(nil) + } + let getCharacteristicsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.getCharacteristics", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getCharacteristicsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myServiceKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + do { + let result = try api.getCharacteristics(myServiceKey: myServiceKeyArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getCharacteristicsChannel.setMessageHandler(nil) + } + let getDescriptorsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.getDescriptors", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getDescriptorsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myCharacteristicKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + do { + let result = try api.getDescriptors(myCharacteristicKey: myCharacteristicKeyArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getDescriptorsChannel.setMessageHandler(nil) + } + let readCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.readCharacteristic", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + readCharacteristicChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.readCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + readCharacteristicChannel.setMessageHandler(nil) + } + let writeCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.writeCharacteristic", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + writeCharacteristicChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + let valueArg = args[2] as! FlutterStandardTypedData + let myTypeNumberArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32) + api.writeCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, value: valueArg, myTypeNumber: myTypeNumberArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + writeCharacteristicChannel.setMessageHandler(nil) + } + let notifyCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.notifyCharacteristic", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + notifyCharacteristicChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + let stateArg = args[2] as! Bool + api.notifyCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, state: stateArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + notifyCharacteristicChannel.setMessageHandler(nil) + } + let readDescriptorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.readDescriptor", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + readDescriptorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myDescriptorKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.readDescriptor(myPeripheralKey: myPeripheralKeyArg, myDescriptorKey: myDescriptorKeyArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + readDescriptorChannel.setMessageHandler(nil) + } + let writeDescriptorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerHostApi.writeDescriptor", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + writeDescriptorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myDescriptorKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + let valueArg = args[2] as! FlutterStandardTypedData + api.writeDescriptor(myPeripheralKey: myPeripheralKeyArg, myDescriptorKey: myDescriptorKeyArg, value: valueArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + writeDescriptorChannel.setMessageHandler(nil) + } + } +} +private class MyCentralControllerFlutterApiCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + return MyAdvertisementArgs.fromList(self.readValue() as! [Any?]) + case 129: + return MyPeripheralArgs.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class MyCentralControllerFlutterApiCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? MyAdvertisementArgs { + super.writeByte(128) + super.writeValue(value.toList()) + } else if let value = value as? MyPeripheralArgs { + super.writeByte(129) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class MyCentralControllerFlutterApiCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return MyCentralControllerFlutterApiCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return MyCentralControllerFlutterApiCodecWriter(data: data) + } +} + +class MyCentralControllerFlutterApiCodec: FlutterStandardMessageCodec { + static let shared = MyCentralControllerFlutterApiCodec(readerWriter: MyCentralControllerFlutterApiCodecReaderWriter()) +} + +/// Generated class from Pigeon that represents Flutter messages that can be called from Swift. +class MyCentralControllerFlutterApi { + private let binaryMessenger: FlutterBinaryMessenger + init(binaryMessenger: FlutterBinaryMessenger){ + self.binaryMessenger = binaryMessenger + } + var codec: FlutterStandardMessageCodec { + return MyCentralControllerFlutterApiCodec.shared + } + func onStateChanged(myStateNumber myStateNumberArg: Int64, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onStateChanged", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myStateNumberArg] as [Any?]) { _ in + completion() + } + } + func onDiscovered(myPeripheralArgs myPeripheralArgsArg: MyPeripheralArgs, rssi rssiArg: Int64, myAdvertisementArgs myAdvertisementArgsArg: MyAdvertisementArgs, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onDiscovered", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myPeripheralArgsArg, rssiArg, myAdvertisementArgsArg] as [Any?]) { _ in + completion() + } + } + func onPeripheralStateChanged(myPeripheralKey myPeripheralKeyArg: Int64, state stateArg: Bool, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onPeripheralStateChanged", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myPeripheralKeyArg, stateArg] as [Any?]) { _ in + completion() + } + } + func onCharacteristicValueChanged(myCharacteristicKey myCharacteristicKeyArg: Int64, value valueArg: FlutterStandardTypedData, completion: @escaping () -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_macos.MyCentralControllerFlutterApi.onCharacteristicValueChanged", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([myCharacteristicKeyArg, valueArg] as [Any?]) { _ in + completion() + } + } +} diff --git a/bluetooth_low_energy_macos/macos/Classes/MyCentralController.swift b/bluetooth_low_energy_macos/macos/Classes/MyCentralController.swift new file mode 100644 index 0000000..9cffd6c --- /dev/null +++ b/bluetooth_low_energy_macos/macos/Classes/MyCentralController.swift @@ -0,0 +1,696 @@ +// +// MyCentralController.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation +import FlutterMacOS +import CoreBluetooth + +class MyCentralController: MyCentralControllerHostApi { + init(_ binaryMessenger: FlutterBinaryMessenger) { + myApi = MyCentralControllerFlutterApi(binaryMessenger: binaryMessenger) + } + + private let myApi: MyCentralControllerFlutterApi + private lazy var myCentralManagerDelegate = MyCentralManagerDelegate(self) + private lazy var myPeripheralDelegate = MyPeripheralDelegate(self) + private let centralManager = CBCentralManager() + + private var peripherals = [Int: CBPeripheral]() + private var services = [Int: CBService]() + private var characteristics = [Int: CBCharacteristic]() + private var descriptors = [Int: CBDescriptor]() + + var setUpCompletion: ((Result) -> Void)? + var connectCompletions = [Int: (Result) -> Void]() + var disconnectCompletions = [Int: (Result) -> Void]() + var discoverGattCompletions = [Int: (Result) -> Void]() + var unfinishedServices = [Int: [CBService]]() + var unfinishedCharacteristics = [Int: [CBCharacteristic]]() + var readCharacteristicCompletions = [Int: (Result) -> Void]() + var writeCharacteristicCompletions = [Int: (Result) -> Void]() + var notifyCharacteristicCompletions = [Int: (Result) -> Void]() + var readDescriptorCompletions = [Int: (Result) -> Void]() + var writeDescriptorCompletions = [Int: (Result) -> Void]() + + func setUp(completion: @escaping (Result) -> Void) { + do { + let unfinishedCompletion = setUpCompletion + if unfinishedCompletion != nil { + throw MyError.illegalState + } + centralManager.delegate = myCentralManagerDelegate + if centralManager.state == .unknown { + setUpCompletion = completion + } else { + let myStateArgs = centralManager.state.toMyArgs() + let myStateNumber = Int64(myStateArgs.rawValue) + let myArgs = MyCentralControllerArgs(myStateNumber: myStateNumber) + completion(.success(myArgs)) + } + } catch { + completion(.failure(error)) + } + } + + func tearDown() throws { + centralManager.delegate = nil + if(centralManager.isScanning) { + centralManager.stopScan() + } + for peripheral in peripherals.values { + peripheral.delegate = nil + if peripheral.state != .disconnected { + centralManager.cancelPeripheralConnection(peripheral) + } + } + peripherals.removeAll() + services.removeAll() + characteristics.removeAll() + descriptors.removeAll() + } + + func startDiscovery() throws { + let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true] + centralManager.scanForPeripherals(withServices: nil, options: options) + } + + func stopDiscovery() throws { + centralManager.stopScan() + } + + func connect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + let unfinishedCompletion = connectCompletions[peripheralKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + centralManager.connect(peripheral) + connectCompletions[peripheralKey] = completion + } catch { + completion(.failure(error)) + } + } + + func disconnect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + let unfinishedCompletion = disconnectCompletions[peripheralKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + centralManager.cancelPeripheralConnection(peripheral) + disconnectCompletions[peripheralKey] = completion + } catch { + completion(.failure(error)) + } + } + + func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + let unfinishedCompletion = discoverGattCompletions[peripheralKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + peripheral.discoverServices(nil) + discoverGattCompletions[peripheralKey] = completion + } catch { + completion(.failure(error)) + } + } + + func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs] { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let services = peripheral.services ?? [] + return services.map { service in + let serviceKey = service.hash + if self.services[serviceKey] == nil { + self.services[serviceKey] = service + } + return service.toMyArgs() + } + } + + func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs] { + let serviceKey = Int(myServiceKey) + guard let service = services[serviceKey] else { + throw MyError.illegalArgument + } + let characteristics = service.characteristics ?? [] + return characteristics.map { characteristic in + let characteristicKey = characteristic.hash + if self.characteristics[characteristicKey] == nil { + self.characteristics[characteristicKey] = characteristic + } + return characteristic.toMyArgs() + } + } + + func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs] { + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let descritors = characteristic.descriptors ?? [] + return descritors.map { descriptor in + let descriptorKey = descriptor.hash + if self.descriptors[descriptorKey] == nil { + self.descriptors[descriptorKey] = descriptor + } + return descriptor.toMyArgs() + } + } + + func readCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let unfinishedCompletion = readCharacteristicCompletions[characteristicKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.readValue(for: characteristic) + readCharacteristicCompletions[characteristicKey] = completion + } catch { + completion(.failure(error)) + } + } + + func writeCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let data = value.data + let myTypeRawValue = Int(myTypeNumber) + guard let myTypeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: myTypeRawValue) else { + throw MyError.illegalArgument + } + let type = myTypeArgs.toType() + let unfinishedCompletion = writeCharacteristicCompletions[characteristicKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.writeValue(data, for: characteristic, type: type) + writeCharacteristicCompletions[characteristicKey] = completion + } catch { + completion(.failure(error)) + } + } + + func notifyCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let characteristicKey = Int(myCharacteristicKey) + guard let characteristic = characteristics[characteristicKey] else { + throw MyError.illegalArgument + } + let unfinishedCompletion = notifyCharacteristicCompletions[characteristicKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.setNotifyValue(state, for: characteristic) + notifyCharacteristicCompletions[characteristicKey] = completion + } catch { + completion(.failure(error)) + } + } + + func readDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let descriptorKey = Int(myDescriptorKey) + guard let descriptor = descriptors[descriptorKey] else { + throw MyError.illegalArgument + } + let unfinishedCompletion = readDescriptorCompletions[descriptorKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.readValue(for: descriptor) + readDescriptorCompletions[descriptorKey] = completion + } catch { + completion(.failure(error)) + } + } + + func writeDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result) -> Void) { + do { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = peripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let descriptorKey = Int(myDescriptorKey) + guard let descriptor = descriptors[descriptorKey] else { + throw MyError.illegalArgument + } + let data = value.data + let unfinishedCompletion = writeDescriptorCompletions[descriptorKey] + if unfinishedCompletion != nil { + throw MyError.illegalState + } + peripheral.writeValue(data, for: descriptor) + writeDescriptorCompletions[descriptorKey] = completion + } catch { + completion(.failure(error)) + } + } + + func didUpdateState(_ state: CBManagerState) { + let completion = setUpCompletion + if state != .unknown && completion != nil { + let myStateArgs = state.toMyArgs() + let myStateNumber = Int64(myStateArgs.rawValue) + let myArgs = MyCentralControllerArgs(myStateNumber: myStateNumber) + completion!(.success(myArgs)) + setUpCompletion = nil + } + let myStateArgs = state.toMyArgs() + let myStateNumber = Int64(myStateArgs.rawValue) + myApi.onStateChanged(myStateNumber: myStateNumber) {} + } + + + func didDiscover(_ peripheral: CBPeripheral, _ advertisementData: [String : Any], _ rssiNumber: NSNumber) { + let peripheralKey = peripheral.hash + if peripherals[peripheralKey] == nil { + peripheral.delegate = myPeripheralDelegate + peripherals[peripheralKey] = peripheral + } + let myPeripheralArgs = peripheral.toMyArgs() + let rssi = rssiNumber.int64Value + let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String + let rawManufacturerSpecificData = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data + var manufacturerSpecificData = [Int64: FlutterStandardTypedData]() + if rawManufacturerSpecificData != nil { + do { + guard let data = rawManufacturerSpecificData else { + throw MyError.illegalArgument + } + guard data.count >= 2 else { + throw MyError.illegalArgument + } + let key = Int64(data[0]) | (Int64(data[1]) << 8) + let bytes = data.count > 2 ? data[2...data.count-1] : Data() + let value = FlutterStandardTypedData(bytes: bytes) + manufacturerSpecificData[key] = value + } catch { + manufacturerSpecificData = [:] + } + } + let rawServiceUUIDs = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID] ?? [] + let serviceUUIDs = rawServiceUUIDs.map { uuid in uuid.uuidString } + let rawServiceData = advertisementData[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] ?? [:] + let elements = rawServiceData.map { (uuid, data) in + let key = uuid.uuidString + let value = FlutterStandardTypedData(bytes: data) + return (key, value) + } + let serviceData = [String?: FlutterStandardTypedData?](uniqueKeysWithValues: elements) + let myAdvertisementArgs = MyAdvertisementArgs(name: name, manufacturerSpecificData: manufacturerSpecificData, serviceUUIDs: serviceUUIDs, serviceData: serviceData) + myApi.onDiscovered(myPeripheralArgs: myPeripheralArgs, rssi: rssi, myAdvertisementArgs: myAdvertisementArgs) {} + } + + func didConnect(_ peripheral: CBPeripheral) { + let peripheralKey = peripheral.hash + let myPeripheralKey = Int64(peripheralKey) + myApi.onPeripheralStateChanged(myPeripheralKey: myPeripheralKey, state: true) {} + guard let completion = connectCompletions.removeValue(forKey: peripheralKey) else { + return + } + completion(.success(())) + } + + func didFailToConnect(_ peripheral: CBPeripheral, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = connectCompletions.removeValue(forKey: peripheralKey) else { + return + } + completion(.failure(error ?? MyError.unknown)) + } + + func didDisconnectPeripheral(_ peripheral: CBPeripheral, _ error: Error?) { + let peripheralKey = peripheral.hash + let myPeripheralKey = Int64(peripheralKey) + let discoverGattCompletion = discoverGattCompletions.removeValue(forKey: peripheralKey) + if discoverGattCompletion != nil { + discoverGattCompletion!(.failure(error ?? MyError.illegalState)) + } + let services = peripheral.services ?? [] + for service in services { + let characteristics = service.characteristics ?? [] + for characteristic in characteristics { + let characteristicKey = characteristic.hash + let readCharacteristicCompletion = readCharacteristicCompletions.removeValue(forKey: characteristicKey) + let writeCharacteristicCompletion = writeCharacteristicCompletions.removeValue(forKey: characteristicKey) + if readCharacteristicCompletion != nil { + readCharacteristicCompletion!(.failure(MyError.illegalState)) + } + if writeCharacteristicCompletion != nil { + writeCharacteristicCompletion!(.failure(MyError.illegalState)) + } + let descriptors = characteristic.descriptors ?? [] + for descriptor in descriptors { + let descriptorKey = descriptor.hash + let readDescriptorCompletion = readDescriptorCompletions.removeValue(forKey: descriptorKey) + let writeDescriptorCompletion = writeDescriptorCompletions.removeValue(forKey: descriptorKey) + if readDescriptorCompletion != nil { + readDescriptorCompletion!(.failure(MyError.illegalState)) + } + if writeDescriptorCompletion != nil { + writeDescriptorCompletion!(.failure(MyError.illegalState)) + } + } + } + } + myApi.onPeripheralStateChanged(myPeripheralKey: myPeripheralKey, state: false) {} + guard let completion = disconnectCompletions.removeValue(forKey: peripheralKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } + + + func didDiscoverServices(_ peripheral: CBPeripheral, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = discoverGattCompletions[peripheralKey] else { + return + } + if error == nil { + var services = peripheral.services ?? [] + if services.isEmpty { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.success(())) + } else { + let service = services.removeFirst() + unfinishedServices[peripheralKey] = services + peripheral.discoverCharacteristics(nil, for: service) + } + } else { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.failure(error!)) + } + } + + func didDiscoverCharacteristics(_ peripheral: CBPeripheral, _ service: CBService, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = discoverGattCompletions[peripheralKey] else { + return + } + if error == nil { + var characteristics = service.characteristics ?? [] + if characteristics.isEmpty { + var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? [] + if services.isEmpty { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.success(())) + } else { + let service = services.removeFirst() + unfinishedServices[peripheralKey] = services + peripheral.discoverCharacteristics(nil, for: service) + } + } else { + let characteristic = characteristics.removeFirst() + unfinishedCharacteristics[peripheralKey] = characteristics + peripheral.discoverDescriptors(for: characteristic) + } + } else { + discoverGattCompletions.removeValue(forKey: peripheralKey) + unfinishedServices.removeValue(forKey: peripheralKey) + completion(.failure(error!)) + } + } + + func didDiscoverDescriptors(_ peripheral: CBPeripheral, _ characteristic: CBCharacteristic, _ error: Error?) { + let peripheralKey = peripheral.hash + guard let completion = discoverGattCompletions[peripheralKey] else { + return + } + if error == nil { + var characteristics = unfinishedCharacteristics.removeValue(forKey: peripheralKey) ?? [] + if (characteristics.isEmpty) { + var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? [] + if services.isEmpty { + discoverGattCompletions.removeValue(forKey: peripheralKey) + completion(.success(())) + } else { + let service = services.removeFirst() + unfinishedServices[peripheralKey] = services + peripheral.discoverCharacteristics(nil, for: service) + } + } else { + let characteristic = characteristics.removeFirst() + unfinishedCharacteristics[peripheralKey] = characteristics + peripheral.discoverDescriptors(for: characteristic) + } + } else { + discoverGattCompletions.removeValue(forKey: peripheralKey) + unfinishedServices.removeValue(forKey: peripheralKey) + unfinishedCharacteristics.removeValue(forKey: peripheralKey) + completion(.failure(error!)) + } + } + + func didUpdateCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) { + let characteristicKey = characteristic.hash + guard let completion = readCharacteristicCompletions.removeValue(forKey: characteristicKey) else { + let myCharacteristicKey = Int64(characteristicKey) + let rawValue = characteristic.value ?? Data() + let value = FlutterStandardTypedData(bytes: rawValue) + myApi.onCharacteristicValueChanged(myCharacteristicKey: myCharacteristicKey, value: value) {} + return + } + if error == nil { + let rawValue = characteristic.value ?? Data() + let value = FlutterStandardTypedData(bytes: rawValue) + completion(.success(value)) + } else { + completion(.failure(error!)) + } + } + + func didWriteCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) { + let characteristicKey = characteristic.hash + guard let completion = writeCharacteristicCompletions.removeValue(forKey: characteristicKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } + + func didUpdateNotificationState(_ characteristic: CBCharacteristic, _ error: Error?) { + let characteristicKey = characteristic.hash + guard let completion = notifyCharacteristicCompletions.removeValue(forKey: characteristicKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } + + func didUpdateDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) { + let descriptorKey = descriptor.hash + guard let completion = readDescriptorCompletions.removeValue(forKey: descriptorKey) else { + return + } + if error == nil { + // TODO: Need to confirm wheather the corresponding descriptor type and value is correct. + let value: FlutterStandardTypedData + let rawValue = descriptor.value + do { + switch descriptor.uuid.uuidString { + case CBUUIDCharacteristicExtendedPropertiesString: + fallthrough + case CBUUIDClientCharacteristicConfigurationString: + fallthrough + case CBUUIDServerCharacteristicConfigurationString: + guard let rawNumber = rawValue as? NSNumber else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawNumber.data) + case CBUUIDCharacteristicUserDescriptionString: + fallthrough + case CBUUIDCharacteristicAggregateFormatString: + guard let rawString = rawValue as? String else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawString.data) + case CBUUIDCharacteristicFormatString: + guard let rawData = rawValue as? Data else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawData) + case CBUUIDL2CAPPSMCharacteristicString: + guard let rawU16 = rawValue as? UInt16 else { + throw MyError.illegalArgument + } + value = FlutterStandardTypedData(bytes: rawU16.data) + default: + throw MyError.illegalArgument + } + } catch { + value = FlutterStandardTypedData() + } + completion(.success((value))) + } else { + completion(.failure(error!)) + } + } + + func didWriteDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) { + let descriptorKey = descriptor.hash + guard let completion = writeDescriptorCompletions.removeValue(forKey: descriptorKey) else { + return + } + if error == nil { + completion(.success(())) + } else { + completion(.failure(error!)) + } + } +} + +extension CBManagerState { + func toMyArgs() -> MyCentralStateArgs { + switch self { + case .unauthorized: + return .unauthorized + case .poweredOff: + return .poweredOff + case .poweredOn: + return .poweredOn + default: + return .unsupported + } + } +} + +extension CBPeripheral { + func toMyArgs() -> MyPeripheralArgs { + let key = Int64(hash) + let uuid = identifier.uuidString + return MyPeripheralArgs(key: key, uuid: uuid) + } +} + +extension CBService { + func toMyArgs() -> MyGattServiceArgs { + let key = Int64(hash) + let uuid = uuid.uuidString + return MyGattServiceArgs(key: key, uuid: uuid) + } +} + +extension CBCharacteristic { + func toMyArgs() -> MyGattCharacteristicArgs { + let key = Int64(hash) + let uuid = uuid.uuidString + let myPropertyArgses = properties.toMyArgses() + let myPropertyNumbers = myPropertyArgses.map { myPropertyArgs in Int64(myPropertyArgs.rawValue) } + return MyGattCharacteristicArgs(key: key, uuid: uuid, myPropertyNumbers: myPropertyNumbers) + } +} + +extension CBDescriptor { + func toMyArgs() -> MyGattDescriptorArgs { + let key = Int64(hash) + let uuid = uuid.uuidString + return MyGattDescriptorArgs(key: key, uuid: uuid) + } +} + +extension CBCharacteristicProperties { + func toMyArgses() -> [MyGattCharacteristicPropertyArgs] { + var myPropertyArgs = [MyGattCharacteristicPropertyArgs]() + if contains(.read) { + myPropertyArgs.append(.read) + } + if contains(.write) { + myPropertyArgs.append(.write) + } + if contains(.writeWithoutResponse) { + myPropertyArgs.append(.writeWithoutResponse) + } + if contains(.notify) { + myPropertyArgs.append(.notify) + } + if contains(.indicate) { + myPropertyArgs.append(.indicate) + } + return myPropertyArgs + } +} + +extension MyGattCharacteristicWriteTypeArgs { + func toType() -> CBCharacteristicWriteType { + switch self { + case .withResponse: + return .withResponse + case .withoutResponse: + return .withoutResponse + } + } +} + +extension NSNumber { + var data: Data { + var source = self + return Data(bytes: &source, count: MemoryLayout.size) + } +} + +extension String { + var data: Data { + return data(using: String.Encoding.utf8)! + } +} + +extension UInt16 { + var data: Data { + var source = self + return Data(bytes: &source, count: MemoryLayout.size) + } +} diff --git a/bluetooth_low_energy_macos/macos/Classes/MyCentralManagerDelegate.swift b/bluetooth_low_energy_macos/macos/Classes/MyCentralManagerDelegate.swift new file mode 100644 index 0000000..4a85ff8 --- /dev/null +++ b/bluetooth_low_energy_macos/macos/Classes/MyCentralManagerDelegate.swift @@ -0,0 +1,38 @@ +// +// MyCentralManagerDelegate.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation +import CoreBluetooth + +class MyCentralManagerDelegate: NSObject, CBCentralManagerDelegate { + private let myCentralController: MyCentralController + + init(_ myCentralController: MyCentralController) { + self.myCentralController = myCentralController + } + + func centralManagerDidUpdateState(_ central: CBCentralManager) { + let state = central.state + myCentralController.didUpdateState(state) + } + + func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { + myCentralController.didDiscover(peripheral, advertisementData, RSSI) + } + + func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { + myCentralController.didConnect(peripheral) + } + + func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { + myCentralController.didFailToConnect(peripheral, error) + } + + func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { + myCentralController.didDisconnectPeripheral(peripheral, error) + } +} diff --git a/bluetooth_low_energy_macos/macos/Classes/MyError.swift b/bluetooth_low_energy_macos/macos/Classes/MyError.swift new file mode 100644 index 0000000..12068c0 --- /dev/null +++ b/bluetooth_low_energy_macos/macos/Classes/MyError.swift @@ -0,0 +1,14 @@ +// +// MyError.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation + +enum MyError: Error { + case illegalArgument + case illegalState + case unknown +} diff --git a/bluetooth_low_energy_macos/macos/Classes/MyPeripheralDelegate.swift b/bluetooth_low_energy_macos/macos/Classes/MyPeripheralDelegate.swift new file mode 100644 index 0000000..5915d9b --- /dev/null +++ b/bluetooth_low_energy_macos/macos/Classes/MyPeripheralDelegate.swift @@ -0,0 +1,49 @@ +// +// MyPeripheralDelegate.swift +// bluetooth_low_energy_ios +// +// Created by 闫守旺 on 2023/8/13. +// + +import Foundation +import CoreBluetooth + +class MyPeripheralDelegate: NSObject, CBPeripheralDelegate { + private let myCentralController: MyCentralController + + init(_ myCentralController: MyCentralController) { + self.myCentralController = myCentralController + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { + myCentralController.didDiscoverServices(peripheral, error) + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { + myCentralController.didDiscoverCharacteristics(peripheral, service, error) + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didDiscoverDescriptors(peripheral, characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didUpdateCharacteristicValue(characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didWriteCharacteristicValue(characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) { + myCentralController.didUpdateNotificationState(characteristic, error) + } + + func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) { + myCentralController.didUpdateDescriptorValue(descriptor, error) + } + + func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) { + myCentralController.didWriteDescriptorValue(descriptor, error) + } +} diff --git a/bluetooth_low_energy_macos/macos/bluetooth_low_energy_macos.podspec b/bluetooth_low_energy_macos/macos/bluetooth_low_energy_macos.podspec new file mode 100644 index 0000000..33ca37f --- /dev/null +++ b/bluetooth_low_energy_macos/macos/bluetooth_low_energy_macos.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint bluetooth_low_energy_macos.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'bluetooth_low_energy_macos' + s.version = '0.0.1' + s.summary = 'A new Flutter plugin project.' + s.description = <<-DESC +A new Flutter plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'FlutterMacOS' + + s.platform = :osx, '10.11' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '5.0' +end diff --git a/bluetooth_low_energy_macos/my_api.dart b/bluetooth_low_energy_macos/my_api.dart new file mode 100644 index 0000000..b304c8a --- /dev/null +++ b/bluetooth_low_energy_macos/my_api.dart @@ -0,0 +1,140 @@ +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/src/my_api.g.dart', + dartOptions: DartOptions(), + swiftOut: 'macos/Classes/MyApi.g.swift', + swiftOptions: SwiftOptions(), + ), +) +@HostApi() +abstract class MyCentralControllerHostApi { + @async + MyCentralControllerArgs setUp(); + void tearDown(); + void startDiscovery(); + void stopDiscovery(); + @async + void connect(int myPeripheralKey); + @async + void disconnect(int myPeripheralKey); + @async + void discoverGATT(int myPeripheralKey); + List getServices(int myPeripheralKey); + List getCharacteristics(int myServiceKey); + List getDescriptors(int myCharacteristicKey); + @async + Uint8List readCharacteristic(int myPeripheralKey, int myCharacteristicKey); + @async + void writeCharacteristic( + int myPeripheralKey, + int myCharacteristicKey, + Uint8List value, + int myTypeNumber, + ); + @async + void notifyCharacteristic( + int myPeripheralKey, + int myCharacteristicKey, + bool state, + ); + @async + Uint8List readDescriptor(int myPeripheralKey, int myDescriptorKey); + @async + void writeDescriptor( + int myPeripheralKey, + int myDescriptorKey, + Uint8List value, + ); +} + +@FlutterApi() +abstract class MyCentralControllerFlutterApi { + void onStateChanged(int myStateNumber); + void onDiscovered( + MyPeripheralArgs myPeripheralArgs, + int rssi, + MyAdvertisementArgs myAdvertisementArgs, + ); + void onPeripheralStateChanged(int myPeripheralKey, bool state); + void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value); +} + +class MyCentralControllerArgs { + final int myStateNumber; + + MyCentralControllerArgs(this.myStateNumber); +} + +class MyPeripheralArgs { + final int key; + final String uuid; + + MyPeripheralArgs(this.key, this.uuid); +} + +class MyAdvertisementArgs { + final String? name; + final Map manufacturerSpecificData; + final List serviceUUIDs; + final Map serviceData; + + MyAdvertisementArgs( + this.name, + this.manufacturerSpecificData, + this.serviceUUIDs, + this.serviceData, + ); +} + +class MyGattServiceArgs { + final int key; + final String uuid; + + MyGattServiceArgs(this.key, this.uuid); +} + +class MyGattCharacteristicArgs { + final int key; + final String uuid; + final List myPropertyNumbers; + + MyGattCharacteristicArgs( + this.key, + this.uuid, + this.myPropertyNumbers, + ); +} + +class MyGattDescriptorArgs { + final int key; + final String uuid; + + MyGattDescriptorArgs(this.key, this.uuid); +} + +enum MyCentralStateArgs { + unknown, + unsupported, + unauthorized, + poweredOff, + poweredOn, +} + +enum MyGattCharacteristicPropertyArgs { + read, + write, + writeWithoutResponse, + notify, + indicate, +} + +enum MyGattCharacteristicWriteTypeArgs { + // Write with response + withResponse, + // Write without response + withoutResponse, + // Write with response and waiting for confirmation + // reliable, +} diff --git a/bluetooth_low_energy_macos/pubspec.yaml b/bluetooth_low_energy_macos/pubspec.yaml new file mode 100644 index 0000000..b16f428 --- /dev/null +++ b/bluetooth_low_energy_macos/pubspec.yaml @@ -0,0 +1,27 @@ +name: bluetooth_low_energy_macos +description: macOS implementation of the bluetooth_low_energy plugin. +version: 2.0.0 +homepage: https://github.com/yanshouwang/bluetooth_low_energy + +environment: + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + bluetooth_low_energy_platform_interface: + path: ../bluetooth_low_energy_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + pigeon: ^10.1.6 + +flutter: + plugin: + platforms: + macos: + pluginClass: BluetoothLowEnergymacOS + dartPluginClass: BluetoothLowEnergymacOS diff --git a/bluetooth_low_energy_platform_interface/.gitignore b/bluetooth_low_energy_platform_interface/.gitignore new file mode 100644 index 0000000..96486fd --- /dev/null +++ b/bluetooth_low_energy_platform_interface/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/bluetooth_low_energy_platform_interface/.metadata b/bluetooth_low_energy_platform_interface/.metadata new file mode 100644 index 0000000..cedd661 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/.metadata @@ -0,0 +1,27 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/bluetooth_low_energy_platform_interface/CHANGELOG.md b/bluetooth_low_energy_platform_interface/CHANGELOG.md new file mode 100644 index 0000000..e510273 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/CHANGELOG.md @@ -0,0 +1,4 @@ +## 2.0.0 + +- Rewrite the whole project with federated plugins. +- Support macOS and Linux. diff --git a/bluetooth_low_energy_platform_interface/LICENSE b/bluetooth_low_energy_platform_interface/LICENSE new file mode 100644 index 0000000..515ed4b --- /dev/null +++ b/bluetooth_low_energy_platform_interface/LICENSE @@ -0,0 +1,21 @@ +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. \ No newline at end of file diff --git a/bluetooth_low_energy_platform_interface/README.md b/bluetooth_low_energy_platform_interface/README.md new file mode 100644 index 0000000..589a8f2 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/README.md @@ -0,0 +1,26 @@ +# bluetooth_low_energy_platform_interface + +A common platform interface for the [`bluetooth_low_energy`][1] plugin. + +This interface allows platform-specific implementations of the `bluetooth_low_energy` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. + +# Usage + +To implement a new platform-specific implementation of `bluetooth_low_energy`, extend +[`CentralController`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`CentralController` by calling +`CentralController.instance = MyCentralController()`. + +# Note on breaking changes + +Strongly prefer non-breaking changes (such as adding a method to the interface) +over breaking changes for this package. + +See https://flutter.dev/go/platform-interface-breaking-changes for a discussion +on why a less-clean interface is preferable to a breaking change. + +[1]: https://pub.dev/packages/bluetooth_low_energy +[2]: lib/src/central_controller.dart diff --git a/bluetooth_low_energy_platform_interface/analysis_options.yaml b/bluetooth_low_energy_platform_interface/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/bluetooth_low_energy_platform_interface/lib/bluetooth_low_energy_platform_interface.dart b/bluetooth_low_energy_platform_interface/lib/bluetooth_low_energy_platform_interface.dart new file mode 100644 index 0000000..38fd598 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/bluetooth_low_energy_platform_interface.dart @@ -0,0 +1,12 @@ +export 'src/errors.dart'; +export 'src/event_args.dart'; +export 'src/central_controller.dart'; +export 'src/central_state.dart'; +export 'src/peripheral.dart'; +export 'src/uuid.dart'; +export 'src/advertisement.dart'; +export 'src/gatt_service.dart'; +export 'src/gatt_characteristic.dart'; +export 'src/gatt_characteristic_property.dart'; +export 'src/gatt_characteristic_write_type.dart'; +export 'src/gatt_descriptor.dart'; diff --git a/bluetooth_low_energy_platform_interface/lib/src/advertisement.dart b/bluetooth_low_energy_platform_interface/lib/src/advertisement.dart new file mode 100644 index 0000000..2be8b0e --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/advertisement.dart @@ -0,0 +1,17 @@ +import 'dart:typed_data'; + +import 'uuid.dart'; + +class Advertisement { + final String? name; + final Map manufacturerSpecificData; + final List serviceUUIDs; + final Map serviceData; + + Advertisement({ + this.name, + this.manufacturerSpecificData = const {}, + this.serviceUUIDs = const [], + this.serviceData = const {}, + }); +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/central_controller.dart b/bluetooth_low_energy_platform_interface/lib/src/central_controller.dart new file mode 100644 index 0000000..b736d5b --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/central_controller.dart @@ -0,0 +1,74 @@ +import 'dart:typed_data'; + +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'central_state.dart'; +import 'event_args.dart'; +import 'gatt_characteristic.dart'; +import 'gatt_characteristic_write_type.dart'; +import 'gatt_descriptor.dart'; +import 'gatt_service.dart'; +import 'peripheral.dart'; + +abstract class CentralController extends PlatformInterface { + /// Constructs a [CentralController]. + CentralController() : super(token: _token); + + static final Object _token = Object(); + + static CentralController? _instance; + + /// The default instance of [CentralController] to use. + static CentralController get instance { + final instance = _instance; + if (instance == null) { + const message = + '`BluetoothLowEnergy` is not implemented on this platform.'; + throw UnimplementedError(message); + } + return instance; + } + + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [CentralController] when + /// they register themselves. + static set instance(CentralController instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + CentralState get state; + Stream get stateChanged; + Stream get discovered; + Stream get peripheralStateChanged; + Stream + get characteristicValueChanged; + + Future setUp(); + Future tearDown(); + Future startDiscovery(); + Future stopDiscovery(); + Future connect(Peripheral peripheral); + Future disconnect(Peripheral peripheral); + Future discoverGATT(Peripheral peripheral); + Future> getServices(Peripheral peripheral); + Future> getCharacteristics(GattService service); + Future> getDescriptors( + GattCharacteristic characteristic, + ); + Future readCharacteristic(GattCharacteristic characteristic); + Future writeCharacteristic( + GattCharacteristic characteristic, { + required Uint8List value, + required GattCharacteristicWriteType type, + }); + Future notifyCharacteristic( + GattCharacteristic characteristic, { + required bool state, + }); + Future readDescriptor(GattDescriptor descriptor); + Future writeDescriptor( + GattDescriptor descriptor, { + required Uint8List value, + }); +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/central_state.dart b/bluetooth_low_energy_platform_interface/lib/src/central_state.dart new file mode 100644 index 0000000..da785e2 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/central_state.dart @@ -0,0 +1,7 @@ +enum CentralState { + unknown, + unsupported, + unauthorized, + poweredOff, + poweredOn, +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/errors.dart b/bluetooth_low_energy_platform_interface/lib/src/errors.dart new file mode 100644 index 0000000..63e1c23 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/errors.dart @@ -0,0 +1,10 @@ +class BluetoothLowEnergyError extends Error { + final String message; + + BluetoothLowEnergyError(this.message); + + @override + String toString() { + return 'BluetoothLowEnergyError: $message'; + } +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/event_args.dart b/bluetooth_low_energy_platform_interface/lib/src/event_args.dart new file mode 100644 index 0000000..fbd6135 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/event_args.dart @@ -0,0 +1,36 @@ +import 'dart:typed_data'; + +import 'advertisement.dart'; +import 'central_state.dart'; +import 'gatt_characteristic.dart'; +import 'peripheral.dart'; + +abstract class EventArgs {} + +class CentralStateChangedEventArgs extends EventArgs { + final CentralState state; + + CentralStateChangedEventArgs(this.state); +} + +class CentralDiscoveredEventArgs extends EventArgs { + final Peripheral peripheral; + final int rssi; + final Advertisement advertisement; + + CentralDiscoveredEventArgs(this.peripheral, this.rssi, this.advertisement); +} + +class PeripheralStateChangedEventArgs extends EventArgs { + final Peripheral peripheral; + final bool state; + + PeripheralStateChangedEventArgs(this.peripheral, this.state); +} + +class GattCharacteristicValueChangedEventArgs extends EventArgs { + final GattCharacteristic characteristic; + final Uint8List value; + + GattCharacteristicValueChangedEventArgs(this.characteristic, this.value); +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart new file mode 100644 index 0000000..56b7d9c --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart @@ -0,0 +1,12 @@ +import 'gatt_characteristic_property.dart'; +import 'uuid.dart'; + +class GattCharacteristic { + final UUID uuid; + final List properties; + + GattCharacteristic({ + required this.uuid, + required this.properties, + }); +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_property.dart b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_property.dart new file mode 100644 index 0000000..d92d32e --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_property.dart @@ -0,0 +1,7 @@ +enum GattCharacteristicProperty { + read, + write, + writeWithoutResponse, + notify, + indicate, +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_write_type.dart b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_write_type.dart new file mode 100644 index 0000000..2d98c0b --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic_write_type.dart @@ -0,0 +1,8 @@ +enum GattCharacteristicWriteType { + // Write with response + withResponse, + // Write without response + withoutResponse, + // Write with response and waiting for confirmation + // reliable, +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart b/bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart new file mode 100644 index 0000000..cabf602 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart @@ -0,0 +1,9 @@ +import 'uuid.dart'; + +class GattDescriptor { + final UUID uuid; + + GattDescriptor({ + required this.uuid, + }); +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/gatt_service.dart b/bluetooth_low_energy_platform_interface/lib/src/gatt_service.dart new file mode 100644 index 0000000..10c2d40 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/gatt_service.dart @@ -0,0 +1,9 @@ +import 'uuid.dart'; + +class GattService { + final UUID uuid; + + GattService({ + required this.uuid, + }); +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/peripheral.dart b/bluetooth_low_energy_platform_interface/lib/src/peripheral.dart new file mode 100644 index 0000000..07ae1f5 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/peripheral.dart @@ -0,0 +1,5 @@ +import 'uuid.dart'; + +abstract class Peripheral { + UUID get uuid; +} diff --git a/bluetooth_low_energy_platform_interface/lib/src/uuid.dart b/bluetooth_low_energy_platform_interface/lib/src/uuid.dart new file mode 100644 index 0000000..90a8a93 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/lib/src/uuid.dart @@ -0,0 +1,141 @@ +/// 128 bit universally unique identifier used in Bluetooth. +class UUID { + /// The value of the UUID in 16 bytes. + final List value; + + /// True if the UUID is a short (16 or 32 bit) encoded UUID. + bool get isShort => + value[4] == 0x00 && + value[5] == 0x00 && + value[6] == 0x10 && + value[7] == 0x00 && + value[8] == 0x80 && + value[9] == 0x00 && + value[10] == 0x00 && + value[11] == 0x80 && + value[12] == 0x5f && + value[13] == 0x9b && + value[14] == 0x34 && + value[15] == 0xfb; + + /// Creates a new UUID from 16 bytes. + UUID(Iterable value) : value = value.toList() { + if (value.length != 16) { + throw const FormatException('Invalid length UUID'); + } + } + + // Creates a new Bluetooth UUID from the short (16 or 32 bit) encoding. + UUID.short(int shortValue) + : value = [ + (shortValue >> 24) & 0xff, + (shortValue >> 16) & 0xff, + (shortValue >> 8) & 0xff, + (shortValue >> 0) & 0xff, + 0x00, + 0x00, + 0x10, + 0x00, + 0x80, + 0x00, + 0x00, + 0x80, + 0x5f, + 0x9b, + 0x34, + 0xfb + ]; + + /// Creates a new UUID from the string format encoding (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx where xx is a hexadecimal number). + factory UUID.fromString(String value) { + if (value.length == 4) { + try { + final shortValue = int.parse(value, radix: 16); + return UUID.short(shortValue); + } catch (e) { + throw const FormatException('Invalid UUID string'); + } + } + var groups = value.split('-'); + if (groups.length != 5 || + groups[0].length != 8 || + groups[1].length != 4 || + groups[2].length != 4 || + groups[3].length != 4 || + groups[4].length != 12) { + throw const FormatException('Invalid UUID string'); + } + int group0, group1, group2, group3, group4; + try { + group0 = int.parse(groups[0], radix: 16); + group1 = int.parse(groups[1], radix: 16); + group2 = int.parse(groups[2], radix: 16); + group3 = int.parse(groups[3], radix: 16); + group4 = int.parse(groups[4], radix: 16); + } catch (e) { + throw const FormatException('Invalid UUID string'); + } + return UUID([ + (group0 >> 24) & 0xff, + (group0 >> 16) & 0xff, + (group0 >> 8) & 0xff, + (group0 >> 0) & 0xff, + (group1 >> 8) & 0xff, + (group1 >> 0) & 0xff, + (group2 >> 8) & 0xff, + (group2 >> 0) & 0xff, + (group3 >> 8) & 0xff, + (group3 >> 0) & 0xff, + (group4 >> 40) & 0xff, + (group4 >> 32) & 0xff, + (group4 >> 24) & 0xff, + (group4 >> 16) & 0xff, + (group4 >> 8) & 0xff, + (group4 >> 0) & 0xff + ]); + } + + @override + String toString() { + var v0 = value[0].toRadixString(16).padLeft(2, '0'); + var v1 = value[1].toRadixString(16).padLeft(2, '0'); + var v2 = value[2].toRadixString(16).padLeft(2, '0'); + var v3 = value[3].toRadixString(16).padLeft(2, '0'); + var v4 = value[4].toRadixString(16).padLeft(2, '0'); + var v5 = value[5].toRadixString(16).padLeft(2, '0'); + var v6 = value[6].toRadixString(16).padLeft(2, '0'); + var v7 = value[7].toRadixString(16).padLeft(2, '0'); + var v8 = value[8].toRadixString(16).padLeft(2, '0'); + var v9 = value[9].toRadixString(16).padLeft(2, '0'); + var v10 = value[10].toRadixString(16).padLeft(2, '0'); + var v11 = value[11].toRadixString(16).padLeft(2, '0'); + var v12 = value[12].toRadixString(16).padLeft(2, '0'); + var v13 = value[13].toRadixString(16).padLeft(2, '0'); + var v14 = value[14].toRadixString(16).padLeft(2, '0'); + var v15 = value[15].toRadixString(16).padLeft(2, '0'); + return '$v0$v1$v2$v3-$v4$v5-$v6$v7-$v8$v9-$v10$v11$v12$v13$v14$v15'; + } + + @override + bool operator ==(other) => + other is UUID && + other.value[0] == value[0] && + other.value[1] == value[1] && + other.value[2] == value[2] && + other.value[3] == value[3] && + other.value[4] == value[4] && + other.value[5] == value[5] && + other.value[6] == value[6] && + other.value[7] == value[7] && + other.value[8] == value[8] && + other.value[9] == value[9] && + other.value[10] == value[10] && + other.value[11] == value[11] && + other.value[12] == value[12] && + other.value[13] == value[13] && + other.value[14] == value[14] && + other.value[15] == value[15]; + + @override + int get hashCode => value.fold(17, (prev, value) => 37 * prev + value); +} diff --git a/bluetooth_low_energy_platform_interface/pubspec.yaml b/bluetooth_low_energy_platform_interface/pubspec.yaml new file mode 100644 index 0000000..b09dc24 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/pubspec.yaml @@ -0,0 +1,18 @@ +name: bluetooth_low_energy_platform_interface +description: A common platform interface for the bluetooth_low_energy plugin. +version: 2.0.0 +homepage: https://github.com/yanshouwang/bluetooth_low_energy + +environment: + sdk: '>=3.0.0 <4.0.0' + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^2.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 diff --git a/bluetooth_low_energy_platform_interface/test/bluetooth_low_energy_platform_interface_test.dart b/bluetooth_low_energy_platform_interface/test/bluetooth_low_energy_platform_interface_test.dart new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/bluetooth_low_energy_platform_interface/test/bluetooth_low_energy_platform_interface_test.dart @@ -0,0 +1 @@ + diff --git a/bluetooth_low_energy_windows/.gitignore b/bluetooth_low_energy_windows/.gitignore new file mode 100644 index 0000000..96486fd --- /dev/null +++ b/bluetooth_low_energy_windows/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/bluetooth_low_energy_windows/.metadata b/bluetooth_low_energy_windows/.metadata new file mode 100644 index 0000000..a0dc8d7 --- /dev/null +++ b/bluetooth_low_energy_windows/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: windows + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/bluetooth_low_energy_windows/CHANGELOG.md b/bluetooth_low_energy_windows/CHANGELOG.md new file mode 100644 index 0000000..e510273 --- /dev/null +++ b/bluetooth_low_energy_windows/CHANGELOG.md @@ -0,0 +1,4 @@ +## 2.0.0 + +- Rewrite the whole project with federated plugins. +- Support macOS and Linux. diff --git a/bluetooth_low_energy_windows/LICENSE b/bluetooth_low_energy_windows/LICENSE new file mode 100644 index 0000000..515ed4b --- /dev/null +++ b/bluetooth_low_energy_windows/LICENSE @@ -0,0 +1,21 @@ +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. \ No newline at end of file diff --git a/bluetooth_low_energy_windows/README.md b/bluetooth_low_energy_windows/README.md new file mode 100644 index 0000000..6f74085 --- /dev/null +++ b/bluetooth_low_energy_windows/README.md @@ -0,0 +1,15 @@ +# bluetooth_low_energy_windows + +The Windows implementation of [`bluetooth_low_energy`][1]. + +## Usage + +This package is [endorsed][2], which means you can simply use `bluetooth_low_energy` +normally. This package will be automatically included in your app when you do, +so you do not need to add it to your `pubspec.yaml`. + +However, if you `import` this package to use any of its APIs directly, you +should add it to your `pubspec.yaml` as usual. + +[1]: https://pub.dev/packages/bluetooth_low_energy +[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin diff --git a/bluetooth_low_energy_windows/analysis_options.yaml b/bluetooth_low_energy_windows/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/bluetooth_low_energy_windows/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/bluetooth_low_energy_windows/lib/bluetooth_low_energy_windows.dart b/bluetooth_low_energy_windows/lib/bluetooth_low_energy_windows.dart new file mode 100644 index 0000000..52ed4d9 --- /dev/null +++ b/bluetooth_low_energy_windows/lib/bluetooth_low_energy_windows.dart @@ -0,0 +1,9 @@ +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; + +import 'src/my_central_controller.dart'; + +abstract class BluetoothLowEnergyWindows { + static void registerWith() { + CentralController.instance = MyCentralController(); + } +} diff --git a/bluetooth_low_energy_windows/lib/src/my_central_controller.dart b/bluetooth_low_energy_windows/lib/src/my_central_controller.dart new file mode 100644 index 0000000..15a8663 --- /dev/null +++ b/bluetooth_low_energy_windows/lib/src/my_central_controller.dart @@ -0,0 +1,120 @@ +import 'dart:typed_data'; + +import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart'; +import 'package:win32/win32.dart' as win32; + +class MyCentralController extends CentralController { + @override + // TODO: implement state + CentralState get state => throw UnimplementedError(); + @override + // TODO: implement stateChanged + Stream get stateChanged => + throw UnimplementedError(); + @override + // TODO: implement discovered + Stream get discovered => + throw UnimplementedError(); + @override + // TODO: implement peripheralStateChanged + Stream get peripheralStateChanged => + throw UnimplementedError(); + @override + // TODO: implement characteristicValueChanged + Stream + get characteristicValueChanged => throw UnimplementedError(); + + @override + Future setUp() { + // TODO: implement setUp + throw UnimplementedError(); + } + + @override + Future tearDown() { + // TODO: implement tearDown + throw UnimplementedError(); + } + + @override + Future startDiscovery() { + // TODO: implement startDiscovery + throw UnimplementedError(); + } + + @override + Future stopDiscovery() { + // TODO: implement stopDiscovery + throw UnimplementedError(); + } + + @override + Future connect(Peripheral peripheral) { + // TODO: implement connect + throw UnimplementedError(); + } + + @override + Future disconnect(Peripheral peripheral) { + // TODO: implement disconnect + throw UnimplementedError(); + } + + @override + Future discoverGATT(Peripheral peripheral) { + // TODO: implement discoverGATT + throw UnimplementedError(); + } + + @override + Future> getServices(Peripheral peripheral) { + // TODO: implement getServices + throw UnimplementedError(); + } + + @override + Future> getCharacteristics(GattService service) { + // TODO: implement getCharacteristics + throw UnimplementedError(); + } + + @override + Future> getDescriptors( + GattCharacteristic characteristic) { + // TODO: implement getDescriptors + throw UnimplementedError(); + } + + @override + Future readCharacteristic(GattCharacteristic characteristic) { + // TODO: implement readCharacteristic + throw UnimplementedError(); + } + + @override + Future writeCharacteristic(GattCharacteristic characteristic, + {required Uint8List value, required GattCharacteristicWriteType type}) { + // TODO: implement writeCharacteristic + throw UnimplementedError(); + } + + @override + Future notifyCharacteristic(GattCharacteristic characteristic, + {required bool state}) { + // TODO: implement notifyCharacteristic + throw UnimplementedError(); + } + + @override + Future readDescriptor(GattDescriptor descriptor) { + // TODO: implement readDescriptor + throw UnimplementedError(); + } + + @override + Future writeDescriptor(GattDescriptor descriptor, + {required Uint8List value}) { + // TODO: implement writeDescriptor + throw UnimplementedError(); + } +} diff --git a/bluetooth_low_energy_windows/pubspec.yaml b/bluetooth_low_energy_windows/pubspec.yaml new file mode 100644 index 0000000..6eda674 --- /dev/null +++ b/bluetooth_low_energy_windows/pubspec.yaml @@ -0,0 +1,28 @@ +name: bluetooth_low_energy_windows +description: Windows implementation of the bluetooth_low_energy plugin. +version: 2.0.0 +homepage: https://github.com/yanshouwang/bluetooth_low_energy + +environment: + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + bluetooth_low_energy_platform_interface: + path: ../bluetooth_low_energy_platform_interface + win32: ^5.0.6 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + +flutter: + plugin: + implements: bluetooth_low_energy + platforms: + windows: + pluginClass: BluetoothLowEnergyWindowsPluginCApi + dartPluginClass: BluetoothLowEnergyWindows diff --git a/bluetooth_low_energy_windows/windows/.gitignore b/bluetooth_low_energy_windows/windows/.gitignore new file mode 100644 index 0000000..b3eb2be --- /dev/null +++ b/bluetooth_low_energy_windows/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/bluetooth_low_energy_windows/windows/CMakeLists.txt b/bluetooth_low_energy_windows/windows/CMakeLists.txt new file mode 100644 index 0000000..038bd7c --- /dev/null +++ b/bluetooth_low_energy_windows/windows/CMakeLists.txt @@ -0,0 +1,53 @@ +# The Flutter tooling requires that developers have a version of Visual Studio +# installed that includes CMake 3.14 or later. You should not increase this +# version, as doing so will cause the plugin to fail to compile for some +# customers of the plugin. +cmake_minimum_required(VERSION 3.14) + +# Project-level configuration. +set(PROJECT_NAME "bluetooth_low_energy_windows") +project(${PROJECT_NAME} LANGUAGES CXX) + +# This value is used when generating builds using this plugin, so it must +# not be changed +set(PLUGIN_NAME "bluetooth_low_energy_windows_plugin") + +# Any new source files that you add to the plugin should be added here. +list(APPEND PLUGIN_SOURCES + "bluetooth_low_energy_windows_plugin.cpp" + "bluetooth_low_energy_windows_plugin.h" +) + +# Define the plugin library target. Its name must not be changed (see comment +# on PLUGIN_NAME above). +add_library(${PLUGIN_NAME} SHARED + "include/bluetooth_low_energy_windows/bluetooth_low_energy_windows_plugin_c_api.h" + "bluetooth_low_energy_windows_plugin_c_api.cpp" + ${PLUGIN_SOURCES} +) + +# Apply a standard set of build settings that are configured in the +# application-level CMakeLists.txt. This can be removed for plugins that want +# full control over build settings. +apply_standard_settings(${PLUGIN_NAME}) + +# Symbols are hidden by default to reduce the chance of accidental conflicts +# between plugins. This should not be removed; any symbols that should be +# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro. +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) + +# Source include directories and library dependencies. Add any plugin-specific +# dependencies here. +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) + +# List of absolute paths to libraries that should be bundled with the plugin. +# This list could contain prebuilt libraries, or libraries created by an +# external build triggered from this build file. +set(bluetooth_low_energy_windows_bundled_libraries + "" + PARENT_SCOPE +) diff --git a/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.cpp b/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.cpp new file mode 100644 index 0000000..aa3a4f4 --- /dev/null +++ b/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.cpp @@ -0,0 +1,59 @@ +#include "bluetooth_low_energy_windows_plugin.h" + +// This must be included before many other Windows headers. +#include + +// For getPlatformVersion; remove unless needed for your plugin implementation. +#include + +#include +#include +#include + +#include +#include + +namespace bluetooth_low_energy_windows { + +// static +void BluetoothLowEnergyWindowsPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarWindows *registrar) { + auto channel = + std::make_unique>( + registrar->messenger(), "bluetooth_low_energy_windows", + &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(); + + channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + + registrar->AddPlugin(std::move(plugin)); +} + +BluetoothLowEnergyWindowsPlugin::BluetoothLowEnergyWindowsPlugin() {} + +BluetoothLowEnergyWindowsPlugin::~BluetoothLowEnergyWindowsPlugin() {} + +void BluetoothLowEnergyWindowsPlugin::HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result) { + if (method_call.method_name().compare("getPlatformVersion") == 0) { + std::ostringstream version_stream; + version_stream << "Windows "; + if (IsWindows10OrGreater()) { + version_stream << "10+"; + } else if (IsWindows8OrGreater()) { + version_stream << "8"; + } else if (IsWindows7OrGreater()) { + version_stream << "7"; + } + result->Success(flutter::EncodableValue(version_stream.str())); + } else { + result->NotImplemented(); + } +} + +} // namespace bluetooth_low_energy_windows diff --git a/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.h b/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.h new file mode 100644 index 0000000..adfae78 --- /dev/null +++ b/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin.h @@ -0,0 +1,32 @@ +#ifndef FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_WINDOWS_PLUGIN_H_ +#define FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_WINDOWS_PLUGIN_H_ + +#include +#include + +#include + +namespace bluetooth_low_energy_windows { + +class BluetoothLowEnergyWindowsPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar); + + BluetoothLowEnergyWindowsPlugin(); + + virtual ~BluetoothLowEnergyWindowsPlugin(); + + // Disallow copy and assign. + BluetoothLowEnergyWindowsPlugin(const BluetoothLowEnergyWindowsPlugin&) = delete; + BluetoothLowEnergyWindowsPlugin& operator=(const BluetoothLowEnergyWindowsPlugin&) = delete; + + private: + // Called when a method is called on this plugin's channel from Dart. + void HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result); +}; + +} // namespace bluetooth_low_energy_windows + +#endif // FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_WINDOWS_PLUGIN_H_ diff --git a/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin_c_api.cpp b/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin_c_api.cpp new file mode 100644 index 0000000..e3196d5 --- /dev/null +++ b/bluetooth_low_energy_windows/windows/bluetooth_low_energy_windows_plugin_c_api.cpp @@ -0,0 +1,12 @@ +#include "include/bluetooth_low_energy_windows/bluetooth_low_energy_windows_plugin_c_api.h" + +#include + +#include "bluetooth_low_energy_windows_plugin.h" + +void BluetoothLowEnergyWindowsPluginCApiRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + bluetooth_low_energy_windows::BluetoothLowEnergyWindowsPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +} diff --git a/bluetooth_low_energy_windows/windows/include/bluetooth_low_energy_windows/bluetooth_low_energy_windows_plugin_c_api.h b/bluetooth_low_energy_windows/windows/include/bluetooth_low_energy_windows/bluetooth_low_energy_windows_plugin_c_api.h new file mode 100644 index 0000000..4c108ea --- /dev/null +++ b/bluetooth_low_energy_windows/windows/include/bluetooth_low_energy_windows/bluetooth_low_energy_windows_plugin_c_api.h @@ -0,0 +1,23 @@ +#ifndef FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_WINDOWS_PLUGIN_C_API_H_ +#define FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_WINDOWS_PLUGIN_C_API_H_ + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) +#else +#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void BluetoothLowEnergyWindowsPluginCApiRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_PLUGIN_BLUETOOTH_LOW_ENERGY_WINDOWS_PLUGIN_C_API_H_ diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock deleted file mode 100644 index d3caa93..0000000 --- a/example/ios/Podfile.lock +++ /dev/null @@ -1,29 +0,0 @@ -PODS: - - bluetooth_low_energy (0.0.1): - - Flutter - - SwiftProtobuf (~> 1.20) - - Flutter (1.0.0) - - SwiftProtobuf (1.20.1) - -DEPENDENCIES: - - bluetooth_low_energy (from `.symlinks/plugins/bluetooth_low_energy/ios`) - - Flutter (from `Flutter`) - -SPEC REPOS: - trunk: - - SwiftProtobuf - -EXTERNAL SOURCES: - bluetooth_low_energy: - :path: ".symlinks/plugins/bluetooth_low_energy/ios" - Flutter: - :path: Flutter - -SPEC CHECKSUMS: - bluetooth_low_energy: af34d921ca3a9e085cf6364c500050965acf25f9 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - SwiftProtobuf: e40a7684079620e84ba522dbaeab0cddb0ec7ffd - -PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 - -COCOAPODS: 1.11.3 diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8 CentralManager.instance; - -void main() { - const app = MyApp(); - runApp(app); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: const HomeView(), - routes: { - 'device': (context) { - final peripheral = - ModalRoute.of(context)?.settings.arguments as Peripheral; - return DeviceView( - peripheral: peripheral, - ); - }, - }, - ); - } -} - -class HomeView extends StatefulWidget { - const HomeView({Key? key}) : super(key: key); - - @override - State createState() => _HomeViewState(); -} - -class _HomeViewState extends State { - late ValueNotifier state; - late ValueNotifier discovering; - late ValueNotifier> broadcasts; - late StreamSubscription stateStreamSubscription; - late StreamSubscription broadcastStreamSubscription; - - @override - void initState() { - super.initState(); - - state = ValueNotifier(false); - discovering = ValueNotifier(false); - broadcasts = ValueNotifier([]); - - state.addListener(onStateChanged); - stateStreamSubscription = central.stateChanged.listen( - (state) => this.state.value = state == BluetoothState.poweredOn, - ); - broadcastStreamSubscription = central.scanned.listen( - (broadcast) { - final broadcasts = this.broadcasts.value; - final i = broadcasts.indexWhere( - (element) => element.peripheral.uuid == broadcast.peripheral.uuid, - ); - if (i < 0) { - this.broadcasts.value = [...broadcasts, broadcast]; - } else { - broadcasts[i] = broadcast; - this.broadcasts.value = [...broadcasts]; - } - }, - ); - setup(); - } - - void setup() async { - final authorized = await central.authorize(); - if (!authorized) { - throw UnimplementedError(); - } - final state = await central.state; - this.state.value = state == BluetoothState.poweredOn; - } - - void onStateChanged() { - final route = ModalRoute.of(context); - if (route == null || !route.isCurrent) { - return; - } - if (state.value) { - startScan(); - } else { - discovering.value = false; - } - } - - @override - void dispose() { - stopScan(); - state.removeListener(onStateChanged); - stateStreamSubscription.cancel(); - broadcastStreamSubscription.cancel(); - - state.dispose(); - discovering.dispose(); - broadcasts.dispose(); - - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Home'), - ), - body: buildBody(context), - ); - } - - void startScan() async { - if (discovering.value || !state.value) { - return; - } - await central.startScan(); - discovering.value = true; - } - - void stopScan() async { - if (!discovering.value || !state.value) { - return; - } - await central.stopScan(); - broadcasts.value = []; - discovering.value = false; - } - - void showBroadcast(Broadcast advertisement) { - showModalBottomSheet( - context: context, - backgroundColor: Colors.transparent, - elevation: 0.0, - builder: (context) => buildBroadcastView(advertisement), - ); - } - - void showDeviceView(Peripheral peripheral) async { - stopScan(); - await Navigator.of(context).pushNamed( - 'device', - arguments: peripheral, - ); - startScan(); - } -} - -extension on _HomeViewState { - Widget buildBody(BuildContext context) { - return ValueListenableBuilder( - valueListenable: state, - builder: (context, bool state, child) { - return state ? buildBroadcastsView(context) : buildClosedView(context); - }, - ); - } - - Widget buildClosedView(BuildContext context) { - return const Center( - child: Text('蓝牙未开启'), - ); - } - - Widget buildBroadcastsView(BuildContext context) { - return RefreshIndicator( - onRefresh: () async => broadcasts.value = [], - child: ValueListenableBuilder( - valueListenable: broadcasts, - builder: (context, List broadcasts, child) { - return ListView.builder( - padding: const EdgeInsets.all(6.0), - itemCount: broadcasts.length, - itemBuilder: (context, i) { - final broadcast = broadcasts.elementAt(i); - final connectable = broadcast.connectable ?? true; - return Card( - color: connectable ? Colors.amber : Colors.grey, - clipBehavior: Clip.antiAlias, - shape: const BeveledRectangleBorder( - borderRadius: BorderRadius.only( - topRight: Radius.circular(12.0), - bottomLeft: Radius.circular(12.0), - ), - ), - margin: const EdgeInsets.all(6.0), - key: Key(broadcast.peripheral.uuid.value), - child: InkWell( - splashColor: Colors.purple, - onTap: connectable - ? () => showDeviceView(broadcast.peripheral) - : null, - onLongPress: () => showBroadcast(broadcast), - child: Container( - height: 100.0, - padding: const EdgeInsets.all(12.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded( - flex: 3, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(broadcast.localName ?? 'UNKNOWN'), - Text( - broadcast.peripheral.uuid.value, - softWrap: true, - ), - ], - ), - ), - Expanded( - flex: 1, - child: Text( - broadcast.rssi.toString(), - textAlign: TextAlign.center, - ), - ), - ], - ), - ), - ), - ); - }, - ); - }, - ), - ); - } - - Widget buildBroadcastView(Broadcast advertisement) { - final widgets = [ - Row( - children: const [ - Text('Type'), - Expanded( - child: Center( - child: Text('Value'), - ), - ), - ], - ), - const Divider(), - ]; - // for (final entry in advertisement.data.entries) { - // final type = '0x${entry.key.toRadixString(16).padLeft(2, '0')}'; - // final value = hex.encode(entry.value); - // final widget = Row( - // children: [ - // Text(type), - // Container(width: 12.0), - // Expanded( - // child: Text( - // value, - // softWrap: true, - // ), - // ), - // ], - // ); - // widgets.add(widget); - // if (entry.key != advertisement.data.entries.last.key) { - // const divider = Divider(); - // widgets.add(divider); - // } - // } - return Container( - margin: const EdgeInsets.all(12.0), - child: Material( - elevation: 1.0, - shape: const 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, - ), - ), - ), - ); - } -} - -class DeviceView extends StatefulWidget { - final Peripheral peripheral; - - const DeviceView({ - Key? key, - required this.peripheral, - }) : super(key: key); - - @override - State createState() => _DeviceViewState(); -} - -class _DeviceViewState extends State { - late StreamSubscription connectionLostStreamSubscription; - late Map> services; - late ValueNotifier state; - late ValueNotifier service; - late ValueNotifier characteristic; - late TextEditingController writeController; - late ValueNotifier> notifies; - late ValueNotifier> logs; - - @override - void initState() { - super.initState(); - - connectionLostStreamSubscription = widget.peripheral.connectionLost.listen( - (error) { - for (var subscription in notifies.value.values) { - subscription.cancel(); - } - service.value = null; - characteristic.value = null; - notifies.value.clear(); - logs.value.clear(); - state.value = ConnectionState.disconnected; - }, - ); - services = {}; - state = ValueNotifier(ConnectionState.disconnected); - service = ValueNotifier(null); - characteristic = ValueNotifier(null); - writeController = TextEditingController(); - notifies = ValueNotifier({}); - logs = ValueNotifier([]); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.peripheral.uuid.value), - actions: [ - buildConnectionState(context), - ], - ), - body: buildBody(context), - ); - } - - 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 { - connectionLostStreamSubscription.cancel(); - 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!); - connectionLostStreamSubscription.cancel(); - state.dispose(); - service.dispose(); - characteristic.dispose(); - notifies.dispose(); - logs.dispose(); - break; - default: - break; - } - } - - void connect() async { - try { - state.value = ConnectionState.connecting; - await widget.peripheral.connect(); - try { - final items0 = >{}; - final services = await widget.peripheral.discoverServices(); - for (var service in services) { - final items1 = []; - final characteristics = await service.discoverCharacteristics(); - for (var characteristic in characteristics) { - items1.add(characteristic); - } - items0[service] = items1; - } - this.services = items0; - } catch (e) { - widget.peripheral.disconnect(); - rethrow; - } - state.value = ConnectionState.connected; - } catch (error) { - state.value = ConnectionState.disconnected; - } - } - - void disconnect() async { - try { - state.value = ConnectionState.disconnecting; - for (var subscription in notifies.value.values) { - subscription.cancel(); - } - await widget.peripheral.disconnect(); - services = {}; - service.value = null; - characteristic.value = null; - notifies.value.clear(); - logs.value.clear(); - state.value = ConnectionState.disconnected; - } catch (e) { - state.value = ConnectionState.connected; - } - } -} - -extension on _DeviceViewState { - Widget buildConnectionState(BuildContext context) { - return ValueListenableBuilder( - valueListenable: state, - builder: (context, ConnectionState state, child) { - void Function()? onPressed; - String data; - switch (state) { - case ConnectionState.disconnected: - onPressed = connect; - data = '连接'; - break; - case ConnectionState.connecting: - data = '连接'; - break; - case ConnectionState.connected: - onPressed = disconnect; - data = '断开'; - break; - case ConnectionState.disconnecting: - data = '断开'; - break; - default: - data = ''; - break; - } - return TextButton( - onPressed: onPressed, - style: TextButton.styleFrom( - foregroundColor: Colors.white, - ), - child: Text(data), - ); - }, - ); - } - - Widget buildBody(BuildContext context) { - return ValueListenableBuilder( - valueListenable: state, - builder: (context, ConnectionState stateValue, child) { - switch (stateValue) { - case ConnectionState.disconnected: - return buildDisconnectedView(context); - case ConnectionState.connecting: - return buildConnectingView(context); - case ConnectionState.connected: - return buildConnectedView(context); - case ConnectionState.disconnecting: - return buildDisconnectingView(context); - default: - throw UnimplementedError(); - } - }, - ); - } - - Widget buildDisconnectedView(BuildContext context) { - return const Center( - child: Text('Disconnected'), - ); - } - - Widget buildConnectingView(BuildContext context) { - return const Center( - child: Text('Connecting'), - ); - } - - Widget buildConnectedView(BuildContext context) { - return ValueListenableBuilder( - valueListenable: service, - builder: (context, GattService? service, child) { - final services = this.services.keys.map((service) { - return DropdownMenuItem( - value: service, - child: Text( - service.uuid.toString(), - softWrap: false, - ), - ); - }).toList(); - final serviceView = DropdownButton( - isExpanded: true, - hint: const Text('Choose a service'), - value: service, - items: services, - onChanged: (service) { - this.service.value = service; - characteristic.value = null; - }, - ); - final views = [serviceView]; - if (service != null) { - final characteristics = this.services[service]?.map((characteristic) { - return DropdownMenuItem( - value: characteristic, - child: Text( - characteristic.uuid.toString(), - softWrap: false, - ), - ); - }).toList(); - final characteristicView = ValueListenableBuilder( - valueListenable: characteristic, - builder: (context, GattCharacteristic? characteristic, child) { - final canWrite = characteristic != null && - (characteristic.canWrite || - characteristic.canWriteWithoutResponse); - final canRead = characteristic != null && characteristic.canRead; - final canNotify = - characteristic != null && characteristic.canNotify; - final readAndNotifyView = Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - IconButton( - onPressed: canRead - ? () async { - final value = await characteristic.read(); - final time = DateTime.now().display; - final log = '[$time][READ] ${hex.encode(value)}'; - logs.value = [...logs.value, log]; - } - : null, - icon: const Icon(Icons.archive), - ), - ValueListenableBuilder( - valueListenable: notifies, - builder: (context, - Map - notifiesValue, - child) { - final notifying = - notifiesValue.containsKey(characteristic); - return IconButton( - onPressed: canNotify - ? () async { - if (notifying) { - await notifiesValue - .remove(characteristic)! - .cancel(); - await characteristic.setNotify(false); - } else { - notifiesValue[characteristic] = - characteristic.valueChanged - .listen((value) { - final time = DateTime.now().display; - final log = - '[$time][NOTIFY] ${hex.encode(value)}'; - logs.value = [...logs.value, log]; - }); - await characteristic.setNotify(true); - } - notifies.value = {...notifiesValue}; - } - : null, - icon: Icon( - Icons.notifications, - color: notifying ? Colors.blue : null, - ), - ); - }), - ], - ); - final controllerView = TextField( - controller: writeController, - decoration: InputDecoration( - // hintText: 'MTU: ${peripheral.maximumWriteLength}', - suffixIcon: IconButton( - onPressed: canWrite - ? () { - final elements = utf8.encode(writeController.text); - final value = Uint8List.fromList(elements); - characteristic.write( - value, - withoutResponse: !characteristic.canWrite, - ); - } - : null, - icon: const Icon(Icons.send), - ), - ), - ); - return Column( - children: [ - DropdownButton( - isExpanded: true, - hint: const Text('Choose a characteristic'), - value: characteristic, - items: characteristics, - onChanged: (characteristic) { - this.characteristic.value = characteristic; - }, - ), - readAndNotifyView, - controllerView, - ], - ); - }, - ); - views.add(characteristicView); - } - final loggerView = Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 12.0), - child: ValueListenableBuilder( - valueListenable: logs, - builder: (context, List logsValue, child) { - return ListView.builder( - itemCount: logsValue.length, - itemBuilder: (context, i) { - final log = logsValue[i]; - return Text(log); - }, - ); - }), - ), - ); - views.add(loggerView); - return Container( - padding: const EdgeInsets.symmetric(horizontal: 12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: views, - ), - ); - }, - ); - } - - Widget buildDisconnectingView(BuildContext context) { - return const Center( - child: Text('Disconnecting'), - ); - } -} - -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'; - } -} - -enum ConnectionState { - disconnected, - connecting, - connected, - disconnecting, -} diff --git a/example/pubspec.lock b/example/pubspec.lock deleted file mode 100644 index 7f6a15f..0000000 --- a/example/pubspec.lock +++ /dev/null @@ -1,294 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "47.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "4.7.0" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.1" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - bluetooth_low_energy: - dependency: "direct main" - description: - path: ".." - relative: true - source: path - version: "1.1.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - convert: - dependency: "direct main" - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.4" - fixnum: - dependency: transitive - description: - name: fixnum - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - lints: - dependency: transitive - description: - name: lints - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - pigeon: - dependency: transitive - description: - name: pigeon - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - protobuf: - dependency: transitive - description: - name: protobuf - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - tuple: - dependency: transitive - description: - name: tuple - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" -sdks: - dart: ">=2.17.6 <3.0.0" - flutter: ">=3.0.0" diff --git a/ios/Classes/BluetoothLowEnergyPlugin.h b/ios/Classes/BluetoothLowEnergyPlugin.h deleted file mode 100644 index 1d3642d..0000000 --- a/ios/Classes/BluetoothLowEnergyPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface BluetoothLowEnergyPlugin : NSObject -@end diff --git a/ios/Classes/BluetoothLowEnergyPlugin.m b/ios/Classes/BluetoothLowEnergyPlugin.m deleted file mode 100644 index 8cc1526..0000000 --- a/ios/Classes/BluetoothLowEnergyPlugin.m +++ /dev/null @@ -1,15 +0,0 @@ -#import "BluetoothLowEnergyPlugin.h" -#if __has_include() -#import -#else -// Support project import fallback if the generated compatibility header -// is not copied when this plugin is created as a library. -// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 -#import "bluetooth_low_energy-Swift.h" -#endif - -@implementation BluetoothLowEnergyPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - [SwiftBluetoothLowEnergyPlugin registerWithRegistrar:registrar]; -} -@end diff --git a/ios/Classes/MyCentralManagerDelegate.swift b/ios/Classes/MyCentralManagerDelegate.swift deleted file mode 100644 index 640820d..0000000 --- a/ios/Classes/MyCentralManagerDelegate.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// MyCentralManagerDelegate.swift -// bluetooth_low_energy -// -// Created by 闫守旺 on 2022/9/20. -// - -import Foundation -import CoreBluetooth - -class MyCentralManagerDelegate: NSObject, CBCentralManagerDelegate { - func centralManagerDidUpdateState(_ central: CBCentralManager) { - // Checks whether the authorize completion is nil. - let state = central.state - let completion = instances.removeValue(forKey: KEY_AUTHORIZE_COMPLETION) as? (NSNumber?, FlutterError?) -> Void - if state != .unknown && completion != nil { - let authorized = NSNumber(value: state != .unauthorized) - completion!(authorized, nil) - } - // Checks whether the state is changed. - let oldNumber = instances[KEY_STATE_NUMBER] as? Int - let number = central.stateNumber - if number == oldNumber { - return - } - instances[KEY_STATE_NUMBER] = number - let stateNumber = NSNumber(value: number) - centralFlutterApi.onStateChanged(stateNumber) {_ in } - } - - func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { - peripheral.delegate = peripheralDelegate - let id = String(peripheral.hash) - var items = register(id) - items[KEY_PERIPHERAL] = peripheral - // This is a copy on write. - instances[id] = items - let connectable = advertisementData[CBAdvertisementDataIsConnectable] as? Bool - let localName = advertisementData[CBAdvertisementDataLocalNameKey] as? String - let manufacturerSpecificData = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data ?? Data() - let serviceData = advertisementData[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] ?? [CBUUID: Data]() - let serviceUUIDs = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID] ?? [CBUUID]() - let solicitedServiceUUIDs = advertisementData[CBAdvertisementDataSolicitedServiceUUIDsKey] as? [CBUUID] ?? [CBUUID]() - let txPowerLevel = advertisementData[CBAdvertisementDataTxPowerLevelKey] as? NSNumber - let data = try! Proto_Broadcast.with { - $0.peripheral = Proto_Peripheral.with { - $0.id = id - $0.uuid = Proto_UUID.with { - $0.value = peripheral.identifier.uuidString - } - } - $0.rssi = RSSI.int32Value - if(connectable != nil) { - $0.connectable = connectable! - } - // We can't get the advertisement's raw value on iOS. - $0.data = Data() - if(localName != nil) { - $0.localName = localName! - } - $0.manufacturerSpecificData = manufacturerSpecificData - $0.serviceDatas = serviceData.map { item in - Proto_ServiceData.with { - $0.uuid = Proto_UUID.with { - $0.value = item.key.uuidString - } - $0.data = item.value - } - } - $0.serviceUuids = serviceUUIDs.map { item in - Proto_UUID.with { - $0.value = item.uuidString - } - } - $0.solicitedServiceUuids = solicitedServiceUUIDs.map { item in - Proto_UUID.with { - $0.value = item.uuidString - } - } - if(txPowerLevel != nil) { - $0.txPowerLevel = txPowerLevel!.int32Value - } - }.serializedData() - let broadcastBuffer = FlutterStandardTypedData(bytes: data) - centralFlutterApi.onScanned(broadcastBuffer) {_ in } - } - - func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { - let id = String(peripheral.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_CONNECT_COMPLETION)") as! (FlutterError?) -> Void - completion(nil) - } - - func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { - let id = String(peripheral.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_CONNECT_COMPLETION)") as! (FlutterError?) -> Void - let errorMessage = error?.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(flutterError) - } - - func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { - let id = String(peripheral.hash) - if error == nil { - let completion = instances.removeValue(forKey: "\(id)/\(KEY_DISCONNECT_COMPLETION)") as! (FlutterError?) -> Void - completion(nil) - } else { - let errorMessage = error!.localizedDescription - peripheralFlutterApi.onConnectionLost(id, errorMessage: errorMessage) {_ in } - } - } -} diff --git a/ios/Classes/MyCentralManagerHostApi.swift b/ios/Classes/MyCentralManagerHostApi.swift deleted file mode 100644 index 7cd6cdd..0000000 --- a/ios/Classes/MyCentralManagerHostApi.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// MyCentralManagerHostApi.swift -// bluetooth_low_energy -// -// Created by 闫守旺 on 2022/9/20. -// - -import Foundation -import CoreBluetooth - -class MyCentralManagerHostApi: NSObject, PigeonCentralManagerHostApi { - func authorize(_ completion: @escaping (NSNumber?, FlutterError?) -> Void) { - let state = central.state - if state == .unknown { - instances[KEY_AUTHORIZE_COMPLETION] = completion - } else { - let authorized = NSNumber(value: state != .unauthorized) - completion(authorized, nil) - } - } - - func getState(_ error: AutoreleasingUnsafeMutablePointer) -> NSNumber? { - return NSNumber(value: central.stateNumber) - } - - func startScan(_ uuidBuffers: [FlutterStandardTypedData]?, completion: @escaping (FlutterError?) -> Void) { - let withServices: [CBUUID]? = uuidBuffers?.map { - let uuid = try! Proto_UUID(serializedData: $0.data) - return CBUUID(string: uuid.value) - } - let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true] - central.scanForPeripherals(withServices: withServices, options: options) - completion(nil) - } - - func stopScan(_ error: AutoreleasingUnsafeMutablePointer) { - central.stopScan() - } -} diff --git a/ios/Classes/MyGattCharacteristicHostApi.swift b/ios/Classes/MyGattCharacteristicHostApi.swift deleted file mode 100644 index 1f887ba..0000000 --- a/ios/Classes/MyGattCharacteristicHostApi.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// MyGattCharacteristicHostApi.swift -// bluetooth_low_energy -// -// Created by 闫守旺 on 2022/9/20. -// - -import Foundation -import CoreBluetooth - -class MyGattCharacteristicHostApi: NSObject, PigeonGattCharacteristicHostApi { - func free(_ id: String, error: AutoreleasingUnsafeMutablePointer) { - unregister(id) - } - - func discoverDescriptors(_ id: String, completion: @escaping ([FlutterStandardTypedData]?, FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let characteristic = items[KEY_CHARACTERISTIC] as! CBCharacteristic - let peripheral = characteristic.service!.peripheral! - peripheral.discoverDescriptors(for: characteristic) - instances["\(id)/\(KEY_DISCOVER_DESCRIPTORS_COMPLETION)"] = completion - } - - func read(_ id: String, completion: @escaping (FlutterStandardTypedData?, FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let characteristic = items[KEY_CHARACTERISTIC] as! CBCharacteristic - let peripheral = characteristic.service!.peripheral! - peripheral.readValue(for: characteristic) - instances["\(id)/\(KEY_READ_COMPLETION)"] = completion - } - - func write(_ id: String, value: FlutterStandardTypedData, withoutResponse: NSNumber, completion: @escaping (FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let characteristic = items[KEY_CHARACTERISTIC] as! CBCharacteristic - let peripheral = characteristic.service!.peripheral! - let data = value.data - let type: CBCharacteristicWriteType = withoutResponse.boolValue ? .withoutResponse : .withResponse - peripheral.writeValue(data, for: characteristic, type: type) - instances["\(id)/\(KEY_WRITE_COMPLETION)"] = completion - } - - func setNotify(_ id: String, value: NSNumber, completion: @escaping (FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let characteristic = items[KEY_CHARACTERISTIC] as! CBCharacteristic - let peripheral = characteristic.service!.peripheral! - peripheral.setNotifyValue(value.boolValue, for: characteristic) - instances["\(id)/\(KEY_SET_NOTIFY_COMPLETION)"] = completion - } -} diff --git a/ios/Classes/MyGattDescriptorHostApi.swift b/ios/Classes/MyGattDescriptorHostApi.swift deleted file mode 100644 index 4954ceb..0000000 --- a/ios/Classes/MyGattDescriptorHostApi.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// MyGattDescriptorHostApi.swift -// bluetooth_low_energy -// -// Created by 闫守旺 on 2022/9/20. -// - -import Foundation -import CoreBluetooth - -class MyGattDescriptorHostApi: NSObject, PigeonGattDescriptorHostApi { - func free(_ id: String, error: AutoreleasingUnsafeMutablePointer) { - unregister(id) - } - - func read(_ id: String, completion: @escaping (FlutterStandardTypedData?, FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let descriptor = items[KEY_DESCRIPTOR] as! CBDescriptor - let peripheral = descriptor.characteristic!.service!.peripheral! - peripheral.readValue(for: descriptor) - instances["\(id)/\(KEY_READ_COMPLETION)"] = completion - } - - func write(_ id: String, value: FlutterStandardTypedData, completion: @escaping (FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let descriptor = items[KEY_DESCRIPTOR] as! CBDescriptor - let peripheral = descriptor.characteristic!.service!.peripheral! - let data = value.data - peripheral.writeValue(data, for: descriptor) - instances["\(id)/\(KEY_WRITE_COMPLETION)"] = completion - } -} diff --git a/ios/Classes/MyGattServiceHostApi.swift b/ios/Classes/MyGattServiceHostApi.swift deleted file mode 100644 index 6caf8df..0000000 --- a/ios/Classes/MyGattServiceHostApi.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// MyGattServiceHostApi.swift -// bluetooth_low_energy -// -// Created by 闫守旺 on 2022/9/20. -// - -import Foundation -import CoreBluetooth - -class MyGattServiceHostApi: NSObject, PigeonGattServiceHostApi { - func free(_ id: String, error: AutoreleasingUnsafeMutablePointer) { - unregister(id) - } - - func discoverCharacteristics(_ id: String, completion: @escaping ([FlutterStandardTypedData]?, FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let service = items[KEY_SERVICE] as! CBService - let peripheral = service.peripheral! - peripheral.discoverCharacteristics(nil, for: service) - instances["\(id)/\(KEY_DISCOVER_CHARACTERISTICS_COMPLETION)"] = completion - } -} diff --git a/ios/Classes/MyPeripheralDelegate.swift b/ios/Classes/MyPeripheralDelegate.swift deleted file mode 100644 index 6c85d84..0000000 --- a/ios/Classes/MyPeripheralDelegate.swift +++ /dev/null @@ -1,211 +0,0 @@ -// -// MyPeripheralDelegate.swift -// bluetooth_low_energy -// -// Created by 闫守旺 on 2022/9/20. -// - -import Foundation -import CoreBluetooth - -class MyPeripheralDelegate: NSObject, CBPeripheralDelegate { - func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { - let id = String(peripheral.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_DISCOVER_SERVICES_COMPLETION)") as! ([FlutterStandardTypedData]?, FlutterError?) -> Void - if error == nil { - var serviceBuffers = [FlutterStandardTypedData]() - let services = peripheral.services - if services != nil { - for service in services! { - let serviceBuffer = registerService(service) - serviceBuffers.append(serviceBuffer) - } - } - completion(serviceBuffers, nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(nil, flutterError) - } - } - - func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { - let id = String(service.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_DISCOVER_CHARACTERISTICS_COMPLETION)") as! ([FlutterStandardTypedData]?, FlutterError?) -> Void - if error == nil { - var characteristicBuffers = [FlutterStandardTypedData]() - let characteristics = service.characteristics - if characteristics != nil { - for characteristic in characteristics! { - let characteristicBuffer = registerCharacteristic(characteristic) - characteristicBuffers.append(characteristicBuffer) - } - } - completion(characteristicBuffers, nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(nil, flutterError) - } - } - - func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) { - let id = String(characteristic.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_DISCOVER_DESCRIPTORS_COMPLETION)") as! ([FlutterStandardTypedData]?, FlutterError?) -> Void - if error == nil { - var descriptorBuffers = [FlutterStandardTypedData]() - let descriptors = characteristic.descriptors - if descriptors != nil { - for descriptor in descriptors! { - let descriptorBuffer = registerDescriptor(descriptor) - descriptorBuffers.append(descriptorBuffer) - } - } - completion(descriptorBuffers, nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(nil, flutterError) - } - } - - func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { - let id = String(characteristic.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_READ_COMPLETION)") as? (FlutterStandardTypedData?, FlutterError?) -> Void - let characteristicValue = characteristic.value - let value = characteristicValue == nil ? FlutterStandardTypedData() : FlutterStandardTypedData(bytes: characteristicValue!) - if completion == nil { - characteristicFlutterApi.onValueChanged(id, value: value) {_ in } - } else if error == nil { - completion!(value, nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion!(nil, flutterError) - } - } - - func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) { - let id = String(characteristic.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_WRITE_COMPLETION)") as! (FlutterError?) -> Void - if error == nil { - completion(nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(flutterError) - } - } - - func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) { - let id = String(characteristic.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_SET_NOTIFY_COMPLETION)") as! (FlutterError?) -> Void - if error == nil { - completion(nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(flutterError) - } - } - - func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) { - let id = String(descriptor.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_READ_COMPLETION)") as! (FlutterStandardTypedData?, FlutterError?) -> Void - if error == nil { - let value: FlutterStandardTypedData - if descriptor.value == nil { - value = FlutterStandardTypedData() - } else { - switch descriptor.uuid.uuidString { - case CBUUIDCharacteristicExtendedPropertiesString: - fallthrough - case CBUUIDClientCharacteristicConfigurationString: - fallthrough - case CBUUIDServerCharacteristicConfigurationString: - let item = descriptor.value as! NSNumber - value = FlutterStandardTypedData(bytes: item.data) - case CBUUIDCharacteristicUserDescriptionString: - fallthrough - case CBUUIDCharacteristicAggregateFormatString: - let item = descriptor.value as! String - value = FlutterStandardTypedData(bytes: item.data) - case CBUUIDCharacteristicFormatString: - let data = descriptor.value as! Data - value = FlutterStandardTypedData(bytes: data) - case CBUUIDL2CAPPSMCharacteristicString: - let item = descriptor.value as! UInt16 - value = FlutterStandardTypedData(bytes: item.data) - default: - value = FlutterStandardTypedData() - } - } - completion(value, nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(nil, flutterError) - } - } - - func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) { - let id = String(descriptor.hash) - let completion = instances.removeValue(forKey: "\(id)/\(KEY_WRITE_COMPLETION)") as! (FlutterError?) -> Void - if error == nil { - completion(nil) - } else { - let errorMessage = error!.localizedDescription - let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil) - completion(flutterError) - } - } - - private func registerService(_ service: CBService) -> FlutterStandardTypedData { - let id = String(service.hash) - var items = register(id) - items[KEY_SERVICE] = service - // This is a copy on write. - instances[id] = items - let data = try! Proto_GattService.with { - $0.id = id - $0.uuid = Proto_UUID.with { - $0.value = service.uuid.uuidString - } - }.serializedData() - return FlutterStandardTypedData(bytes: data) - } - - private func registerCharacteristic(_ characteristic: CBCharacteristic) -> FlutterStandardTypedData { - let id = String(characteristic.hash) - var items = register(id) - items[KEY_CHARACTERISTIC] = characteristic - // This is a copy on write. - instances[id] = items - let data = try! Proto_GattCharacteristic.with { - $0.id = id - $0.uuid = Proto_UUID.with { - $0.value = characteristic.uuid.uuidString - } - $0.canRead = characteristic.properties.contains(.read) - $0.canWrite = characteristic.properties.contains(.write) - $0.canWriteWithoutResponse = characteristic.properties.contains(.writeWithoutResponse) - $0.canNotify = characteristic.properties.contains(.notify) - }.serializedData() - return FlutterStandardTypedData(bytes: data) - } - - private func registerDescriptor(_ descriptor: CBDescriptor) -> FlutterStandardTypedData { - let id = String(descriptor.hash) - var items = register(id) - items[KEY_DESCRIPTOR] = descriptor - // This is a copy on write. - instances[id] = items - let data = try! Proto_GattDescriptor.with { - $0.id = id - $0.uuid = Proto_UUID.with { - $0.value = descriptor.uuid.uuidString - } - }.serializedData() - return FlutterStandardTypedData(bytes: data) - } -} diff --git a/ios/Classes/MyPeripheralHostApi.swift b/ios/Classes/MyPeripheralHostApi.swift deleted file mode 100644 index ea5330a..0000000 --- a/ios/Classes/MyPeripheralHostApi.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// MyPeripheralHostApi.swift -// bluetooth_low_energy -// -// Created by 闫守旺 on 2022/9/20. -// - -import Foundation -import CoreBluetooth - -class MyPeripheralHostApi: NSObject, PigeonPeripheralHostApi { - func free(_ id: String, error: AutoreleasingUnsafeMutablePointer) { - unregister(id) - } - - func connect(_ id: String, completion: @escaping (FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let peripheral = items[KEY_PERIPHERAL] as! CBPeripheral - central.connect(peripheral) - instances["\(id)/\(KEY_CONNECT_COMPLETION)"] = completion - } - - func disconnect(_ id: String, completion: @escaping (FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let peripheral = items[KEY_PERIPHERAL] as! CBPeripheral - central.cancelPeripheralConnection(peripheral) - instances["\(id)/\(KEY_DISCONNECT_COMPLETION)"] = completion - } - - func requestMtu(_ id: String, completion: @escaping (NSNumber?, FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let peripheral = items[KEY_PERIPHERAL] as! CBPeripheral - let value = peripheral.maximumWriteValueLength(for: .withoutResponse) - let maximumWriteLength = NSNumber(value: value) - completion(maximumWriteLength, nil) - } - - func discoverServices(_ id: String, completion: @escaping ([FlutterStandardTypedData]?, FlutterError?) -> Void) { - let items = instances[id] as! [String: Any] - let peripheral = items[KEY_PERIPHERAL] as! CBPeripheral - peripheral.discoverServices(nil) - instances["\(id)/\(KEY_DISCOVER_SERVICES_COMPLETION)"] = completion - } -} diff --git a/ios/Classes/SwiftBluetoothLowEnergyPlugin.swift b/ios/Classes/SwiftBluetoothLowEnergyPlugin.swift deleted file mode 100644 index c711a43..0000000 --- a/ios/Classes/SwiftBluetoothLowEnergyPlugin.swift +++ /dev/null @@ -1,112 +0,0 @@ -import Flutter -import UIKit -import CoreBluetooth - -public class SwiftBluetoothLowEnergyPlugin: NSObject, FlutterPlugin { - public static func register(with registrar: FlutterPluginRegistrar) { - let binaryMessenger = registrar.messenger() - - PigeonCentralManagerHostApiSetup(binaryMessenger, centralHostApi) - PigeonPeripheralHostApiSetup(binaryMessenger, peripherialHostApi) - PigeonGattServiceHostApiSetup(binaryMessenger, serviceHostApi) - PigeonGattCharacteristicHostApiSetup(binaryMessenger, characteristicHostApi) - PigeonGattDescriptorHostApiSetup(binaryMessenger, descriptorHostApi) - - instances[KEY_CENTRAL_MANAGER_FLUTTER_API] = PigeonCentralManagerFlutterApi(binaryMessenger: binaryMessenger) - instances[KEY_PERIPHERAL_FLUTTER_API] = PigeonPeripheralFlutterApi(binaryMessenger: binaryMessenger) - instances[KEY_GATT_CHARACTERISTIC_FLUTTER_API] = PigeonGattCharacteristicFlutterApi(binaryMessenger: binaryMessenger) - } -} - -let BLUETOOTH_LOW_ENERGY_ERROR = "BLUETOOTH_LOW_ENERGY_ERROR" -let KEY_CENTRAL_MANAGER_FLUTTER_API = "KEY_CENTRAL_MANAGER_FLUTTER_API" -let KEY_PERIPHERAL_FLUTTER_API = "KEY_PERIPHERAL_FLUTTER_API" -let KEY_GATT_CHARACTERISTIC_FLUTTER_API = "KEY_GATT_CHARACTERISTIC_FLUTTER_API" -let KEY_STATE_NUMBER = "KEY_STATE_NUMBER" -let KEY_COUNT = "KEY_COUNT" -let KEY_PERIPHERAL = "KEY_PERIPHERAL" -let KEY_SERVICE = "KEY_SERVICE" -let KEY_CHARACTERISTIC = "KEY_CHARACTERISTIC" -let KEY_DESCRIPTOR = "KEY_DESCRIPTOR" -let KEY_AUTHORIZE_COMPLETION = "KEY_AUTHORIZE_COMPLETION" -let KEY_CONNECT_COMPLETION = "KEY_CONNECT_COMPLETION" -let KEY_DISCONNECT_COMPLETION = "KEY_DISCONNECT_COMPLETION" -let KEY_DISCOVER_SERVICES_COMPLETION = "KEY_DISCOVER_SERVICES_COMPLETION" -let KEY_DISCOVER_CHARACTERISTICS_COMPLETION = "KEY_DISCOVER_CHARACTERISTICS_COMPLETION" -let KEY_DISCOVER_DESCRIPTORS_COMPLETION = "KEY_DISCOVER_DESCRIPTORS_COMPLETION" -let KEY_READ_COMPLETION = "KEY_READ_COMPLETION" -let KEY_WRITE_COMPLETION = "KEY_WRITE_COMPLETION" -let KEY_SET_NOTIFY_COMPLETION = "KEY_SET_NOTIFY_COMPLETION" - -var instances = [String: Any]() - -let central = CBCentralManager(delegate: centralManagerDelegate, queue: nil) -let centralManagerDelegate = MyCentralManagerDelegate() -let peripheralDelegate = MyPeripheralDelegate() - -let centralHostApi = MyCentralManagerHostApi() -let peripherialHostApi = MyPeripheralHostApi() -let serviceHostApi = MyGattServiceHostApi() -let characteristicHostApi = MyGattCharacteristicHostApi() -let descriptorHostApi = MyGattDescriptorHostApi() - -var centralFlutterApi: PigeonCentralManagerFlutterApi { return instances[KEY_CENTRAL_MANAGER_FLUTTER_API] as! PigeonCentralManagerFlutterApi } -var peripheralFlutterApi: PigeonPeripheralFlutterApi { return instances[KEY_PERIPHERAL_FLUTTER_API] as! PigeonPeripheralFlutterApi } -var characteristicFlutterApi: PigeonGattCharacteristicFlutterApi { return instances[KEY_GATT_CHARACTERISTIC_FLUTTER_API] as! PigeonGattCharacteristicFlutterApi } - -func register(_ id:String) -> [String:Any] { - var items = instances[id] as? [String: Any] ?? [String: Any]() - var count = items[KEY_COUNT] as? Int ?? 0 - count += 1 - items[KEY_COUNT] = count - // This is a copy on write. - instances[id] = items - debugPrint("register: \(id)") - return items -} - -func unregister(_ id: String) { - var items = instances[id] as! [String: Any] - var count = items[KEY_COUNT] as! Int - count -= 1 - items[KEY_COUNT] = count - if count < 1 { - instances.removeValue(forKey: id) - debugPrint("unregister: \(id)") - } else { - // This is a copy on write. - instances[id] = items - } -} - -extension CBCentralManager { - var stateNumber: Int { - if state == .unsupported { - return Proto_BluetoothState.unsupported.rawValue - } else if state == .poweredOn { - return Proto_BluetoothState.poweredOn.rawValue - } else { - return Proto_BluetoothState.poweredOff.rawValue - } - } -} - -extension NSNumber { - var data: Data { - var source = self - return Data(bytes: &source, count: MemoryLayout.size) - } -} - -extension String { - var data: Data { - return data(using: String.Encoding.utf8)! - } -} - -extension UInt16 { - var data: Data { - var source = self - return Data(bytes: &source, count: MemoryLayout.size) - } -} diff --git a/ios/Classes/pigeon/Messages.h b/ios/Classes/pigeon/Messages.h deleted file mode 100644 index f02bc9c..0000000 --- a/ios/Classes/pigeon/Messages.h +++ /dev/null @@ -1,94 +0,0 @@ -// Autogenerated from Pigeon (v4.2.0), do not edit directly. -// See also: https://pub.dev/packages/pigeon -#import -@protocol FlutterBinaryMessenger; -@protocol FlutterMessageCodec; -@class FlutterError; -@class FlutterStandardTypedData; - -NS_ASSUME_NONNULL_BEGIN - - -///The codec used by PigeonCentralManagerHostApi. -NSObject *PigeonCentralManagerHostApiGetCodec(void); - -@protocol PigeonCentralManagerHostApi -- (void)authorize:(void(^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; -/// @return `nil` only when `error != nil`. -- (nullable NSNumber *)getState:(FlutterError *_Nullable *_Nonnull)error; -- (void)startScan:(nullable NSArray *)uuidBuffers completion:(void(^)(FlutterError *_Nullable))completion; -- (void)stopScan:(FlutterError *_Nullable *_Nonnull)error; -@end - -extern void PigeonCentralManagerHostApiSetup(id binaryMessenger, NSObject *_Nullable api); - -///The codec used by PigeonCentralManagerFlutterApi. -NSObject *PigeonCentralManagerFlutterApiGetCodec(void); - -@interface PigeonCentralManagerFlutterApi : NSObject -- (instancetype)initWithBinaryMessenger:(id)binaryMessenger; -- (void)onStateChanged:(NSNumber *)stateNumber completion:(void(^)(NSError *_Nullable))completion; -- (void)onScanned:(FlutterStandardTypedData *)broadcastBuffer completion:(void(^)(NSError *_Nullable))completion; -@end -///The codec used by PigeonPeripheralHostApi. -NSObject *PigeonPeripheralHostApiGetCodec(void); - -@protocol PigeonPeripheralHostApi -- (void)free:(NSString *)id error:(FlutterError *_Nullable *_Nonnull)error; -- (void)connect:(NSString *)id completion:(void(^)(FlutterError *_Nullable))completion; -- (void)disconnect:(NSString *)id completion:(void(^)(FlutterError *_Nullable))completion; -- (void)requestMtu:(NSString *)id completion:(void(^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; -- (void)discoverServices:(NSString *)id completion:(void(^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -@end - -extern void PigeonPeripheralHostApiSetup(id binaryMessenger, NSObject *_Nullable api); - -///The codec used by PigeonPeripheralFlutterApi. -NSObject *PigeonPeripheralFlutterApiGetCodec(void); - -@interface PigeonPeripheralFlutterApi : NSObject -- (instancetype)initWithBinaryMessenger:(id)binaryMessenger; -- (void)onConnectionLost:(NSString *)id errorMessage:(NSString *)errorMessage completion:(void(^)(NSError *_Nullable))completion; -@end -///The codec used by PigeonGattServiceHostApi. -NSObject *PigeonGattServiceHostApiGetCodec(void); - -@protocol PigeonGattServiceHostApi -- (void)free:(NSString *)id error:(FlutterError *_Nullable *_Nonnull)error; -- (void)discoverCharacteristics:(NSString *)id completion:(void(^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -@end - -extern void PigeonGattServiceHostApiSetup(id binaryMessenger, NSObject *_Nullable api); - -///The codec used by PigeonGattCharacteristicHostApi. -NSObject *PigeonGattCharacteristicHostApiGetCodec(void); - -@protocol PigeonGattCharacteristicHostApi -- (void)free:(NSString *)id error:(FlutterError *_Nullable *_Nonnull)error; -- (void)discoverDescriptors:(NSString *)id completion:(void(^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -- (void)read:(NSString *)id completion:(void(^)(FlutterStandardTypedData *_Nullable, FlutterError *_Nullable))completion; -- (void)write:(NSString *)id value:(FlutterStandardTypedData *)value withoutResponse:(NSNumber *)withoutResponse completion:(void(^)(FlutterError *_Nullable))completion; -- (void)setNotify:(NSString *)id value:(NSNumber *)value completion:(void(^)(FlutterError *_Nullable))completion; -@end - -extern void PigeonGattCharacteristicHostApiSetup(id binaryMessenger, NSObject *_Nullable api); - -///The codec used by PigeonGattCharacteristicFlutterApi. -NSObject *PigeonGattCharacteristicFlutterApiGetCodec(void); - -@interface PigeonGattCharacteristicFlutterApi : NSObject -- (instancetype)initWithBinaryMessenger:(id)binaryMessenger; -- (void)onValueChanged:(NSString *)id value:(FlutterStandardTypedData *)value completion:(void(^)(NSError *_Nullable))completion; -@end -///The codec used by PigeonGattDescriptorHostApi. -NSObject *PigeonGattDescriptorHostApiGetCodec(void); - -@protocol PigeonGattDescriptorHostApi -- (void)free:(NSString *)id error:(FlutterError *_Nullable *_Nonnull)error; -- (void)read:(NSString *)id completion:(void(^)(FlutterStandardTypedData *_Nullable, FlutterError *_Nullable))completion; -- (void)write:(NSString *)id value:(FlutterStandardTypedData *)value completion:(void(^)(FlutterError *_Nullable))completion; -@end - -extern void PigeonGattDescriptorHostApiSetup(id binaryMessenger, NSObject *_Nullable api); - -NS_ASSUME_NONNULL_END diff --git a/ios/Classes/pigeon/Messages.m b/ios/Classes/pigeon/Messages.m deleted file mode 100644 index 9230906..0000000 --- a/ios/Classes/pigeon/Messages.m +++ /dev/null @@ -1,760 +0,0 @@ -// Autogenerated from Pigeon (v4.2.0), do not edit directly. -// See also: https://pub.dev/packages/pigeon -#import "Messages.h" -#import - -#if !__has_feature(objc_arc) -#error File requires ARC to be enabled. -#endif - -static NSDictionary *wrapResult(id result, FlutterError *error) { - NSDictionary *errorDict = (NSDictionary *)[NSNull null]; - if (error) { - errorDict = @{ - @"code": (error.code ?: [NSNull null]), - @"message": (error.message ?: [NSNull null]), - @"details": (error.details ?: [NSNull null]), - }; - } - return @{ - @"result": (result ?: [NSNull null]), - @"error": errorDict, - }; -} -static id GetNullableObject(NSDictionary* dict, id key) { - id result = dict[key]; - return (result == [NSNull null]) ? nil : result; -} -static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { - id result = array[key]; - return (result == [NSNull null]) ? nil : result; -} - - - -@interface PigeonCentralManagerHostApiCodecReader : FlutterStandardReader -@end -@implementation PigeonCentralManagerHostApiCodecReader -@end - -@interface PigeonCentralManagerHostApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonCentralManagerHostApiCodecWriter -@end - -@interface PigeonCentralManagerHostApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonCentralManagerHostApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonCentralManagerHostApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonCentralManagerHostApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonCentralManagerHostApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonCentralManagerHostApiCodecReaderWriter *readerWriter = [[PigeonCentralManagerHostApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -void PigeonCentralManagerHostApiSetup(id binaryMessenger, NSObject *api) { - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.CentralManagerHostApi.authorize" - binaryMessenger:binaryMessenger - codec:PigeonCentralManagerHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(authorize:)], @"PigeonCentralManagerHostApi api (%@) doesn't respond to @selector(authorize:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api authorize:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.CentralManagerHostApi.getState" - binaryMessenger:binaryMessenger - codec:PigeonCentralManagerHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(getState:)], @"PigeonCentralManagerHostApi api (%@) doesn't respond to @selector(getState:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - FlutterError *error; - NSNumber *output = [api getState:&error]; - callback(wrapResult(output, error)); - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.CentralManagerHostApi.startScan" - binaryMessenger:binaryMessenger - codec:PigeonCentralManagerHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(startScan:completion:)], @"PigeonCentralManagerHostApi api (%@) doesn't respond to @selector(startScan:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSArray *arg_uuidBuffers = GetNullableObjectAtIndex(args, 0); - [api startScan:arg_uuidBuffers completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.CentralManagerHostApi.stopScan" - binaryMessenger:binaryMessenger - codec:PigeonCentralManagerHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(stopScan:)], @"PigeonCentralManagerHostApi api (%@) doesn't respond to @selector(stopScan:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - FlutterError *error; - [api stopScan:&error]; - callback(wrapResult(nil, error)); - }]; - } - else { - [channel setMessageHandler:nil]; - } - } -} -@interface PigeonCentralManagerFlutterApiCodecReader : FlutterStandardReader -@end -@implementation PigeonCentralManagerFlutterApiCodecReader -@end - -@interface PigeonCentralManagerFlutterApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonCentralManagerFlutterApiCodecWriter -@end - -@interface PigeonCentralManagerFlutterApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonCentralManagerFlutterApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonCentralManagerFlutterApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonCentralManagerFlutterApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonCentralManagerFlutterApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonCentralManagerFlutterApiCodecReaderWriter *readerWriter = [[PigeonCentralManagerFlutterApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -@interface PigeonCentralManagerFlutterApi () -@property (nonatomic, strong) NSObject *binaryMessenger; -@end - -@implementation PigeonCentralManagerFlutterApi - -- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; - if (self) { - _binaryMessenger = binaryMessenger; - } - return self; -} -- (void)onStateChanged:(NSNumber *)arg_stateNumber completion:(void(^)(NSError *_Nullable))completion { - FlutterBasicMessageChannel *channel = - [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.CentralManagerFlutterApi.onStateChanged" - binaryMessenger:self.binaryMessenger - codec:PigeonCentralManagerFlutterApiGetCodec()]; - [channel sendMessage:@[arg_stateNumber ?: [NSNull null]] reply:^(id reply) { - completion(nil); - }]; -} -- (void)onScanned:(FlutterStandardTypedData *)arg_broadcastBuffer completion:(void(^)(NSError *_Nullable))completion { - FlutterBasicMessageChannel *channel = - [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.CentralManagerFlutterApi.onScanned" - binaryMessenger:self.binaryMessenger - codec:PigeonCentralManagerFlutterApiGetCodec()]; - [channel sendMessage:@[arg_broadcastBuffer ?: [NSNull null]] reply:^(id reply) { - completion(nil); - }]; -} -@end -@interface PigeonPeripheralHostApiCodecReader : FlutterStandardReader -@end -@implementation PigeonPeripheralHostApiCodecReader -@end - -@interface PigeonPeripheralHostApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonPeripheralHostApiCodecWriter -@end - -@interface PigeonPeripheralHostApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonPeripheralHostApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonPeripheralHostApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonPeripheralHostApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonPeripheralHostApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonPeripheralHostApiCodecReaderWriter *readerWriter = [[PigeonPeripheralHostApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -void PigeonPeripheralHostApiSetup(id binaryMessenger, NSObject *api) { - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.PeripheralHostApi.free" - binaryMessenger:binaryMessenger - codec:PigeonPeripheralHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(free:error:)], @"PigeonPeripheralHostApi api (%@) doesn't respond to @selector(free:error:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - FlutterError *error; - [api free:arg_id error:&error]; - callback(wrapResult(nil, error)); - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.PeripheralHostApi.connect" - binaryMessenger:binaryMessenger - codec:PigeonPeripheralHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(connect:completion:)], @"PigeonPeripheralHostApi api (%@) doesn't respond to @selector(connect:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api connect:arg_id completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.PeripheralHostApi.disconnect" - binaryMessenger:binaryMessenger - codec:PigeonPeripheralHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(disconnect:completion:)], @"PigeonPeripheralHostApi api (%@) doesn't respond to @selector(disconnect:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api disconnect:arg_id completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.PeripheralHostApi.requestMtu" - binaryMessenger:binaryMessenger - codec:PigeonPeripheralHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(requestMtu:completion:)], @"PigeonPeripheralHostApi api (%@) doesn't respond to @selector(requestMtu:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api requestMtu:arg_id completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.PeripheralHostApi.discoverServices" - binaryMessenger:binaryMessenger - codec:PigeonPeripheralHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(discoverServices:completion:)], @"PigeonPeripheralHostApi api (%@) doesn't respond to @selector(discoverServices:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api discoverServices:arg_id completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } -} -@interface PigeonPeripheralFlutterApiCodecReader : FlutterStandardReader -@end -@implementation PigeonPeripheralFlutterApiCodecReader -@end - -@interface PigeonPeripheralFlutterApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonPeripheralFlutterApiCodecWriter -@end - -@interface PigeonPeripheralFlutterApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonPeripheralFlutterApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonPeripheralFlutterApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonPeripheralFlutterApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonPeripheralFlutterApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonPeripheralFlutterApiCodecReaderWriter *readerWriter = [[PigeonPeripheralFlutterApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -@interface PigeonPeripheralFlutterApi () -@property (nonatomic, strong) NSObject *binaryMessenger; -@end - -@implementation PigeonPeripheralFlutterApi - -- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; - if (self) { - _binaryMessenger = binaryMessenger; - } - return self; -} -- (void)onConnectionLost:(NSString *)arg_id errorMessage:(NSString *)arg_errorMessage completion:(void(^)(NSError *_Nullable))completion { - FlutterBasicMessageChannel *channel = - [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.PeripheralFlutterApi.onConnectionLost" - binaryMessenger:self.binaryMessenger - codec:PigeonPeripheralFlutterApiGetCodec()]; - [channel sendMessage:@[arg_id ?: [NSNull null], arg_errorMessage ?: [NSNull null]] reply:^(id reply) { - completion(nil); - }]; -} -@end -@interface PigeonGattServiceHostApiCodecReader : FlutterStandardReader -@end -@implementation PigeonGattServiceHostApiCodecReader -@end - -@interface PigeonGattServiceHostApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonGattServiceHostApiCodecWriter -@end - -@interface PigeonGattServiceHostApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonGattServiceHostApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonGattServiceHostApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonGattServiceHostApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonGattServiceHostApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonGattServiceHostApiCodecReaderWriter *readerWriter = [[PigeonGattServiceHostApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -void PigeonGattServiceHostApiSetup(id binaryMessenger, NSObject *api) { - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattServiceHostApi.free" - binaryMessenger:binaryMessenger - codec:PigeonGattServiceHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(free:error:)], @"PigeonGattServiceHostApi api (%@) doesn't respond to @selector(free:error:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - FlutterError *error; - [api free:arg_id error:&error]; - callback(wrapResult(nil, error)); - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattServiceHostApi.discoverCharacteristics" - binaryMessenger:binaryMessenger - codec:PigeonGattServiceHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(discoverCharacteristics:completion:)], @"PigeonGattServiceHostApi api (%@) doesn't respond to @selector(discoverCharacteristics:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api discoverCharacteristics:arg_id completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } -} -@interface PigeonGattCharacteristicHostApiCodecReader : FlutterStandardReader -@end -@implementation PigeonGattCharacteristicHostApiCodecReader -@end - -@interface PigeonGattCharacteristicHostApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonGattCharacteristicHostApiCodecWriter -@end - -@interface PigeonGattCharacteristicHostApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonGattCharacteristicHostApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonGattCharacteristicHostApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonGattCharacteristicHostApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonGattCharacteristicHostApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonGattCharacteristicHostApiCodecReaderWriter *readerWriter = [[PigeonGattCharacteristicHostApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -void PigeonGattCharacteristicHostApiSetup(id binaryMessenger, NSObject *api) { - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattCharacteristicHostApi.free" - binaryMessenger:binaryMessenger - codec:PigeonGattCharacteristicHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(free:error:)], @"PigeonGattCharacteristicHostApi api (%@) doesn't respond to @selector(free:error:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - FlutterError *error; - [api free:arg_id error:&error]; - callback(wrapResult(nil, error)); - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattCharacteristicHostApi.discoverDescriptors" - binaryMessenger:binaryMessenger - codec:PigeonGattCharacteristicHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(discoverDescriptors:completion:)], @"PigeonGattCharacteristicHostApi api (%@) doesn't respond to @selector(discoverDescriptors:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api discoverDescriptors:arg_id completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattCharacteristicHostApi.read" - binaryMessenger:binaryMessenger - codec:PigeonGattCharacteristicHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(read:completion:)], @"PigeonGattCharacteristicHostApi api (%@) doesn't respond to @selector(read:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api read:arg_id completion:^(FlutterStandardTypedData *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattCharacteristicHostApi.write" - binaryMessenger:binaryMessenger - codec:PigeonGattCharacteristicHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(write:value:withoutResponse:completion:)], @"PigeonGattCharacteristicHostApi api (%@) doesn't respond to @selector(write:value:withoutResponse:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - FlutterStandardTypedData *arg_value = GetNullableObjectAtIndex(args, 1); - NSNumber *arg_withoutResponse = GetNullableObjectAtIndex(args, 2); - [api write:arg_id value:arg_value withoutResponse:arg_withoutResponse completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattCharacteristicHostApi.setNotify" - binaryMessenger:binaryMessenger - codec:PigeonGattCharacteristicHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(setNotify:value:completion:)], @"PigeonGattCharacteristicHostApi api (%@) doesn't respond to @selector(setNotify:value:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_value = GetNullableObjectAtIndex(args, 1); - [api setNotify:arg_id value:arg_value completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } -} -@interface PigeonGattCharacteristicFlutterApiCodecReader : FlutterStandardReader -@end -@implementation PigeonGattCharacteristicFlutterApiCodecReader -@end - -@interface PigeonGattCharacteristicFlutterApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonGattCharacteristicFlutterApiCodecWriter -@end - -@interface PigeonGattCharacteristicFlutterApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonGattCharacteristicFlutterApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonGattCharacteristicFlutterApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonGattCharacteristicFlutterApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonGattCharacteristicFlutterApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonGattCharacteristicFlutterApiCodecReaderWriter *readerWriter = [[PigeonGattCharacteristicFlutterApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -@interface PigeonGattCharacteristicFlutterApi () -@property (nonatomic, strong) NSObject *binaryMessenger; -@end - -@implementation PigeonGattCharacteristicFlutterApi - -- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { - self = [super init]; - if (self) { - _binaryMessenger = binaryMessenger; - } - return self; -} -- (void)onValueChanged:(NSString *)arg_id value:(FlutterStandardTypedData *)arg_value completion:(void(^)(NSError *_Nullable))completion { - FlutterBasicMessageChannel *channel = - [FlutterBasicMessageChannel - messageChannelWithName:@"dev.flutter.pigeon.GattCharacteristicFlutterApi.onValueChanged" - binaryMessenger:self.binaryMessenger - codec:PigeonGattCharacteristicFlutterApiGetCodec()]; - [channel sendMessage:@[arg_id ?: [NSNull null], arg_value ?: [NSNull null]] reply:^(id reply) { - completion(nil); - }]; -} -@end -@interface PigeonGattDescriptorHostApiCodecReader : FlutterStandardReader -@end -@implementation PigeonGattDescriptorHostApiCodecReader -@end - -@interface PigeonGattDescriptorHostApiCodecWriter : FlutterStandardWriter -@end -@implementation PigeonGattDescriptorHostApiCodecWriter -@end - -@interface PigeonGattDescriptorHostApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation PigeonGattDescriptorHostApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[PigeonGattDescriptorHostApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[PigeonGattDescriptorHostApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *PigeonGattDescriptorHostApiGetCodec() { - static dispatch_once_t sPred = 0; - static FlutterStandardMessageCodec *sSharedObject = nil; - dispatch_once(&sPred, ^{ - PigeonGattDescriptorHostApiCodecReaderWriter *readerWriter = [[PigeonGattDescriptorHostApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - - -void PigeonGattDescriptorHostApiSetup(id binaryMessenger, NSObject *api) { - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattDescriptorHostApi.free" - binaryMessenger:binaryMessenger - codec:PigeonGattDescriptorHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(free:error:)], @"PigeonGattDescriptorHostApi api (%@) doesn't respond to @selector(free:error:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - FlutterError *error; - [api free:arg_id error:&error]; - callback(wrapResult(nil, error)); - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattDescriptorHostApi.read" - binaryMessenger:binaryMessenger - codec:PigeonGattDescriptorHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(read:completion:)], @"PigeonGattDescriptorHostApi api (%@) doesn't respond to @selector(read:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - [api read:arg_id completion:^(FlutterStandardTypedData *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = - [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.GattDescriptorHostApi.write" - binaryMessenger:binaryMessenger - codec:PigeonGattDescriptorHostApiGetCodec() ]; - if (api) { - NSCAssert([api respondsToSelector:@selector(write:value:completion:)], @"PigeonGattDescriptorHostApi api (%@) doesn't respond to @selector(write:value:completion:)", api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_id = GetNullableObjectAtIndex(args, 0); - FlutterStandardTypedData *arg_value = GetNullableObjectAtIndex(args, 1); - [api write:arg_id value:arg_value completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } - else { - [channel setMessageHandler:nil]; - } - } -} diff --git a/ios/Classes/proto/messages.pb.swift b/ios/Classes/proto/messages.pb.swift deleted file mode 100644 index ba41ce0..0000000 --- a/ios/Classes/proto/messages.pb.swift +++ /dev/null @@ -1,642 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: proto/messages.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that you are building against the same version of the API -// that was used to generate this file. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -enum Proto_BluetoothState: SwiftProtobuf.Enum { - typealias RawValue = Int - case unsupported // = 0 - case poweredOff // = 1 - case poweredOn // = 2 - case UNRECOGNIZED(Int) - - init() { - self = .unsupported - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unsupported - case 1: self = .poweredOff - case 2: self = .poweredOn - default: self = .UNRECOGNIZED(rawValue) - } - } - - var rawValue: Int { - switch self { - case .unsupported: return 0 - case .poweredOff: return 1 - case .poweredOn: return 2 - case .UNRECOGNIZED(let i): return i - } - } - -} - -#if swift(>=4.2) - -extension Proto_BluetoothState: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [Proto_BluetoothState] = [ - .unsupported, - .poweredOff, - .poweredOn, - ] -} - -#endif // swift(>=4.2) - -struct Proto_Broadcast { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var peripheral: Proto_Peripheral { - get {return _peripheral ?? Proto_Peripheral()} - set {_peripheral = newValue} - } - /// Returns true if `peripheral` has been explicitly set. - var hasPeripheral: Bool {return self._peripheral != nil} - /// Clears the value of `peripheral`. Subsequent reads from it will return its default value. - mutating func clearPeripheral() {self._peripheral = nil} - - var rssi: Int32 = 0 - - var connectable: Bool { - get {return _connectable ?? false} - set {_connectable = newValue} - } - /// Returns true if `connectable` has been explicitly set. - var hasConnectable: Bool {return self._connectable != nil} - /// Clears the value of `connectable`. Subsequent reads from it will return its default value. - mutating func clearConnectable() {self._connectable = nil} - - var data: Data = Data() - - var localName: String { - get {return _localName ?? String()} - set {_localName = newValue} - } - /// Returns true if `localName` has been explicitly set. - var hasLocalName: Bool {return self._localName != nil} - /// Clears the value of `localName`. Subsequent reads from it will return its default value. - mutating func clearLocalName() {self._localName = nil} - - var manufacturerSpecificData: Data = Data() - - var serviceDatas: [Proto_ServiceData] = [] - - var serviceUuids: [Proto_UUID] = [] - - var solicitedServiceUuids: [Proto_UUID] = [] - - var txPowerLevel: Int32 { - get {return _txPowerLevel ?? 0} - set {_txPowerLevel = newValue} - } - /// Returns true if `txPowerLevel` has been explicitly set. - var hasTxPowerLevel: Bool {return self._txPowerLevel != nil} - /// Clears the value of `txPowerLevel`. Subsequent reads from it will return its default value. - mutating func clearTxPowerLevel() {self._txPowerLevel = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _peripheral: Proto_Peripheral? = nil - fileprivate var _connectable: Bool? = nil - fileprivate var _localName: String? = nil - fileprivate var _txPowerLevel: Int32? = nil -} - -struct Proto_Peripheral { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var id: String = String() - - var uuid: Proto_UUID { - get {return _uuid ?? Proto_UUID()} - set {_uuid = newValue} - } - /// Returns true if `uuid` has been explicitly set. - var hasUuid: Bool {return self._uuid != nil} - /// Clears the value of `uuid`. Subsequent reads from it will return its default value. - mutating func clearUuid() {self._uuid = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _uuid: Proto_UUID? = nil -} - -struct Proto_GattService { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var id: String = String() - - var uuid: Proto_UUID { - get {return _uuid ?? Proto_UUID()} - set {_uuid = newValue} - } - /// Returns true if `uuid` has been explicitly set. - var hasUuid: Bool {return self._uuid != nil} - /// Clears the value of `uuid`. Subsequent reads from it will return its default value. - mutating func clearUuid() {self._uuid = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _uuid: Proto_UUID? = nil -} - -struct Proto_GattCharacteristic { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var id: String = String() - - var uuid: Proto_UUID { - get {return _uuid ?? Proto_UUID()} - set {_uuid = newValue} - } - /// Returns true if `uuid` has been explicitly set. - var hasUuid: Bool {return self._uuid != nil} - /// Clears the value of `uuid`. Subsequent reads from it will return its default value. - mutating func clearUuid() {self._uuid = nil} - - var canRead: Bool = false - - var canWrite: Bool = false - - var canWriteWithoutResponse: Bool = false - - var canNotify: Bool = false - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _uuid: Proto_UUID? = nil -} - -struct Proto_GattDescriptor { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var id: String = String() - - var uuid: Proto_UUID { - get {return _uuid ?? Proto_UUID()} - set {_uuid = newValue} - } - /// Returns true if `uuid` has been explicitly set. - var hasUuid: Bool {return self._uuid != nil} - /// Clears the value of `uuid`. Subsequent reads from it will return its default value. - mutating func clearUuid() {self._uuid = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _uuid: Proto_UUID? = nil -} - -struct Proto_UUID { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var value: String = String() - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -struct Proto_ServiceData { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var uuid: Proto_UUID { - get {return _uuid ?? Proto_UUID()} - set {_uuid = newValue} - } - /// Returns true if `uuid` has been explicitly set. - var hasUuid: Bool {return self._uuid != nil} - /// Clears the value of `uuid`. Subsequent reads from it will return its default value. - mutating func clearUuid() {self._uuid = nil} - - var data: Data = Data() - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _uuid: Proto_UUID? = nil -} - -#if swift(>=5.5) && canImport(_Concurrency) -extension Proto_BluetoothState: @unchecked Sendable {} -extension Proto_Broadcast: @unchecked Sendable {} -extension Proto_Peripheral: @unchecked Sendable {} -extension Proto_GattService: @unchecked Sendable {} -extension Proto_GattCharacteristic: @unchecked Sendable {} -extension Proto_GattDescriptor: @unchecked Sendable {} -extension Proto_UUID: @unchecked Sendable {} -extension Proto_ServiceData: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "proto" - -extension Proto_BluetoothState: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "BLUETOOTH_STATE_UNSUPPORTED"), - 1: .same(proto: "BLUETOOTH_STATE_POWERED_OFF"), - 2: .same(proto: "BLUETOOTH_STATE_POWERED_ON"), - ] -} - -extension Proto_Broadcast: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Broadcast" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "peripheral"), - 2: .same(proto: "rssi"), - 3: .same(proto: "connectable"), - 4: .same(proto: "data"), - 5: .standard(proto: "local_name"), - 6: .standard(proto: "manufacturer_specific_data"), - 7: .standard(proto: "service_datas"), - 8: .standard(proto: "service_uuids"), - 9: .standard(proto: "solicited_service_uuids"), - 10: .standard(proto: "tx_power_level"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &self._peripheral) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self.rssi) }() - case 3: try { try decoder.decodeSingularBoolField(value: &self._connectable) }() - case 4: try { try decoder.decodeSingularBytesField(value: &self.data) }() - case 5: try { try decoder.decodeSingularStringField(value: &self._localName) }() - case 6: try { try decoder.decodeSingularBytesField(value: &self.manufacturerSpecificData) }() - case 7: try { try decoder.decodeRepeatedMessageField(value: &self.serviceDatas) }() - case 8: try { try decoder.decodeRepeatedMessageField(value: &self.serviceUuids) }() - case 9: try { try decoder.decodeRepeatedMessageField(value: &self.solicitedServiceUuids) }() - case 10: try { try decoder.decodeSingularInt32Field(value: &self._txPowerLevel) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._peripheral { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if self.rssi != 0 { - try visitor.visitSingularInt32Field(value: self.rssi, fieldNumber: 2) - } - try { if let v = self._connectable { - try visitor.visitSingularBoolField(value: v, fieldNumber: 3) - } }() - if !self.data.isEmpty { - try visitor.visitSingularBytesField(value: self.data, fieldNumber: 4) - } - try { if let v = self._localName { - try visitor.visitSingularStringField(value: v, fieldNumber: 5) - } }() - if !self.manufacturerSpecificData.isEmpty { - try visitor.visitSingularBytesField(value: self.manufacturerSpecificData, fieldNumber: 6) - } - if !self.serviceDatas.isEmpty { - try visitor.visitRepeatedMessageField(value: self.serviceDatas, fieldNumber: 7) - } - if !self.serviceUuids.isEmpty { - try visitor.visitRepeatedMessageField(value: self.serviceUuids, fieldNumber: 8) - } - if !self.solicitedServiceUuids.isEmpty { - try visitor.visitRepeatedMessageField(value: self.solicitedServiceUuids, fieldNumber: 9) - } - try { if let v = self._txPowerLevel { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 10) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Proto_Broadcast, rhs: Proto_Broadcast) -> Bool { - if lhs._peripheral != rhs._peripheral {return false} - if lhs.rssi != rhs.rssi {return false} - if lhs._connectable != rhs._connectable {return false} - if lhs.data != rhs.data {return false} - if lhs._localName != rhs._localName {return false} - if lhs.manufacturerSpecificData != rhs.manufacturerSpecificData {return false} - if lhs.serviceDatas != rhs.serviceDatas {return false} - if lhs.serviceUuids != rhs.serviceUuids {return false} - if lhs.solicitedServiceUuids != rhs.solicitedServiceUuids {return false} - if lhs._txPowerLevel != rhs._txPowerLevel {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Proto_Peripheral: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Peripheral" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "uuid"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self.id) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._uuid) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !self.id.isEmpty { - try visitor.visitSingularStringField(value: self.id, fieldNumber: 1) - } - try { if let v = self._uuid { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Proto_Peripheral, rhs: Proto_Peripheral) -> Bool { - if lhs.id != rhs.id {return false} - if lhs._uuid != rhs._uuid {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Proto_GattService: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".GattService" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "uuid"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self.id) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._uuid) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !self.id.isEmpty { - try visitor.visitSingularStringField(value: self.id, fieldNumber: 1) - } - try { if let v = self._uuid { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Proto_GattService, rhs: Proto_GattService) -> Bool { - if lhs.id != rhs.id {return false} - if lhs._uuid != rhs._uuid {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Proto_GattCharacteristic: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".GattCharacteristic" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "uuid"), - 3: .standard(proto: "can_read"), - 4: .standard(proto: "can_write"), - 5: .standard(proto: "can_write_without_response"), - 6: .standard(proto: "can_notify"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self.id) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._uuid) }() - case 3: try { try decoder.decodeSingularBoolField(value: &self.canRead) }() - case 4: try { try decoder.decodeSingularBoolField(value: &self.canWrite) }() - case 5: try { try decoder.decodeSingularBoolField(value: &self.canWriteWithoutResponse) }() - case 6: try { try decoder.decodeSingularBoolField(value: &self.canNotify) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !self.id.isEmpty { - try visitor.visitSingularStringField(value: self.id, fieldNumber: 1) - } - try { if let v = self._uuid { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - if self.canRead != false { - try visitor.visitSingularBoolField(value: self.canRead, fieldNumber: 3) - } - if self.canWrite != false { - try visitor.visitSingularBoolField(value: self.canWrite, fieldNumber: 4) - } - if self.canWriteWithoutResponse != false { - try visitor.visitSingularBoolField(value: self.canWriteWithoutResponse, fieldNumber: 5) - } - if self.canNotify != false { - try visitor.visitSingularBoolField(value: self.canNotify, fieldNumber: 6) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Proto_GattCharacteristic, rhs: Proto_GattCharacteristic) -> Bool { - if lhs.id != rhs.id {return false} - if lhs._uuid != rhs._uuid {return false} - if lhs.canRead != rhs.canRead {return false} - if lhs.canWrite != rhs.canWrite {return false} - if lhs.canWriteWithoutResponse != rhs.canWriteWithoutResponse {return false} - if lhs.canNotify != rhs.canNotify {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Proto_GattDescriptor: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".GattDescriptor" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "uuid"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self.id) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._uuid) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !self.id.isEmpty { - try visitor.visitSingularStringField(value: self.id, fieldNumber: 1) - } - try { if let v = self._uuid { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Proto_GattDescriptor, rhs: Proto_GattDescriptor) -> Bool { - if lhs.id != rhs.id {return false} - if lhs._uuid != rhs._uuid {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Proto_UUID: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".UUID" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "value"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self.value) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.value.isEmpty { - try visitor.visitSingularStringField(value: self.value, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Proto_UUID, rhs: Proto_UUID) -> Bool { - if lhs.value != rhs.value {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Proto_ServiceData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".ServiceData" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "uuid"), - 2: .same(proto: "data"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &self._uuid) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self.data) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._uuid { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !self.data.isEmpty { - try visitor.visitSingularBytesField(value: self.data, fieldNumber: 2) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Proto_ServiceData, rhs: Proto_ServiceData) -> Bool { - if lhs._uuid != rhs._uuid {return false} - if lhs.data != rhs.data {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/lib/bluetooth_low_energy.dart b/lib/bluetooth_low_energy.dart deleted file mode 100644 index 1cc44df..0000000 --- a/lib/bluetooth_low_energy.dart +++ /dev/null @@ -1,8 +0,0 @@ -export 'src/central_manager.dart'; -export 'src/peripheral.dart'; -export 'src/gatt_service.dart'; -export 'src/gatt_characteristic.dart'; -export 'src/gatt_descriptor.dart'; -export 'src/bluetooth_state.dart'; -export 'src/broadcast.dart'; -export 'src/uuid.dart'; diff --git a/lib/src/api.dart b/lib/src/api.dart deleted file mode 100644 index 5472e86..0000000 --- a/lib/src/api.dart +++ /dev/null @@ -1,137 +0,0 @@ -import 'dart:typed_data'; - -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:tuple/tuple.dart'; - -import 'impl.dart'; - -abstract class CentralManagerApi extends PlatformInterface { - /// Constructs a [CentralManagerApi]. - CentralManagerApi() : super(token: _token); - - static final Object _token = Object(); - - static CentralManagerApi _instance = MyCentralManagerApi(); - - /// The default instance of [CentralManagerApi] to use. - static CentralManagerApi get instance => _instance; - - /// Platform-specific implementations should set this with their own - /// platform-specific class that extends [CentralManagerApi] when - /// they register themselves. - static set instance(CentralManagerApi instance) { - PlatformInterface.verifyToken(instance, _token); - _instance = instance; - } - - Future get state; - Stream get stateChanged; - Stream get scanned; - - Future authorize(); - Future startScan(List? uuidBuffers); - Future stopScan(); -} - -abstract class PeripheralApi extends PlatformInterface { - /// Constructs a [PeripheralApi]. - PeripheralApi() : super(token: _token); - - static final Object _token = Object(); - - static PeripheralApi _instance = MyPeripheralApi(); - - /// The default instance of [PeripheralApi] to use. - static PeripheralApi get instance => _instance; - - /// Platform-specific implementations should set this with their own - /// platform-specific class that extends [PeripheralApi] when - /// they register themselves. - static set instance(PeripheralApi instance) { - PlatformInterface.verifyToken(instance, _token); - _instance = instance; - } - - Stream> get connectionLost; - - Future free(String id); - Future connect(String id); - Future disconnect(String id); - Future requestMtu(String id); - Future> discoverServices(String id); -} - -abstract class GattServiceApi extends PlatformInterface { - /// Constructs a [GattServiceApi]. - GattServiceApi() : super(token: _token); - - static final Object _token = Object(); - - static GattServiceApi _instance = MyGattServiceApi(); - - /// The default instance of [GattServiceApi] to use. - static GattServiceApi get instance => _instance; - - /// Platform-specific implementations should set this with their own - /// platform-specific class that extends [GattServiceApi] when - /// they register themselves. - static set instance(GattServiceApi instance) { - PlatformInterface.verifyToken(instance, _token); - _instance = instance; - } - - Future free(String id); - Future> discoverCharacteristics(String id); -} - -abstract class GattCharacteristicApi extends PlatformInterface { - /// Constructs a [GattCharacteristicApi]. - GattCharacteristicApi() : super(token: _token); - - static final Object _token = Object(); - - static GattCharacteristicApi _instance = MyGattCharacteristicApi(); - - /// The default instance of [GattCharacteristicApi] to use. - static GattCharacteristicApi get instance => _instance; - - /// Platform-specific implementations should set this with their own - /// platform-specific class that extends [GattCharacteristicApi] when - /// they register themselves. - static set instance(GattCharacteristicApi instance) { - PlatformInterface.verifyToken(instance, _token); - _instance = instance; - } - - Stream> get valueChanged; - - Future free(String id); - Future> discoverDescriptors(String id); - Future read(String id); - Future write(String id, Uint8List value, bool withoutResponse); - Future setNotify(String id, bool value); -} - -abstract class GattDescriptorApi extends PlatformInterface { - /// Constructs a [GattDescriptorApi]. - GattDescriptorApi() : super(token: _token); - - static final Object _token = Object(); - - static GattDescriptorApi _instance = MyGattDescriptorApi(); - - /// The default instance of [GattDescriptorApi] to use. - static GattDescriptorApi get instance => _instance; - - /// Platform-specific implementations should set this with their own - /// platform-specific class that extends [GattDescriptorApi] when - /// they register themselves. - static set instance(GattDescriptorApi instance) { - PlatformInterface.verifyToken(instance, _token); - _instance = instance; - } - - Future free(String id); - Future read(String id); - Future write(String id, Uint8List value); -} diff --git a/lib/src/bluetooth_state.dart b/lib/src/bluetooth_state.dart deleted file mode 100644 index 66cfbed..0000000 --- a/lib/src/bluetooth_state.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum BluetoothState { - unsupported, - poweredOff, - poweredOn, -} diff --git a/lib/src/broadcast.dart b/lib/src/broadcast.dart deleted file mode 100644 index 2cdbbca..0000000 --- a/lib/src/broadcast.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'dart:typed_data'; - -import 'peripheral.dart'; -import 'uuid.dart'; - -abstract class Broadcast { - Peripheral get peripheral; - int get rssi; - bool? get connectable; - Uint8List get data; - String? get localName; - Uint8List get manufacturerSpecificData; - Map get serviceData; - List get serviceUUIDs; - List get solicitedServiceUUIDs; - int? get txPowerLevel; -} diff --git a/lib/src/central_manager.dart b/lib/src/central_manager.dart deleted file mode 100644 index 44c7c53..0000000 --- a/lib/src/central_manager.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'broadcast.dart'; -import 'impl.dart'; -import 'bluetooth_state.dart'; -import 'uuid.dart'; - -abstract class CentralManager { - Future get state; - Stream get stateChanged; - Stream get scanned; - - Future authorize(); - Future startScan({List? uuids}); - Future stopScan(); - - static final _instance = MyCentralManager(); - static CentralManager get instance => _instance; -} diff --git a/lib/src/gatt_characteristic.dart b/lib/src/gatt_characteristic.dart deleted file mode 100644 index 7fd8760..0000000 --- a/lib/src/gatt_characteristic.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'dart:typed_data'; - -import 'gatt_descriptor.dart'; -import 'uuid.dart'; - -abstract class GattCharacteristic { - UUID get uuid; - bool get canRead; - bool get canWrite; - bool get canWriteWithoutResponse; - bool get canNotify; - Stream get valueChanged; - - Future> discoverDescriptors(); - Future read(); - Future write(Uint8List value, {bool withoutResponse = false}); - Future setNotify(bool value); -} diff --git a/lib/src/gatt_descriptor.dart b/lib/src/gatt_descriptor.dart deleted file mode 100644 index fc1031e..0000000 --- a/lib/src/gatt_descriptor.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'dart:typed_data'; - -import 'uuid.dart'; - -abstract class GattDescriptor { - UUID get uuid; - - Future read(); - Future write(Uint8List value); -} diff --git a/lib/src/gatt_service.dart b/lib/src/gatt_service.dart deleted file mode 100644 index c72f5cf..0000000 --- a/lib/src/gatt_service.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'gatt_characteristic.dart'; -import 'uuid.dart'; - -abstract class GattService { - UUID get uuid; - - Future> discoverCharacteristics(); -} diff --git a/lib/src/impl.dart b/lib/src/impl.dart deleted file mode 100644 index edac6c0..0000000 --- a/lib/src/impl.dart +++ /dev/null @@ -1,532 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/services.dart'; -import 'package:tuple/tuple.dart'; - -import 'broadcast.dart'; -import 'api.dart'; -import 'bluetooth_state.dart'; -import 'central_manager.dart'; -import 'gatt_characteristic.dart'; -import 'gatt_descriptor.dart'; -import 'gatt_service.dart'; -import 'peripheral.dart'; -import 'pigeon.dart'; -import 'proto.dart' as proto; -import 'uuid.dart'; - -const bluetoothLowEnergyError = 'bluetoothLowEnergyError'; - -class MyCentralManagerApi extends CentralManagerApi - implements CentralManagerFlutterApi { - final hostApi = CentralManagerHostApi(); - final stateStreamController = StreamController.broadcast(); - final broadcastStreamController = StreamController.broadcast(); - - MyCentralManagerApi() { - CentralManagerFlutterApi.setup(this); - } - - @override - Future get state => hostApi.getState(); - @override - Stream get stateChanged => stateStreamController.stream; - @override - Stream get scanned => broadcastStreamController.stream; - - @override - Future authorize() { - return hostApi.authorize(); - } - - @override - Future startScan(List? uuidBuffers) { - return hostApi.startScan(uuidBuffers); - } - - @override - Future stopScan() { - return hostApi.stopScan(); - } - - @override - void onStateChanged(int stateNumber) { - stateStreamController.add(stateNumber); - } - - @override - void onScanned(Uint8List broadcastBuffer) { - broadcastStreamController.add(broadcastBuffer); - } -} - -class MyPeripheralApi extends PeripheralApi implements PeripheralFlutterApi { - final hostApi = PeripheralHostApi(); - final connectionLostStreamController = - StreamController>.broadcast(); - - MyPeripheralApi() { - PeripheralFlutterApi.setup(this); - } - - @override - Stream> get connectionLost => - connectionLostStreamController.stream; - - @override - Future free(String id) { - return hostApi.free(id); - } - - @override - Future connect(String id) { - return hostApi.connect(id); - } - - @override - Future disconnect(String id) { - return hostApi.disconnect(id); - } - - @override - Future requestMtu(String id) { - return hostApi.requestMtu(id); - } - - @override - Future> discoverServices(String id) { - return hostApi.discoverServices(id).then((buffers) => buffers.cast()); - } - - @override - void onConnectionLost(String id, String errorMessage) { - final event = Tuple2(id, errorMessage); - connectionLostStreamController.add(event); - } -} - -class MyGattServiceApi extends GattServiceApi { - final hostApi = GattServiceHostApi(); - - @override - Future free(String id) { - return hostApi.free(id); - } - - @override - Future> discoverCharacteristics(String id) { - return hostApi - .discoverCharacteristics(id) - .then((buffers) => buffers.cast()); - } -} - -class MyGattCharacteristicApi extends GattCharacteristicApi - implements GattCharacteristicFlutterApi { - final hostApi = GattCharacteristicHostApi(); - - MyGattCharacteristicApi() { - GattCharacteristicFlutterApi.setup(this); - } - - final valueStreamController = - StreamController>.broadcast(); - - @override - Stream> get valueChanged => - valueStreamController.stream; - - @override - Future free(String id) { - return hostApi.free(id); - } - - @override - Future> discoverDescriptors(String id) { - return hostApi.discoverDescriptors(id).then((buffers) => buffers.cast()); - } - - @override - Future read(String id) { - return hostApi.read(id); - } - - @override - Future write(String id, Uint8List value, bool withoutResponse) { - return hostApi.write(id, value, withoutResponse); - } - - @override - Future setNotify(String id, bool value) { - return hostApi.setNotify(id, value); - } - - @override - void onValueChanged(String id, Uint8List value) { - final event = Tuple2(id, value); - valueStreamController.add(event); - } -} - -class MyGattDescriptorApi extends GattDescriptorApi { - final hostApi = GattDescriptorHostApi(); - - @override - Future free(String id) { - return hostApi.free(id); - } - - @override - Future read(String id) { - return hostApi.read(id); - } - - @override - Future write(String id, Uint8List value) { - return hostApi.write(id, value); - } -} - -class MyCentralManager implements CentralManager { - static CentralManagerApi get api => CentralManagerApi.instance; - - @override - Future get state => - api.state.then((number) => BluetoothState.values[number]); - @override - Stream get stateChanged => - api.stateChanged.map((number) => BluetoothState.values[number]); - @override - Stream get scanned => - api.scanned.map((buffer) => MyBroadcast.fromBuffer(buffer)); - - @override - Future authorize() { - return api.authorize(); - } - - @override - Future startScan({List? uuids}) { - final uuidBuffers = uuids?.map((uuid) => uuid.buffer).toList(); - return api.startScan(uuidBuffers); - } - - @override - Future stopScan() { - return api.stopScan(); - } -} - -class MyBroadcast implements Broadcast { - @override - final Peripheral peripheral; - @override - final int rssi; - @override - final bool? connectable; - @override - final Uint8List data; - @override - final String? localName; - @override - final Uint8List manufacturerSpecificData; - @override - final Map serviceData; - @override - final List serviceUUIDs; - @override - final List solicitedServiceUUIDs; - @override - final int? txPowerLevel; - - MyBroadcast({ - required this.peripheral, - required this.rssi, - required this.connectable, - required this.data, - required this.localName, - required this.manufacturerSpecificData, - required this.serviceData, - required this.serviceUUIDs, - required this.solicitedServiceUUIDs, - required this.txPowerLevel, - }); - - factory MyBroadcast.fromBuffer(Uint8List buffer) { - final broadcast = proto.Broadcast.fromBuffer(buffer); - final peripheral = MyPeripheral.fromProto(broadcast.peripheral); - final rssi = broadcast.rssi; - final connectable = - broadcast.hasConnectable() ? broadcast.connectable : null; - final data = Uint8List.fromList(broadcast.data); - final localName = broadcast.hasLocalName() ? broadcast.localName : null; - final manufacturerSpecificData = - Uint8List.fromList(broadcast.manufacturerSpecificData); - final serviceData = { - for (var serviceData in broadcast.serviceDatas) - MyUUID.fromProto(serviceData.uuid): Uint8List.fromList(serviceData.data) - }; - final serviceUUIDs = - broadcast.serviceUuids.map((uuid) => MyUUID.fromProto(uuid)).toList(); - final solicitedServiceUUIDs = broadcast.solicitedServiceUuids - .map((uuid) => MyUUID.fromProto(uuid)) - .toList(); - final txPowerLevel = - broadcast.hasTxPowerLevel() ? broadcast.txPowerLevel : null; - return MyBroadcast( - peripheral: peripheral, - rssi: rssi, - connectable: connectable, - data: data, - localName: localName, - manufacturerSpecificData: manufacturerSpecificData, - serviceData: serviceData, - serviceUUIDs: serviceUUIDs, - solicitedServiceUUIDs: solicitedServiceUUIDs, - txPowerLevel: txPowerLevel, - ); - } -} - -class MyPeripheral implements Peripheral { - static PeripheralApi get api => PeripheralApi.instance; - - static final finalizer = Finalizer((id) { - api.free(id); - }); - - final String id; - @override - final UUID uuid; - - MyPeripheral({required this.id, required this.uuid}) { - finalizer.attach( - this, - id, - ); - } - - factory MyPeripheral.fromProto(proto.Peripheral peripheral) { - return MyPeripheral( - id: peripheral.id, - uuid: MyUUID.fromProto(peripheral.uuid), - ); - } - - @override - Stream get connectionLost => - api.connectionLost.where((event) => event.item1 == id).map( - (event) => PlatformException( - code: bluetoothLowEnergyError, - message: event.item2, - ), - ); - - @override - Future connect() { - return api.connect(id); - } - - @override - Future disconnect() { - return api.disconnect(id); - } - - @override - Future requestMtu() { - return api.requestMtu(id); - } - - @override - Future> discoverServices() { - return api.discoverServices(id).then( - (buffers) => buffers - .map((buffer) => MyGattService.fromBuffer(buffer)) - .toList(), - ); - } -} - -class MyGattService extends GattService { - static GattServiceApi get api => GattServiceApi.instance; - - static final finalizer = Finalizer((id) { - api.free(id); - }); - - final String id; - @override - final UUID uuid; - - MyGattService({required this.id, required this.uuid}) { - finalizer.attach( - this, - id, - ); - } - - factory MyGattService.fromBuffer(Uint8List buffer) { - final service = proto.GattService.fromBuffer(buffer); - final uuid = MyUUID.fromProto(service.uuid); - return MyGattService( - id: service.id, - uuid: uuid, - ); - } - - @override - Future> discoverCharacteristics() { - return api.discoverCharacteristics(id).then( - (buffers) => buffers - .map((buffer) => MyGattCharacteristic.fromBuffer(buffer)) - .toList(), - ); - } -} - -class MyGattCharacteristic extends GattCharacteristic { - static GattCharacteristicApi get api => GattCharacteristicApi.instance; - - static final finalizer = Finalizer((id) { - api.free(id); - }); - - final String id; - @override - final UUID uuid; - @override - final bool canRead; - @override - final bool canWrite; - @override - final bool canWriteWithoutResponse; - @override - final bool canNotify; - - MyGattCharacteristic({ - required this.id, - required this.uuid, - required this.canRead, - required this.canWrite, - required this.canWriteWithoutResponse, - required this.canNotify, - }) { - finalizer.attach( - this, - id, - ); - } - - factory MyGattCharacteristic.fromBuffer(Uint8List buffer) { - final characteristic = proto.GattCharacteristic.fromBuffer(buffer); - final uuid = MyUUID.fromProto(characteristic.uuid); - final canRead = characteristic.canRead; - final canWrite = characteristic.canWrite; - final canWriteWithoutResponse = characteristic.canWriteWithoutResponse; - final canNotify = characteristic.canNotify; - return MyGattCharacteristic( - id: characteristic.id, - uuid: uuid, - canRead: canRead, - canWrite: canWrite, - canWriteWithoutResponse: canWriteWithoutResponse, - canNotify: canNotify, - ); - } - - @override - Stream get valueChanged => api.valueChanged - .where((event) => event.item1 == id) - .map((event) => event.item2); - - @override - Future> discoverDescriptors() { - return api.discoverDescriptors(id).then( - (buffers) => buffers - .map((buffer) => MyGattDescriptor.fromBuffer(buffer)) - .toList(), - ); - } - - @override - Future read() { - return api.read(id); - } - - @override - Future write(Uint8List value, {bool withoutResponse = false}) { - return api.write(id, value, withoutResponse); - } - - @override - Future setNotify(bool value) { - return api.setNotify(id, value); - } -} - -class MyGattDescriptor extends GattDescriptor { - static GattDescriptorApi get api => GattDescriptorApi.instance; - - static final finalizer = Finalizer((id) { - GattDescriptorApi.instance.free(id); - }); - - final String id; - @override - final UUID uuid; - - MyGattDescriptor({required this.id, required this.uuid}) { - finalizer.attach( - this, - id, - ); - } - - factory MyGattDescriptor.fromBuffer(Uint8List buffer) { - final descriptor = proto.GattDescriptor.fromBuffer(buffer); - final uuid = MyUUID.fromProto(descriptor.uuid); - return MyGattDescriptor( - id: descriptor.id, - uuid: uuid, - ); - } - - @override - Future read() { - return api.read(id); - } - - @override - Future write(Uint8List value) { - return api.write(id, value); - } -} - -class MyUUID implements UUID { - @override - final String value; - - MyUUID({required this.value}); - - factory MyUUID.fromProto(proto.UUID uuid) { - final value = uuid.value.toLowerCase(); - return MyUUID(value: value); - } - - @override - String toString() { - return 'UUID: $value'; - } - - @override - int get hashCode => value.hashCode; - - @override - bool operator ==(Object other) { - return other is MyUUID && other.value == value; - } -} - -extension on UUID { - Uint8List get buffer => proto.UUID(value: value).writeToBuffer(); -} diff --git a/lib/src/peripheral.dart b/lib/src/peripheral.dart deleted file mode 100644 index 357d0fe..0000000 --- a/lib/src/peripheral.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'gatt_service.dart'; -import 'uuid.dart'; - -abstract class Peripheral { - UUID get uuid; - - Stream get connectionLost; - - Future connect(); - Future disconnect(); - Future requestMtu(); - Future> discoverServices(); -} diff --git a/lib/src/pigeon.dart b/lib/src/pigeon.dart deleted file mode 100644 index dcc675a..0000000 --- a/lib/src/pigeon.dart +++ /dev/null @@ -1 +0,0 @@ -export 'pigeon/messages.g.dart'; diff --git a/lib/src/pigeon/messages.g.dart b/lib/src/pigeon/messages.g.dart deleted file mode 100644 index 0634784..0000000 --- a/lib/src/pigeon/messages.g.dart +++ /dev/null @@ -1,643 +0,0 @@ -// Autogenerated from Pigeon (v4.2.0), do not edit directly. -// See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import -import 'dart:async'; -import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; - -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; -import 'package:flutter/services.dart'; - -class _CentralManagerHostApiCodec extends StandardMessageCodec { - const _CentralManagerHostApiCodec(); -} - -class CentralManagerHostApi { - /// Constructor for [CentralManagerHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - CentralManagerHostApi({BinaryMessenger? binaryMessenger}) : _binaryMessenger = binaryMessenger; - - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _CentralManagerHostApiCodec(); - - Future authorize() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.authorize', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send(null) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as bool?)!; - } - } - - Future getState() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.getState', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send(null) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as int?)!; - } - } - - Future startScan(List? arg_uuidBuffers) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.startScan', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_uuidBuffers]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future stopScan() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.stopScan', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send(null) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } -} - -class _CentralManagerFlutterApiCodec extends StandardMessageCodec { - const _CentralManagerFlutterApiCodec(); -} -abstract class CentralManagerFlutterApi { - static const MessageCodec codec = _CentralManagerFlutterApiCodec(); - - void onStateChanged(int stateNumber); - void onScanned(Uint8List broadcastBuffer); - static void setup(CentralManagerFlutterApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerFlutterApi.onStateChanged', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMessageHandler(null); - } else { - channel.setMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.CentralManagerFlutterApi.onStateChanged was null.'); - final List args = (message as List?)!; - final int? arg_stateNumber = (args[0] as int?); - assert(arg_stateNumber != null, 'Argument for dev.flutter.pigeon.CentralManagerFlutterApi.onStateChanged was null, expected non-null int.'); - api.onStateChanged(arg_stateNumber!); - return; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerFlutterApi.onScanned', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMessageHandler(null); - } else { - channel.setMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.CentralManagerFlutterApi.onScanned was null.'); - final List args = (message as List?)!; - final Uint8List? arg_broadcastBuffer = (args[0] as Uint8List?); - assert(arg_broadcastBuffer != null, 'Argument for dev.flutter.pigeon.CentralManagerFlutterApi.onScanned was null, expected non-null Uint8List.'); - api.onScanned(arg_broadcastBuffer!); - return; - }); - } - } - } -} - -class _PeripheralHostApiCodec extends StandardMessageCodec { - const _PeripheralHostApiCodec(); -} - -class PeripheralHostApi { - /// Constructor for [PeripheralHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - PeripheralHostApi({BinaryMessenger? binaryMessenger}) : _binaryMessenger = binaryMessenger; - - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _PeripheralHostApiCodec(); - - Future free(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.free', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future connect(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.connect', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future disconnect(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.disconnect', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future requestMtu(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.requestMtu', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as int?)!; - } - } - - Future> discoverServices(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.discoverServices', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as List?)!.cast(); - } - } -} - -class _PeripheralFlutterApiCodec extends StandardMessageCodec { - const _PeripheralFlutterApiCodec(); -} -abstract class PeripheralFlutterApi { - static const MessageCodec codec = _PeripheralFlutterApiCodec(); - - void onConnectionLost(String id, String errorMessage); - static void setup(PeripheralFlutterApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralFlutterApi.onConnectionLost', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMessageHandler(null); - } else { - channel.setMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.PeripheralFlutterApi.onConnectionLost was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.PeripheralFlutterApi.onConnectionLost was null, expected non-null String.'); - final String? arg_errorMessage = (args[1] as String?); - assert(arg_errorMessage != null, 'Argument for dev.flutter.pigeon.PeripheralFlutterApi.onConnectionLost was null, expected non-null String.'); - api.onConnectionLost(arg_id!, arg_errorMessage!); - return; - }); - } - } - } -} - -class _GattServiceHostApiCodec extends StandardMessageCodec { - const _GattServiceHostApiCodec(); -} - -class GattServiceHostApi { - /// Constructor for [GattServiceHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - GattServiceHostApi({BinaryMessenger? binaryMessenger}) : _binaryMessenger = binaryMessenger; - - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _GattServiceHostApiCodec(); - - Future free(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattServiceHostApi.free', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future> discoverCharacteristics(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattServiceHostApi.discoverCharacteristics', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as List?)!.cast(); - } - } -} - -class _GattCharacteristicHostApiCodec extends StandardMessageCodec { - const _GattCharacteristicHostApiCodec(); -} - -class GattCharacteristicHostApi { - /// Constructor for [GattCharacteristicHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - GattCharacteristicHostApi({BinaryMessenger? binaryMessenger}) : _binaryMessenger = binaryMessenger; - - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _GattCharacteristicHostApiCodec(); - - Future free(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.free', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future> discoverDescriptors(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.discoverDescriptors', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as List?)!.cast(); - } - } - - Future read(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.read', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as Uint8List?)!; - } - } - - Future write(String arg_id, Uint8List arg_value, bool arg_withoutResponse) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.write', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id, arg_value, arg_withoutResponse]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future setNotify(String arg_id, bool arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.setNotify', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id, arg_value]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } -} - -class _GattCharacteristicFlutterApiCodec extends StandardMessageCodec { - const _GattCharacteristicFlutterApiCodec(); -} -abstract class GattCharacteristicFlutterApi { - static const MessageCodec codec = _GattCharacteristicFlutterApiCodec(); - - void onValueChanged(String id, Uint8List value); - static void setup(GattCharacteristicFlutterApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicFlutterApi.onValueChanged', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMessageHandler(null); - } else { - channel.setMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattCharacteristicFlutterApi.onValueChanged was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattCharacteristicFlutterApi.onValueChanged was null, expected non-null String.'); - final Uint8List? arg_value = (args[1] as Uint8List?); - assert(arg_value != null, 'Argument for dev.flutter.pigeon.GattCharacteristicFlutterApi.onValueChanged was null, expected non-null Uint8List.'); - api.onValueChanged(arg_id!, arg_value!); - return; - }); - } - } - } -} - -class _GattDescriptorHostApiCodec extends StandardMessageCodec { - const _GattDescriptorHostApiCodec(); -} - -class GattDescriptorHostApi { - /// Constructor for [GattDescriptorHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - GattDescriptorHostApi({BinaryMessenger? binaryMessenger}) : _binaryMessenger = binaryMessenger; - - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _GattDescriptorHostApiCodec(); - - Future free(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattDescriptorHostApi.free', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } - - Future read(String arg_id) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattDescriptorHostApi.read', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as Uint8List?)!; - } - } - - Future write(String arg_id, Uint8List arg_value) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattDescriptorHostApi.write', codec, binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_id, arg_value]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return; - } - } -} diff --git a/lib/src/proto.dart b/lib/src/proto.dart deleted file mode 100644 index ce733c7..0000000 --- a/lib/src/proto.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'proto/messages.pb.dart'; -export 'proto/messages.pbenum.dart'; -export 'proto/messages.pbjson.dart'; diff --git a/lib/src/proto/messages.pb.dart b/lib/src/proto/messages.pb.dart deleted file mode 100644 index f97bc02..0000000 --- a/lib/src/proto/messages.pb.dart +++ /dev/null @@ -1,588 +0,0 @@ -/// -// Generated code. Do not modify. -// source: proto/messages.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -export 'messages.pbenum.dart'; - -class Broadcast extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Broadcast', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'proto'), createEmptyInstance: create) - ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'peripheral', subBuilder: Peripheral.create) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rssi', $pb.PbFieldType.O3) - ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'connectable') - ..a<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY) - ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'localName') - ..a<$core.List<$core.int>>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'manufacturerSpecificData', $pb.PbFieldType.OY) - ..pc(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serviceDatas', $pb.PbFieldType.PM, subBuilder: ServiceData.create) - ..pc(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serviceUuids', $pb.PbFieldType.PM, subBuilder: UUID.create) - ..pc(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'solicitedServiceUuids', $pb.PbFieldType.PM, subBuilder: UUID.create) - ..a<$core.int>(10, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txPowerLevel', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - Broadcast._() : super(); - factory Broadcast({ - Peripheral? peripheral, - $core.int? rssi, - $core.bool? connectable, - $core.List<$core.int>? data, - $core.String? localName, - $core.List<$core.int>? manufacturerSpecificData, - $core.Iterable? serviceDatas, - $core.Iterable? serviceUuids, - $core.Iterable? solicitedServiceUuids, - $core.int? txPowerLevel, - }) { - final _result = create(); - if (peripheral != null) { - _result.peripheral = peripheral; - } - if (rssi != null) { - _result.rssi = rssi; - } - if (connectable != null) { - _result.connectable = connectable; - } - if (data != null) { - _result.data = data; - } - if (localName != null) { - _result.localName = localName; - } - if (manufacturerSpecificData != null) { - _result.manufacturerSpecificData = manufacturerSpecificData; - } - if (serviceDatas != null) { - _result.serviceDatas.addAll(serviceDatas); - } - if (serviceUuids != null) { - _result.serviceUuids.addAll(serviceUuids); - } - if (solicitedServiceUuids != null) { - _result.solicitedServiceUuids.addAll(solicitedServiceUuids); - } - if (txPowerLevel != null) { - _result.txPowerLevel = txPowerLevel; - } - return _result; - } - factory Broadcast.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Broadcast.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Broadcast clone() => Broadcast()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Broadcast copyWith(void Function(Broadcast) updates) => super.copyWith((message) => updates(message as Broadcast)) as Broadcast; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Broadcast create() => Broadcast._(); - Broadcast createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static Broadcast getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Broadcast? _defaultInstance; - - @$pb.TagNumber(1) - Peripheral get peripheral => $_getN(0); - @$pb.TagNumber(1) - set peripheral(Peripheral v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasPeripheral() => $_has(0); - @$pb.TagNumber(1) - void clearPeripheral() => clearField(1); - @$pb.TagNumber(1) - Peripheral ensurePeripheral() => $_ensure(0); - - @$pb.TagNumber(2) - $core.int get rssi => $_getIZ(1); - @$pb.TagNumber(2) - set rssi($core.int v) { $_setSignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasRssi() => $_has(1); - @$pb.TagNumber(2) - void clearRssi() => clearField(2); - - @$pb.TagNumber(3) - $core.bool get connectable => $_getBF(2); - @$pb.TagNumber(3) - set connectable($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasConnectable() => $_has(2); - @$pb.TagNumber(3) - void clearConnectable() => clearField(3); - - @$pb.TagNumber(4) - $core.List<$core.int> get data => $_getN(3); - @$pb.TagNumber(4) - set data($core.List<$core.int> v) { $_setBytes(3, v); } - @$pb.TagNumber(4) - $core.bool hasData() => $_has(3); - @$pb.TagNumber(4) - void clearData() => clearField(4); - - @$pb.TagNumber(5) - $core.String get localName => $_getSZ(4); - @$pb.TagNumber(5) - set localName($core.String v) { $_setString(4, v); } - @$pb.TagNumber(5) - $core.bool hasLocalName() => $_has(4); - @$pb.TagNumber(5) - void clearLocalName() => clearField(5); - - @$pb.TagNumber(6) - $core.List<$core.int> get manufacturerSpecificData => $_getN(5); - @$pb.TagNumber(6) - set manufacturerSpecificData($core.List<$core.int> v) { $_setBytes(5, v); } - @$pb.TagNumber(6) - $core.bool hasManufacturerSpecificData() => $_has(5); - @$pb.TagNumber(6) - void clearManufacturerSpecificData() => clearField(6); - - @$pb.TagNumber(7) - $core.List get serviceDatas => $_getList(6); - - @$pb.TagNumber(8) - $core.List get serviceUuids => $_getList(7); - - @$pb.TagNumber(9) - $core.List get solicitedServiceUuids => $_getList(8); - - @$pb.TagNumber(10) - $core.int get txPowerLevel => $_getIZ(9); - @$pb.TagNumber(10) - set txPowerLevel($core.int v) { $_setSignedInt32(9, v); } - @$pb.TagNumber(10) - $core.bool hasTxPowerLevel() => $_has(9); - @$pb.TagNumber(10) - void clearTxPowerLevel() => clearField(10); -} - -class Peripheral extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Peripheral', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'proto'), createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uuid', subBuilder: UUID.create) - ..hasRequiredFields = false - ; - - Peripheral._() : super(); - factory Peripheral({ - $core.String? id, - UUID? uuid, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (uuid != null) { - _result.uuid = uuid; - } - return _result; - } - factory Peripheral.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Peripheral.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Peripheral clone() => Peripheral()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Peripheral copyWith(void Function(Peripheral) updates) => super.copyWith((message) => updates(message as Peripheral)) as Peripheral; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Peripheral create() => Peripheral._(); - Peripheral createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static Peripheral getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Peripheral? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - UUID get uuid => $_getN(1); - @$pb.TagNumber(2) - set uuid(UUID v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasUuid() => $_has(1); - @$pb.TagNumber(2) - void clearUuid() => clearField(2); - @$pb.TagNumber(2) - UUID ensureUuid() => $_ensure(1); -} - -class GattService extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GattService', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'proto'), createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uuid', subBuilder: UUID.create) - ..hasRequiredFields = false - ; - - GattService._() : super(); - factory GattService({ - $core.String? id, - UUID? uuid, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (uuid != null) { - _result.uuid = uuid; - } - return _result; - } - factory GattService.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GattService.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GattService clone() => GattService()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GattService copyWith(void Function(GattService) updates) => super.copyWith((message) => updates(message as GattService)) as GattService; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GattService create() => GattService._(); - GattService createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GattService getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GattService? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - UUID get uuid => $_getN(1); - @$pb.TagNumber(2) - set uuid(UUID v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasUuid() => $_has(1); - @$pb.TagNumber(2) - void clearUuid() => clearField(2); - @$pb.TagNumber(2) - UUID ensureUuid() => $_ensure(1); -} - -class GattCharacteristic extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GattCharacteristic', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'proto'), createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uuid', subBuilder: UUID.create) - ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'canRead') - ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'canWrite') - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'canWriteWithoutResponse') - ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'canNotify') - ..hasRequiredFields = false - ; - - GattCharacteristic._() : super(); - factory GattCharacteristic({ - $core.String? id, - UUID? uuid, - $core.bool? canRead, - $core.bool? canWrite, - $core.bool? canWriteWithoutResponse, - $core.bool? canNotify, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (uuid != null) { - _result.uuid = uuid; - } - if (canRead != null) { - _result.canRead = canRead; - } - if (canWrite != null) { - _result.canWrite = canWrite; - } - if (canWriteWithoutResponse != null) { - _result.canWriteWithoutResponse = canWriteWithoutResponse; - } - if (canNotify != null) { - _result.canNotify = canNotify; - } - return _result; - } - factory GattCharacteristic.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GattCharacteristic.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GattCharacteristic clone() => GattCharacteristic()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GattCharacteristic copyWith(void Function(GattCharacteristic) updates) => super.copyWith((message) => updates(message as GattCharacteristic)) as GattCharacteristic; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GattCharacteristic create() => GattCharacteristic._(); - GattCharacteristic createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GattCharacteristic getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GattCharacteristic? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - UUID get uuid => $_getN(1); - @$pb.TagNumber(2) - set uuid(UUID v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasUuid() => $_has(1); - @$pb.TagNumber(2) - void clearUuid() => clearField(2); - @$pb.TagNumber(2) - UUID ensureUuid() => $_ensure(1); - - @$pb.TagNumber(3) - $core.bool get canRead => $_getBF(2); - @$pb.TagNumber(3) - set canRead($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasCanRead() => $_has(2); - @$pb.TagNumber(3) - void clearCanRead() => clearField(3); - - @$pb.TagNumber(4) - $core.bool get canWrite => $_getBF(3); - @$pb.TagNumber(4) - set canWrite($core.bool v) { $_setBool(3, v); } - @$pb.TagNumber(4) - $core.bool hasCanWrite() => $_has(3); - @$pb.TagNumber(4) - void clearCanWrite() => clearField(4); - - @$pb.TagNumber(5) - $core.bool get canWriteWithoutResponse => $_getBF(4); - @$pb.TagNumber(5) - set canWriteWithoutResponse($core.bool v) { $_setBool(4, v); } - @$pb.TagNumber(5) - $core.bool hasCanWriteWithoutResponse() => $_has(4); - @$pb.TagNumber(5) - void clearCanWriteWithoutResponse() => clearField(5); - - @$pb.TagNumber(6) - $core.bool get canNotify => $_getBF(5); - @$pb.TagNumber(6) - set canNotify($core.bool v) { $_setBool(5, v); } - @$pb.TagNumber(6) - $core.bool hasCanNotify() => $_has(5); - @$pb.TagNumber(6) - void clearCanNotify() => clearField(6); -} - -class GattDescriptor extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GattDescriptor', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'proto'), createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uuid', subBuilder: UUID.create) - ..hasRequiredFields = false - ; - - GattDescriptor._() : super(); - factory GattDescriptor({ - $core.String? id, - UUID? uuid, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (uuid != null) { - _result.uuid = uuid; - } - return _result; - } - factory GattDescriptor.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GattDescriptor.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GattDescriptor clone() => GattDescriptor()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GattDescriptor copyWith(void Function(GattDescriptor) updates) => super.copyWith((message) => updates(message as GattDescriptor)) as GattDescriptor; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GattDescriptor create() => GattDescriptor._(); - GattDescriptor createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GattDescriptor getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GattDescriptor? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - UUID get uuid => $_getN(1); - @$pb.TagNumber(2) - set uuid(UUID v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasUuid() => $_has(1); - @$pb.TagNumber(2) - void clearUuid() => clearField(2); - @$pb.TagNumber(2) - UUID ensureUuid() => $_ensure(1); -} - -class UUID extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UUID', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'proto'), createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value') - ..hasRequiredFields = false - ; - - UUID._() : super(); - factory UUID({ - $core.String? value, - }) { - final _result = create(); - if (value != null) { - _result.value = value; - } - return _result; - } - factory UUID.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory UUID.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - UUID clone() => UUID()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - UUID copyWith(void Function(UUID) updates) => super.copyWith((message) => updates(message as UUID)) as UUID; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static UUID create() => UUID._(); - UUID createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static UUID getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static UUID? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get value => $_getSZ(0); - @$pb.TagNumber(1) - set value($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasValue() => $_has(0); - @$pb.TagNumber(1) - void clearValue() => clearField(1); -} - -class ServiceData extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServiceData', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'proto'), createEmptyInstance: create) - ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uuid', subBuilder: UUID.create) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY) - ..hasRequiredFields = false - ; - - ServiceData._() : super(); - factory ServiceData({ - UUID? uuid, - $core.List<$core.int>? data, - }) { - final _result = create(); - if (uuid != null) { - _result.uuid = uuid; - } - if (data != null) { - _result.data = data; - } - return _result; - } - factory ServiceData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ServiceData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ServiceData clone() => ServiceData()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ServiceData copyWith(void Function(ServiceData) updates) => super.copyWith((message) => updates(message as ServiceData)) as ServiceData; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ServiceData create() => ServiceData._(); - ServiceData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static ServiceData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static ServiceData? _defaultInstance; - - @$pb.TagNumber(1) - UUID get uuid => $_getN(0); - @$pb.TagNumber(1) - set uuid(UUID v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasUuid() => $_has(0); - @$pb.TagNumber(1) - void clearUuid() => clearField(1); - @$pb.TagNumber(1) - UUID ensureUuid() => $_ensure(0); - - @$pb.TagNumber(2) - $core.List<$core.int> get data => $_getN(1); - @$pb.TagNumber(2) - set data($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasData() => $_has(1); - @$pb.TagNumber(2) - void clearData() => clearField(2); -} - diff --git a/lib/src/proto/messages.pbenum.dart b/lib/src/proto/messages.pbenum.dart deleted file mode 100644 index 0d6fafe..0000000 --- a/lib/src/proto/messages.pbenum.dart +++ /dev/null @@ -1,28 +0,0 @@ -/// -// Generated code. Do not modify. -// source: proto/messages.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class BluetoothState extends $pb.ProtobufEnum { - static const BluetoothState BLUETOOTH_STATE_UNSUPPORTED = BluetoothState._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BLUETOOTH_STATE_UNSUPPORTED'); - static const BluetoothState BLUETOOTH_STATE_POWERED_OFF = BluetoothState._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BLUETOOTH_STATE_POWERED_OFF'); - static const BluetoothState BLUETOOTH_STATE_POWERED_ON = BluetoothState._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BLUETOOTH_STATE_POWERED_ON'); - - static const $core.List values = [ - BLUETOOTH_STATE_UNSUPPORTED, - BLUETOOTH_STATE_POWERED_OFF, - BLUETOOTH_STATE_POWERED_ON, - ]; - - static final $core.Map<$core.int, BluetoothState> _byValue = $pb.ProtobufEnum.initByValue(values); - static BluetoothState? valueOf($core.int value) => _byValue[value]; - - const BluetoothState._($core.int v, $core.String n) : super(v, n); -} - diff --git a/lib/src/proto/messages.pbjson.dart b/lib/src/proto/messages.pbjson.dart deleted file mode 100644 index d6cf34d..0000000 --- a/lib/src/proto/messages.pbjson.dart +++ /dev/null @@ -1,115 +0,0 @@ -/// -// Generated code. Do not modify. -// source: proto/messages.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use bluetoothStateDescriptor instead') -const BluetoothState$json = const { - '1': 'BluetoothState', - '2': const [ - const {'1': 'BLUETOOTH_STATE_UNSUPPORTED', '2': 0}, - const {'1': 'BLUETOOTH_STATE_POWERED_OFF', '2': 1}, - const {'1': 'BLUETOOTH_STATE_POWERED_ON', '2': 2}, - ], -}; - -/// Descriptor for `BluetoothState`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List bluetoothStateDescriptor = $convert.base64Decode('Cg5CbHVldG9vdGhTdGF0ZRIfChtCTFVFVE9PVEhfU1RBVEVfVU5TVVBQT1JURUQQABIfChtCTFVFVE9PVEhfU1RBVEVfUE9XRVJFRF9PRkYQARIeChpCTFVFVE9PVEhfU1RBVEVfUE9XRVJFRF9PThAC'); -@$core.Deprecated('Use broadcastDescriptor instead') -const Broadcast$json = const { - '1': 'Broadcast', - '2': const [ - const {'1': 'peripheral', '3': 1, '4': 1, '5': 11, '6': '.proto.Peripheral', '10': 'peripheral'}, - const {'1': 'rssi', '3': 2, '4': 1, '5': 5, '10': 'rssi'}, - const {'1': 'connectable', '3': 3, '4': 1, '5': 8, '9': 0, '10': 'connectable', '17': true}, - const {'1': 'data', '3': 4, '4': 1, '5': 12, '10': 'data'}, - const {'1': 'local_name', '3': 5, '4': 1, '5': 9, '9': 1, '10': 'localName', '17': true}, - const {'1': 'manufacturer_specific_data', '3': 6, '4': 1, '5': 12, '10': 'manufacturerSpecificData'}, - const {'1': 'service_datas', '3': 7, '4': 3, '5': 11, '6': '.proto.ServiceData', '10': 'serviceDatas'}, - const {'1': 'service_uuids', '3': 8, '4': 3, '5': 11, '6': '.proto.UUID', '10': 'serviceUuids'}, - const {'1': 'solicited_service_uuids', '3': 9, '4': 3, '5': 11, '6': '.proto.UUID', '10': 'solicitedServiceUuids'}, - const {'1': 'tx_power_level', '3': 10, '4': 1, '5': 5, '9': 2, '10': 'txPowerLevel', '17': true}, - ], - '8': const [ - const {'1': '_connectable'}, - const {'1': '_local_name'}, - const {'1': '_tx_power_level'}, - ], -}; - -/// Descriptor for `Broadcast`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List broadcastDescriptor = $convert.base64Decode('CglCcm9hZGNhc3QSMQoKcGVyaXBoZXJhbBgBIAEoCzIRLnByb3RvLlBlcmlwaGVyYWxSCnBlcmlwaGVyYWwSEgoEcnNzaRgCIAEoBVIEcnNzaRIlCgtjb25uZWN0YWJsZRgDIAEoCEgAUgtjb25uZWN0YWJsZYgBARISCgRkYXRhGAQgASgMUgRkYXRhEiIKCmxvY2FsX25hbWUYBSABKAlIAVIJbG9jYWxOYW1liAEBEjwKGm1hbnVmYWN0dXJlcl9zcGVjaWZpY19kYXRhGAYgASgMUhhtYW51ZmFjdHVyZXJTcGVjaWZpY0RhdGESNwoNc2VydmljZV9kYXRhcxgHIAMoCzISLnByb3RvLlNlcnZpY2VEYXRhUgxzZXJ2aWNlRGF0YXMSMAoNc2VydmljZV91dWlkcxgIIAMoCzILLnByb3RvLlVVSURSDHNlcnZpY2VVdWlkcxJDChdzb2xpY2l0ZWRfc2VydmljZV91dWlkcxgJIAMoCzILLnByb3RvLlVVSURSFXNvbGljaXRlZFNlcnZpY2VVdWlkcxIpCg50eF9wb3dlcl9sZXZlbBgKIAEoBUgCUgx0eFBvd2VyTGV2ZWyIAQFCDgoMX2Nvbm5lY3RhYmxlQg0KC19sb2NhbF9uYW1lQhEKD190eF9wb3dlcl9sZXZlbA=='); -@$core.Deprecated('Use peripheralDescriptor instead') -const Peripheral$json = const { - '1': 'Peripheral', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'uuid', '3': 2, '4': 1, '5': 11, '6': '.proto.UUID', '10': 'uuid'}, - ], -}; - -/// Descriptor for `Peripheral`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List peripheralDescriptor = $convert.base64Decode('CgpQZXJpcGhlcmFsEg4KAmlkGAEgASgJUgJpZBIfCgR1dWlkGAIgASgLMgsucHJvdG8uVVVJRFIEdXVpZA=='); -@$core.Deprecated('Use gattServiceDescriptor instead') -const GattService$json = const { - '1': 'GattService', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'uuid', '3': 2, '4': 1, '5': 11, '6': '.proto.UUID', '10': 'uuid'}, - ], -}; - -/// Descriptor for `GattService`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gattServiceDescriptor = $convert.base64Decode('CgtHYXR0U2VydmljZRIOCgJpZBgBIAEoCVICaWQSHwoEdXVpZBgCIAEoCzILLnByb3RvLlVVSURSBHV1aWQ='); -@$core.Deprecated('Use gattCharacteristicDescriptor instead') -const GattCharacteristic$json = const { - '1': 'GattCharacteristic', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'uuid', '3': 2, '4': 1, '5': 11, '6': '.proto.UUID', '10': 'uuid'}, - const {'1': 'can_read', '3': 3, '4': 1, '5': 8, '10': 'canRead'}, - const {'1': 'can_write', '3': 4, '4': 1, '5': 8, '10': 'canWrite'}, - const {'1': 'can_write_without_response', '3': 5, '4': 1, '5': 8, '10': 'canWriteWithoutResponse'}, - const {'1': 'can_notify', '3': 6, '4': 1, '5': 8, '10': 'canNotify'}, - ], -}; - -/// Descriptor for `GattCharacteristic`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gattCharacteristicDescriptor = $convert.base64Decode('ChJHYXR0Q2hhcmFjdGVyaXN0aWMSDgoCaWQYASABKAlSAmlkEh8KBHV1aWQYAiABKAsyCy5wcm90by5VVUlEUgR1dWlkEhkKCGNhbl9yZWFkGAMgASgIUgdjYW5SZWFkEhsKCWNhbl93cml0ZRgEIAEoCFIIY2FuV3JpdGUSOwoaY2FuX3dyaXRlX3dpdGhvdXRfcmVzcG9uc2UYBSABKAhSF2NhbldyaXRlV2l0aG91dFJlc3BvbnNlEh0KCmNhbl9ub3RpZnkYBiABKAhSCWNhbk5vdGlmeQ=='); -@$core.Deprecated('Use gattDescriptorDescriptor instead') -const GattDescriptor$json = const { - '1': 'GattDescriptor', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'uuid', '3': 2, '4': 1, '5': 11, '6': '.proto.UUID', '10': 'uuid'}, - ], -}; - -/// Descriptor for `GattDescriptor`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gattDescriptorDescriptor = $convert.base64Decode('Cg5HYXR0RGVzY3JpcHRvchIOCgJpZBgBIAEoCVICaWQSHwoEdXVpZBgCIAEoCzILLnByb3RvLlVVSURSBHV1aWQ='); -@$core.Deprecated('Use uUIDDescriptor instead') -const UUID$json = const { - '1': 'UUID', - '2': const [ - const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'}, - ], -}; - -/// Descriptor for `UUID`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List uUIDDescriptor = $convert.base64Decode('CgRVVUlEEhQKBXZhbHVlGAEgASgJUgV2YWx1ZQ=='); -@$core.Deprecated('Use serviceDataDescriptor instead') -const ServiceData$json = const { - '1': 'ServiceData', - '2': const [ - const {'1': 'uuid', '3': 1, '4': 1, '5': 11, '6': '.proto.UUID', '10': 'uuid'}, - const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'}, - ], -}; - -/// Descriptor for `ServiceData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List serviceDataDescriptor = $convert.base64Decode('CgtTZXJ2aWNlRGF0YRIfCgR1dWlkGAEgASgLMgsucHJvdG8uVVVJRFIEdXVpZBISCgRkYXRhGAIgASgMUgRkYXRh'); diff --git a/lib/src/proto/messages.pbserver.dart b/lib/src/proto/messages.pbserver.dart deleted file mode 100644 index 0dc5b00..0000000 --- a/lib/src/proto/messages.pbserver.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// -// Generated code. Do not modify. -// source: proto/messages.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - -export 'messages.pb.dart'; - diff --git a/lib/src/uuid.dart b/lib/src/uuid.dart deleted file mode 100644 index 881989e..0000000 --- a/lib/src/uuid.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'impl.dart'; - -abstract class UUID { - String get value; - - factory UUID(String value) { - return MyUUID(value: value); - } -} diff --git a/pigeon/messages.dart b/pigeon/messages.dart deleted file mode 100644 index 1470848..0000000 --- a/pigeon/messages.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'package:pigeon/pigeon.dart'; - -@ConfigurePigeon( - PigeonOptions( - dartOut: 'lib/src/pigeon/messages.g.dart', - dartTestOut: 'test/pigeon/test_messages.g.dart', - javaOut: - 'android/src/main/java/dev/yanshouwang/bluetooth_low_energy/pigeon/Messages.java', - javaOptions: JavaOptions( - package: 'dev.yanshouwang.bluetooth_low_energy.pigeon', - ), - objcHeaderOut: 'ios/Classes/pigeon/Messages.h', - objcSourceOut: 'ios/Classes/pigeon/Messages.m', - objcOptions: ObjcOptions( - header: 'ios/Classes/pigeon/Messages.h', - prefix: 'Pigeon', - ), - ), -) -@HostApi(dartHostTestHandler: 'TestCentralControllerHostApi') -abstract class CentralManagerHostApi { - @ObjCSelector('authorize') - @async - bool authorize(); - @ObjCSelector('getState') - int getState(); - @ObjCSelector('startScan:') - @async - void startScan(List? uuidBuffers); - @ObjCSelector('stopScan') - void stopScan(); -} - -@FlutterApi() -abstract class CentralManagerFlutterApi { - @ObjCSelector('onStateChanged:') - void onStateChanged(int stateNumber); - @ObjCSelector('onScanned:') - void onScanned(Uint8List broadcastBuffer); -} - -@HostApi(dartHostTestHandler: 'TestPeripheralHostApi') -abstract class PeripheralHostApi { - @ObjCSelector('free:') - void free(String id); - @ObjCSelector('connect:') - @async - void connect(String id); - @ObjCSelector('disconnect:') - @async - void disconnect(String id); - @ObjCSelector('requestMtu:') - @async - int requestMtu(String id); - @ObjCSelector('discoverServices:') - @async - List discoverServices(String id); -} - -@FlutterApi() -abstract class PeripheralFlutterApi { - @ObjCSelector('onConnectionLost:errorMessage:') - void onConnectionLost(String id, String errorMessage); -} - -@HostApi(dartHostTestHandler: 'TestGattServiceHostApi') -abstract class GattServiceHostApi { - @ObjCSelector('free:') - void free(String id); - @ObjCSelector('discoverCharacteristics:') - @async - List discoverCharacteristics(String id); -} - -@HostApi(dartHostTestHandler: 'TestGattCharacteristicHostApi') -abstract class GattCharacteristicHostApi { - @ObjCSelector('free:') - void free(String id); - @ObjCSelector('discoverDescriptors:') - @async - List discoverDescriptors(String id); - @ObjCSelector('read:') - @async - Uint8List read(String id); - @ObjCSelector('write:value:withoutResponse:') - @async - void write(String id, Uint8List value, bool withoutResponse); - @ObjCSelector('setNotify:value:') - @async - void setNotify(String id, bool value); -} - -@FlutterApi() -abstract class GattCharacteristicFlutterApi { - @ObjCSelector('onValueChanged:value:') - void onValueChanged(String id, Uint8List value); -} - -@HostApi(dartHostTestHandler: 'TestGattDescriptorHostApi') -abstract class GattDescriptorHostApi { - @ObjCSelector('free:') - void free(String id); - @ObjCSelector('read:') - @async - Uint8List read(String id); - @ObjCSelector('write:value:') - @async - void write(String id, Uint8List value); -} diff --git a/proto/messages.proto b/proto/messages.proto deleted file mode 100644 index d54ea0d..0000000 --- a/proto/messages.proto +++ /dev/null @@ -1,57 +0,0 @@ -syntax = "proto3"; -package proto; - -option java_package = "dev.yanshouwang.bluetooth_low_energy.proto"; -option java_multiple_files = true; - -message Broadcast { - Peripheral peripheral = 1; - int32 rssi = 2; - optional bool connectable = 3; - bytes data = 4; - optional string local_name = 5; - bytes manufacturer_specific_data = 6; - repeated ServiceData service_datas = 7; - repeated UUID service_uuids = 8; - repeated UUID solicited_service_uuids = 9; - optional int32 tx_power_level = 10; -} - -message Peripheral { - string id = 1; - UUID uuid = 2; -} - -message GattService { - string id = 1; - UUID uuid = 2; -} - -message GattCharacteristic { - string id = 1; - UUID uuid = 2; - bool can_read = 3; - bool can_write = 4; - bool can_write_without_response = 5; - bool can_notify = 6; -} - -message GattDescriptor { - string id = 1; - UUID uuid = 2; -} - -enum BluetoothState { - BLUETOOTH_STATE_UNSUPPORTED = 0; - BLUETOOTH_STATE_POWERED_OFF = 1; - BLUETOOTH_STATE_POWERED_ON = 2; -} - -message UUID { - string value = 1; -} - -message ServiceData { - UUID uuid = 1; - bytes data = 2; -} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml deleted file mode 100644 index 6cf2b01..0000000 --- a/pubspec.yaml +++ /dev/null @@ -1,76 +0,0 @@ -name: bluetooth_low_energy -description: A bluetooth low energy plugin for flutter, which can be used to develope central role apps. -version: 1.1.0 -homepage: https://github.com/yanshouwang/bluetooth_low_energy - -environment: - sdk: ">=2.17.6 <3.0.0" - flutter: ">=2.5.0" - -dependencies: - flutter: - sdk: flutter - plugin_platform_interface: ^2.0.2 - pigeon: ^4.0.2 - protobuf: ^2.1.0 - fixnum: ^1.0.1 - tuple: ^2.0.0 - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^2.0.0 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. -flutter: - # This section identifies this Flutter project as a plugin project. - # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) - # which should be registered in the plugin registry. This is required for - # using method channels. - # The Android 'package' specifies package in which the registered class is. - # This is required for using method channels on Android. - # The 'ffiPlugin' specifies that native code should be built and bundled. - # This is required for using `dart:ffi`. - # All these are used by the tooling to maintain consistency when - # adding or updating assets for this project. - plugin: - platforms: - android: - package: dev.yanshouwang.bluetooth_low_energy - pluginClass: BluetoothLowEnergyPlugin - ios: - pluginClass: BluetoothLowEnergyPlugin - - # To add assets to your plugin package, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # - # For details regarding assets in packages, see - # https://flutter.dev/assets-and-images/#from-packages - # - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # To add custom fonts to your plugin package, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts in packages, see - # https://flutter.dev/custom-fonts/#from-packages diff --git a/scripts/run_pigeon.sh b/scripts/run_pigeon.sh index ca1938e..715890e 100644 --- a/scripts/run_pigeon.sh +++ b/scripts/run_pigeon.sh @@ -1,34 +1 @@ -DART_OUT=lib/src/pigeon -DART_TEST_OUT=test/pigeon -JAVA_OUT=android/src/main/java/dev/yanshouwang/bluetooth_low_energy/pigeon -SWIFT_OUT=ios/Classes/pigeon - -if [ -d $DART_OUT ] -then - rm -rf ${DART_OUT}/* -else - mkdir -p $DART_OUT -fi - -if [ -d $DART_TEST_OUT ] -then - rm -rf ${DART_TEST_OUT}/* -else - mkdir -p $DART_TEST_OUT -fi - -if [ -d $JAVA_OUT ] -then - rm -rf ${JAVA_OUT}/* -else - mkdir -p $JAVA_OUT -fi - -if [ -d $SWIFT_OUT ] -then - rm -rf ${SWIFT_OUT}/* -else - mkdir -p $SWIFT_OUT -fi - -flutter pub run pigeon --input pigeon/messages.dart \ No newline at end of file +dart run pigeon --input my_api.dart \ No newline at end of file diff --git a/scripts/run_protoc.sh b/scripts/run_protoc.sh deleted file mode 100644 index 0338615..0000000 --- a/scripts/run_protoc.sh +++ /dev/null @@ -1,53 +0,0 @@ -DART_OUT=lib/src -JAVA_OUT=android/src/main/java -KOTLIN_OUT=android/src/main/kotlin -SWIFT_OUT=ios/Classes - -PACKAGE=dev/yanshouwang/bluetooth_low_energy/proto - -if [ -d $DART_OUT ] -then - if [ -d ${DART_OUT}/proto ] - then - rm -rf ${DART_OUT}/proto/* - fi -else - mkdir -p $DART_OUT -fi - -if [ -d $JAVA_OUT ] -then - if [ -d ${JAVA_OUT}/$PACKAGE ] - then - rm -rf ${JAVA_OUT}/$PACKAGE/* - fi -else - mkdir -p $JAVA_OUT -fi - -if [ -d $KOTLIN_OUT ] -then - if [ -d ${KOTLIN_OUT}/$PACKAGE ] - then - rm -rf ${KOTLIN_OUT}/$PACKAGE/* - fi -else - mkdir -p $KOTLIN_OUT -fi - -if [ -d $SWIFT_OUT ] -then - if [ -d ${SWIFT_OUT}/proto ] - then - rm -rf ${SWIFT_OUT}/proto/* - fi -else - mkdir -p $SWIFT_OUT -fi - -protoc \ - --dart_out $DART_OUT \ - --java_out $JAVA_OUT \ - --kotlin_out $KOTLIN_OUT \ - --swift_out $SWIFT_OUT \ - proto/messages.proto \ No newline at end of file diff --git a/test/pigeon/test_messages.g.dart b/test/pigeon/test_messages.g.dart deleted file mode 100644 index 49322da..0000000 --- a/test/pigeon/test_messages.g.dart +++ /dev/null @@ -1,382 +0,0 @@ -// Autogenerated from Pigeon (v4.2.0), do not edit directly. -// See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import -// ignore_for_file: avoid_relative_lib_imports -import 'dart:async'; -import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:bluetooth_low_energy/src/pigeon/messages.g.dart'; - -class _TestCentralControllerHostApiCodec extends StandardMessageCodec { - const _TestCentralControllerHostApiCodec(); -} -abstract class TestCentralControllerHostApi { - static const MessageCodec codec = _TestCentralControllerHostApiCodec(); - - Future authorize(); - int getState(); - Future startScan(List? uuidBuffers); - void stopScan(); - static void setup(TestCentralControllerHostApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.authorize', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - // ignore message - final bool output = await api.authorize(); - return {'result': output}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.getState', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - // ignore message - final int output = api.getState(); - return {'result': output}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.startScan', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.CentralManagerHostApi.startScan was null.'); - final List args = (message as List?)!; - final List? arg_uuidBuffers = (args[0] as List?)?.cast(); - await api.startScan(arg_uuidBuffers); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.CentralManagerHostApi.stopScan', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - // ignore message - api.stopScan(); - return {}; - }); - } - } - } -} - -class _TestPeripheralHostApiCodec extends StandardMessageCodec { - const _TestPeripheralHostApiCodec(); -} -abstract class TestPeripheralHostApi { - static const MessageCodec codec = _TestPeripheralHostApiCodec(); - - void free(String id); - Future connect(String id); - Future disconnect(String id); - Future requestMtu(String id); - Future> discoverServices(String id); - static void setup(TestPeripheralHostApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.free', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.free was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.free was null, expected non-null String.'); - api.free(arg_id!); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.connect', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.connect was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.connect was null, expected non-null String.'); - await api.connect(arg_id!); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.disconnect', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.disconnect was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.disconnect was null, expected non-null String.'); - await api.disconnect(arg_id!); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.requestMtu', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.requestMtu was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.requestMtu was null, expected non-null String.'); - final int output = await api.requestMtu(arg_id!); - return {'result': output}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.PeripheralHostApi.discoverServices', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.discoverServices was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.PeripheralHostApi.discoverServices was null, expected non-null String.'); - final List output = await api.discoverServices(arg_id!); - return {'result': output}; - }); - } - } - } -} - -class _TestGattServiceHostApiCodec extends StandardMessageCodec { - const _TestGattServiceHostApiCodec(); -} -abstract class TestGattServiceHostApi { - static const MessageCodec codec = _TestGattServiceHostApiCodec(); - - void free(String id); - Future> discoverCharacteristics(String id); - static void setup(TestGattServiceHostApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattServiceHostApi.free', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattServiceHostApi.free was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattServiceHostApi.free was null, expected non-null String.'); - api.free(arg_id!); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattServiceHostApi.discoverCharacteristics', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattServiceHostApi.discoverCharacteristics was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattServiceHostApi.discoverCharacteristics was null, expected non-null String.'); - final List output = await api.discoverCharacteristics(arg_id!); - return {'result': output}; - }); - } - } - } -} - -class _TestGattCharacteristicHostApiCodec extends StandardMessageCodec { - const _TestGattCharacteristicHostApiCodec(); -} -abstract class TestGattCharacteristicHostApi { - static const MessageCodec codec = _TestGattCharacteristicHostApiCodec(); - - void free(String id); - Future> discoverDescriptors(String id); - Future read(String id); - Future write(String id, Uint8List value, bool withoutResponse); - Future setNotify(String id, bool value); - static void setup(TestGattCharacteristicHostApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.free', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.free was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.free was null, expected non-null String.'); - api.free(arg_id!); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.discoverDescriptors', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.discoverDescriptors was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.discoverDescriptors was null, expected non-null String.'); - final List output = await api.discoverDescriptors(arg_id!); - return {'result': output}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.read', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.read was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.read was null, expected non-null String.'); - final Uint8List output = await api.read(arg_id!); - return {'result': output}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.write', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.write was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.write was null, expected non-null String.'); - final Uint8List? arg_value = (args[1] as Uint8List?); - assert(arg_value != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.write was null, expected non-null Uint8List.'); - final bool? arg_withoutResponse = (args[2] as bool?); - assert(arg_withoutResponse != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.write was null, expected non-null bool.'); - await api.write(arg_id!, arg_value!, arg_withoutResponse!); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattCharacteristicHostApi.setNotify', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.setNotify was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.setNotify was null, expected non-null String.'); - final bool? arg_value = (args[1] as bool?); - assert(arg_value != null, 'Argument for dev.flutter.pigeon.GattCharacteristicHostApi.setNotify was null, expected non-null bool.'); - await api.setNotify(arg_id!, arg_value!); - return {}; - }); - } - } - } -} - -class _TestGattDescriptorHostApiCodec extends StandardMessageCodec { - const _TestGattDescriptorHostApiCodec(); -} -abstract class TestGattDescriptorHostApi { - static const MessageCodec codec = _TestGattDescriptorHostApiCodec(); - - void free(String id); - Future read(String id); - Future write(String id, Uint8List value); - static void setup(TestGattDescriptorHostApi? api, {BinaryMessenger? binaryMessenger}) { - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattDescriptorHostApi.free', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattDescriptorHostApi.free was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattDescriptorHostApi.free was null, expected non-null String.'); - api.free(arg_id!); - return {}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattDescriptorHostApi.read', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattDescriptorHostApi.read was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattDescriptorHostApi.read was null, expected non-null String.'); - final Uint8List output = await api.read(arg_id!); - return {'result': output}; - }); - } - } - { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.GattDescriptorHostApi.write', codec, binaryMessenger: binaryMessenger); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, 'Argument for dev.flutter.pigeon.GattDescriptorHostApi.write was null.'); - final List args = (message as List?)!; - final String? arg_id = (args[0] as String?); - assert(arg_id != null, 'Argument for dev.flutter.pigeon.GattDescriptorHostApi.write was null, expected non-null String.'); - final Uint8List? arg_value = (args[1] as Uint8List?); - assert(arg_value != null, 'Argument for dev.flutter.pigeon.GattDescriptorHostApi.write was null, expected non-null Uint8List.'); - await api.write(arg_id!, arg_value!); - return {}; - }); - } - } - } -}