Git Product home page Git Product logo

quick_blue's People

Contributors

ebaglieriskylabs avatar fotidim avatar sunbreak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

quick_blue's Issues

MTU change

is there a way to change MTU value and priority to increase data rate (Bluetooth 5)?

Weird issue regarding deviceid

I've made a generic method to connect to a BLE device, but when I debug it it crashes on a 'PlatformException(IllegalArgument, Unknown deviceId: 00:A0:50:CE:79:25, null, null)' error, which I find quite weird considering the device ID comes from the setConnectionHandler callback.

    Future<void> _handleConnectionChange(String deviceId, BlueConnectionState state) async {
      print('_handleConnectionChange $deviceId' + " : " + state.value.toString());


      if(state.value == "connected"){
        QuickBlue.discoverServices(deviceId);
        ServiceFactory sf = ServiceFactory();
        var service = sf.BuildServiceC();
        var idinfoRequest =
        service.GetCharacteristic(Characteristics.IDENTIFICATION_INFO_REQUEST);

        if(idinfoRequest == null || idinfoResponse == null){
          return;
        }

        QuickBlue.writeValue(deviceId, service.UUID.toLowerCase(), idinfoRequest.UUID.toLowerCase(), Uint8List(1), BleOutputProperty.withResponse);
      }
    }

    QuickBlue.setConnectionHandler(_handleConnectionChange);

Discoverservices works fine, but the writeValue functions returns the exception given above.

Is this a bug or am I doing something wrong?

Can't run on windows

Hi,

I tried to test quick_blue (cool project, looks promising) on windows. Unfortunately I get this error message:

D:\temp\flutter\ble_tst>flutter run -d windows
Launching lib\main.dart on Windows in debug mode...
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: Der Befehl "setlocal [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -DBUILD_TYPE=Debug -P cmake_install.cmake [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: :cmEnd [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: :cmErrorLevel [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: exit /b %1 [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: :cmDone [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: :VCEnd" wurde mit dem Code 1 beendet. [D:\temp\flutter\ble_tst\build\windows\INSTALL.vcxproj]
Building Windows application...
Exception: Build process failed.

Do you have any hints? This is my flutter doctor -v output:

D:\temp\flutter\ble_tst>flutter doctor -v
[√] Flutter (Channel dev, 1.25.0-8.0.pre, on Microsoft Windows [Version 10.0.18363.1256], locale de-DE)
    • Flutter version 1.25.0-8.0.pre at C:\flutter
    • Framework revision a12e2a473a (2 days ago), 2020-12-08 23:13:04 -0500
    • Engine revision df39e5c515
    • Dart version 2.12.0 (build 2.12.0-133.0.dev)

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at C:\Users\marku\AppData\Local\Android\Sdk
    • Platform android-29, build-tools 29.0.2
    • ANDROID_HOME = C:\Users\marku\AppData\Local\Android\Sdk
    • Java binary at: D:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.8.2)
    • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
    • Visual Studio Community 2019 version 16.8.30717.126
    • Windows 10 SDK version 10.0.18362.0

[√] Android Studio (version 3.6)
    • Android Studio at D:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] VS Code (version 1.51.1)
    • VS Code at C:\Users\marku\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.17.0

[√] Connected device (3 available)
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.18363.1256]
    • Chrome (web)      • chrome  • web-javascript • Google Chrome 87.0.4280.88
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 87.0.664.55

• No issues found!

[Windows] Expose isPaired and canPair

I would like to monitor the pairing status so that I prompt the user to pair through Windows settings if needed. There are the isPaired and the carPair properties. I would be great of those would be exposed on the Flutter side.

Pair request on windows

When I want to read a protected characteristic, on android a pair request is automatically created and after that, I can read the data. On windows, the pair request is not created automatically and app crashes

[Windows] Lost connection to device when paired

Hi,
I just want to say thank you so much for the package for BLE, I am still very new, but I want to help if I can. I am trying to use some services which require authorization (Apple Notification Center Service). For now, I am testing using LightBlue and creating a virtual peripheral. I noticed that when I try to pair my device manually in windows settings, the pairing is successful, but when I try to listen via setNotifiable(...) I lose connection to the device. This error disappears again if I go back into windows settings and unpair the device. I am fairly new to flutter or BLE so I may be misunderstanding some fundamentals.

Note: This code is running on Windows and communicating with my iPhone.

flutter doctor -v

[√] Flutter (Channel stable, 2.10.4, on Microsoft Windows [Version 10.0.22000.613], locale en-US)
• Flutter version 2.10.4 at C:\Users\mazime\src\Flutter\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision c860cba910 (3 weeks ago), 2022-03-25 00:23:12 -0500
• Engine revision 57d3bac3dd
• Dart version 2.16.2
• DevTools version 2.9.2
[√] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
• Android SDK at C:\Users\Popsi\AppData\Local\Android\sdk
[√] HTTP Host Availability
• All required HTTP hosts are available
• No issues found!

Code

  void _handleConnectionChange(String deviceId, BlueConnectionState state) {
    print('_handleConnectionChange $deviceId, $state');
    print(state.value);
    if (state.value == "connected") {
      print("Discovering Services!");
      //QuickBlue.discoverServices(deviceId); Not Necessary
      QuickBlue.setNotifiable(
          deviceId, serviceid, charid, BleInputProperty.notification);
    }
  }

What pairing looks like.
image
Note that both of these devices will appear after a single pairing attempt.

Not even the virtual LightBlue services work anymore

flutter: Alert Notification
flutter: Found
flutter: stopScan invokeMethod success
flutter: _handleConnectionChange 104442226430328, Instance of 'BlueConnectionState'
flutter: connected
flutter: Discovering Services!
flutter: _handleConnectionChange 104442226430328, Instance of 'BlueConnectionState'
flutter: connected
flutter: Discovering Services!
Lost connection to device.

^ Ignore the random prints

When I click remove device and unpair the code begins to work again and I can easily listen to the virtual peripheral provided by LightBlue

flutter: _handleConnectionChange 105262347644159, Instance of 'BlueConnectionState'
flutter: connected
flutter: 5fbc4cd6ecff
flutter: Discovering Services!
flutter: _handleValueChange 105262347644159, 00002a46-0000-1000-8000-00805f9b34fb, 000000000f0e0d0000
flutter: _handleValueChange 105262347644159, 00002a46-0000-1000-8000-00805f9b34fb, 000000000f0e0d0000
flutter: _handleValueChange 105262347644159, 00002a46-0000-1000-8000-00805f9b34fb, 000000000f0e0d0000
flutter: _handleValueChange 105262347644159, 00002a46-0000-1000-8000-00805f9b34fb, 000000000f0e0d0000

I am hoping that pairing the device will not make my Windows computer unable to communicate with my iOS device as I think that many of Apple's built-in services require the device to be paired, although I may be wrong about that.

Windows BluetoothDeviceAgent use after free.

The agents are stored as unique pointers, and then passed to async methods as references. If you disconnect the device then the memory for the agent is freed. The references outstanding coroutines have are now invalid.

winrt::fire_and_forget QuickBlueWindowsPlugin::SetNotifiableAsync(BluetoothDeviceAgent& bluetoothDeviceAgent, std::string service, std::string characteristic, std::string bleInputProperty) {

While waiting here someone calls disconnect, which executes synchronously and deletes bluetoothDeviceAgent.

  auto gattCharacteristic = co_await bluetoothDeviceAgent.GetCharacteristicAsync(service, characteristic);

  auto descriptorValue = bleInputProperty == "notification" ? GattClientCharacteristicConfigurationDescriptorValue::Notify
    : bleInputProperty == "indication" ? GattClientCharacteristicConfigurationDescriptorValue::Indicate
    : GattClientCharacteristicConfigurationDescriptorValue::None;
  auto writeDescriptorStatus = co_await gattCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(descriptorValue);
  if (writeDescriptorStatus != GattCommunicationStatus::Success)
    OutputDebugString((L"WriteClientCharacteristicConfigurationDescriptorAsync " + winrt::to_hstring((int32_t)writeDescriptorStatus) + L"\n").c_str());

When this code executes you get undefined behavior, and most likely an access violation.

  if (bleInputProperty != "disabled") {
    bluetoothDeviceAgent.valueChangedTokens[characteristic] = gattCharacteristic.ValueChanged({ this, &QuickBlueWindowsPlugin::GattCharacteristic_ValueChanged });
  } else {
    gattCharacteristic.ValueChanged(std::exchange(bluetoothDeviceAgent.valueChangedTokens[characteristic], {}));
  }
}

I think this could also happen internal to the agent. The agent contains async methods which have no guarantee that they will not operate on invalid memory after co_await.

PlatformException(Characteristic unavailable, null, null, null)

i got this characteristics
2022-05-03_22-21

then connected and i try read value like this

await QuickBlue.readValue(
        '98:F6:21:D4:DE:F1', // this is the phone's mac address
        '00001801-0000-1000-8000-00805f9b34fb',
        '00002a05-0000-1000-8000-00805f9b34fb',
      );

but i got this error

[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: PlatformException(Characteristic unavailable, null, null, null)
E/flutter ( 8295): #0      StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:607
E/flutter ( 8295): #1      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:177

Device is not able to discover in app but showing in mobile's bluetooth settings

Hi,

I have checked using given example as well as integrating in my app but I am not able to get particular device in scan result
in any android OS (Checked with 7,9,11,12).

But device is showing in mobile's bluetooth settings as available device.

I have also checked using native android development just to make sure and device is showing in scan result.

Please refer to the attached images.

Device name : OS_Horti_PRM_2

1st image is from mobile's bluetooth settings

1

and 2nd is from my app.

2

Any help would be appreciated.

Thanks
Nikhil Sathawara

quick_blue incompatible with connectivity_plus

Hi,

thanks for the plugin. Quick_blue seems to be incompatible with connectivity_plus. Maybe you can update the dependencies?

Because no versions of quick_blue match >0.4.1+1 <0.5.0 and quick_blue 0.4.1+1 depends on quick_blue_linux ^0.1.2, quick_blue ^0.4.1+1 requires quick_blue_linux ^0.1.2.
And because no versions of quick_blue_linux match >0.1.2 <0.2.0, quick_blue ^0.4.1+1 requires quick_blue_linux 0.1.2.
And because quick_blue_linux 0.1.2 depends on bluez ^0.7.9 and no versions of bluez match >0.7.9 <0.8.0, quick_blue ^0.4.1+1 requires bluez 0.7.9.
And because bluez 0.7.9 depends on dbus ^0.6.0 and nm >=0.5.0 depends on dbus ^0.7.0, quick_blue ^0.4.1+1 is incompatible with nm >=0.5.0.
And because connectivity_plus >=2.2.1 depends on connectivity_plus_linux ^1.3.0 which depends on nm ^0.5.0, quick_blue ^0.4.1+1 is incompatible with connectivity_plus >=2.2.1.

on flutter channel 'beta' Android requires permission BLUETOOTH_PRIVILEGED ?

Context: trying to run the example folder, on android 11.

Works fine on flutter chanel 'stable' (2.10.4). Symptoms below appear on channel 'beta'

When I build and run the app, and click "startScan"
OR
When I add bluetooth permissions to AndroidManifest, build and run the app, and click "startScan"

Then the debug log shows a permission error (below). There are some very old comments that the BLUETOOTH_PRIVILEDGED permission is not available for third-party apps. Perhaps there is a workaround for using some of these functions?

D/BluetoothAdapter(13764): isLeEnabled(): BLE_ON
D/BluetoothLeScanner(13764): onScannerRegistered() - status=0 scannerId=10 mScannerId=0
W/Binder (13764): Caught a RuntimeException from the binder stub implementation.
W/Binder (13764): java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission: Neither user 10452 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
W/Binder (13764): at android.os.Parcel.createExceptionOrNull(Parcel.java:2373)
W/Binder (13764): at android.os.Parcel.createException(Parcel.java:2357)
W/Binder (13764): at android.os.Parcel.readException(Parcel.java:2340)
W/Binder (13764): at android.os.Parcel.readException(Parcel.java:2282)
W/Binder (13764): at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:1377)
W/Binder (13764): at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onScannerRegistered(BluetoothLeScanner.java:457)
W/Binder (13764): at android.bluetooth.le.IScannerCallback$Stub.onTransact(IScannerCallback.java:115)
W/Binder (13764): at android.os.Binder.execTransactInternal(Binder.java:1159)
W/Binder (13764): at android.os.Binder.execTransact(Binder.java:1123)

I have tried with and without AndroidManifest permissions:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-feature android:name="android.hardware.bluetooth_le"
        android:required="false" />

Unable to use on Windows

NUGET.EXE not found.
CMake Error at flutter/ephemeral/.plugin_symlinks/quick_blue_windows/windows/CMakeLists.txt:10 (message):
  Please install this executable, and run CMake again.


Exception: Unable to generate build files

[Android] - setNotifiable throw a java.lang.NullPointerException

Hello,

Thank you for this package!
When using on Android, the QuickBlue.setNotifiable function , it throws a java error:

E/MethodChannel#quick_blue/method( 4902): java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothGattDescriptor.setValue(byte[])' on a null object reference
E/MethodChannel#quick_blue/method( 4902): 	at com.example.quick_blue.QuickBluePluginKt.setNotifiable(QuickBluePlugin.kt:296)
E/MethodChannel#quick_blue/method( 4902): 	at com.example.quick_blue.QuickBluePlugin.onMethodCall(QuickBluePlugin.kt:111)
E/MethodChannel#quick_blue/method( 4902): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#quick_blue/method( 4902): 	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296)
E/MethodChannel#quick_blue/method( 4902): 	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:320)
E/MethodChannel#quick_blue/method( 4902): 	at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12)
E/MethodChannel#quick_blue/method( 4902): 	at android.os.Handler.handleCallback(Handler.java:938)
E/MethodChannel#quick_blue/method( 4902): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#quick_blue/method( 4902): 	at android.os.Looper.loop(Looper.java:223)
E/MethodChannel#quick_blue/method( 4902): 	at android.app.ActivityThread.main(ActivityThread.java:7664)
E/MethodChannel#quick_blue/method( 4902): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#quick_blue/method( 4902): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
E/MethodChannel#quick_blue/method( 4902): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

The responsible code is:

  QuickBlue.setConnectionHandler(
        (String deviceId, BlueConnectionState state) {
      if (state == BlueConnectionState.connected) {
        QuickBlue.setValueHandler((deviceId, characteristicId, value) {
          ctrl.sink.add(value);
        });

        //TODO: Waiting for [PR-52](https://github.com/woodemi/quick_blue/pull/52)
        QuickBlue.setServiceHandler(
            (deviceId, serviceId /*, characteristicsId*/) {
          if (serviceId ==
                  TestQuickBlue.SERVICE
                      .toLowerCase() /* &&
          characteristicsId ==
              DeviceBloc.NOTIFY_CHARACTERISTICS.toLowerCase()*/
              ) {
            //CRASH
            QuickBlue.setNotifiable(
                deviceId,
                TestQuickBlue.SERVICE.toLowerCase(),
                TestQuickBlue.NOTIFY_CHARACTERISTICS.toLowerCase(),
                BleInputProperty.notification);
          }
        });
        QuickBlue.discoverServices(deviceId);
      }
    });
    QuickBlue.connect(deviceId);

Do you have an idea of the problem?
Best

Different Bluetooth address format per platform

Hi! I noticed Bluetooth address is a int64 (as String) on Windows, which I seem to be able to parse correctly:

import 'package:convert/convert.dart';
[...]
ByteData btAddressData = ByteData(8)..setUint64(0, int.parse(device.deviceId));
String formatted = hex.encode(btAddressData.buffer.asUint8List(2, 6));

But on Android it is already formatted as a string (like AA:BB:CC:11:22:33). Would you accept a PR to equalize this difference? If so, what would be preferred? Perhaps it could be even better to have the Bluetooth address as Uint8List in the model.

Side note: I have not yet tested this on iOS/iPadOS/macOS as I currently don't have these devices available.

get null UUID error when i call QuickBlue.setNotifiable

(18865): Service 00001801-0000-1000-8000-00805f9b34fb
I/flutter (18865): _handleServiceDiscovery E6:6A:A1:A5:1F:D6, 00001800-0000-1000-8000-00805f9b34fb
I/flutter (18865): _handleServiceDiscovery E6:6A:A1:A5:1F:D6, 00001801-0000-1000-8000-00805f9b34fb
E/MethodChannel#quick_blue/method(18865): Failed to handle method call
E/MethodChannel#quick_blue/method(18865): java.lang.NullPointerException: Attempt to invoke virtual method 'android.bluetooth.BluetoothGattDescriptor android.bluetooth.BluetoothGattCharacteristic.getDescriptor(java.util.UUID)' on a null object reference
E/MethodChannel#quick_blue/method(18865): at com.example.quick_blue.QuickBluePluginKt.setNotifiable(QuickBluePlugin.kt:290)
E/MethodChannel#quick_blue/method(18865): at com.example.quick_blue.QuickBluePlugin.onMethodCall(QuickBluePlugin.kt:111)
E/MethodChannel#quick_blue/method(18865): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#quick_blue/method(18865): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296)
E/MethodChannel#quick_blue/method(18865): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:320)
E/MethodChannel#quick_blue/method(18865): at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12)
E/MethodChannel#quick_blue/method(18865): at android.os.Handler.handleCallback(Handler.java:938)
E/MethodChannel#quick_blue/method(18865): at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#quick_blue/method(18865): at android.os.Looper.loop(Looper.java:233)
E/MethodChannel#quick_blue/method(18865): at android.app.ActivityThread.main(ActivityThread.java:8010)
E/MethodChannel#quick_blue/method(18865): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#quick_blue/method(18865): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
E/MethodChannel#quick_blue/method(18865): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
E/flutter (18865): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: PlatformException(error, Attempt to invoke virtual method 'android.bluetooth.BluetoothGattDescriptor android.bluetooth.BluetoothGattCharacteristic.getDescriptor(java.util.UUID)' on a null object reference, null, java.lang.NullPointerException: Attempt to invoke virtual method 'android.bluetooth.BluetoothGattDescriptor android.bluetooth.BluetoothGattCharacteristic.getDescriptor(java.util.UUID)' on a null object reference
E/flutter (18865): at com.example.quick_blue.QuickBluePluginKt.setNotifiable(QuickBluePlugin.kt:290)
E/flutter (18865): at com.example.quick_blue.QuickBluePlugin.onMethodCall(QuickBluePlugin.kt:111)
E/flutter (18865): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/flutter (18865): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296)
E/flutter (18865): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:320)
E/flutter (18865): at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12)
E/flutter (18865): at android.os.Handler.handleCallback(Handler.java:938)
E/flutter (18865): at android.os.Handler.dispatchMessage(Handler.java:99)
E/flutter (18865): at android.os.Looper.loop(Looper.java:233)
E/flutter (18865): at android.app.ActivityThread.main(ActivityThread.java:8010)
E/flutter (18865): at java.lang.reflect.Method.invoke(Native Method)
E/flutter (18865): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
E/flutter (18865): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
E/flutter (18865): )
E/flutter (18865): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
E/flutter (18865): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:177:18)

Many Issues compiling example project

Hello!

When compiling the example project for windows (or just adding the quick_blue: ^0.4.1+1 depedency) will give the error code:

Building Windows application... NUGET.EXE not found. CMake Error at flutter/ephemeral/.plugin_symlinks/quick_blue_windows/windows/CMakeLists.txt:10 (message): Please install this executable, and run CMake again.

Then if I add nuget.exe to the root project directory, it gives the following build error:

D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: The command "setlocal [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: D:\vs\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe -DBUILD_TYPE=Debug -P cmake_install.cmake [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: :cmEnd [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: :cmErrorLevel [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: exit /b %1 [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: :cmDone [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] D:\vs\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: :VCEnd" exited with code 1. [D:\code\quick_blue-master\quick_blue_example\build\windows\INSTALL.vcxproj] Exception: Build process failed.

Anything I still need to install or do? I can't compile your example project or even the package in any way, and help would be appreciated!

Exception: Unable to generate build files

I am getting this error when I run the app
NUGET.EXE not found. CMake Error at flutter/ephemeral/.plugin_symlinks/quick_blue_windows/windows/CMakeLists.txt:10 (message): Please install this executable, and run CMake again.

Check if device is already connected 📲

Hi,

Thank you very much for your effort. Is there a way to see all connected devices? If a device is already connected, It won't be shown in the scanResultStream Stream.

Thanks in advance!

Steps to execute an example for windows

May I please if there are any particular sequence of steps that I need to execute to run this code in windows 10?
At the moment, I am using vs code and have opened
main.dart and tried compiling. I get the following error!
FileSystemException: Cannot create link, path = 'E:\appdev\expts\windows\quick_blue\quick_blue_example\windows\flutter\ephemeral.plugin_symlinks\quick_blue_windows' (OS Error: Incorrect function.
, errno = 1)

Thank you for the time

Default loglevel is very noisey.

Can we please have a method to set the loglevel of the used by internal logging? ALL and INFO is making it very hard to do BLE development when there are many devices in the workshop.

Version problems

I get this among other similar errors when trying to use your package.
Any plans to update ?

Because test <1.3.0 requires SDK version >=1.8.0 <2.0.0-∞ and test >=1.16.0-nullsafety <1.16.0-nullsafety.8 requires SDK version >=2.10.0-0 <2.12.0, test <1.3.0-∞ or >=1.16.0-nullsafety <1.16.0-nullsafety.8 is forbidden.
And because test >=1.16.0-nullsafety.8 <1.16.0-nullsafety.18 depends on typed_data >=1.3.0-nullsafety <1.3.0 and test >=1.16.0-nullsafety.18 <1.16.0-nullsafety.19 depends on test_api 0.2.19-nullsafety.7, test <1.3.0-∞ or >=1.16.0-nullsafety <1.16.0-nullsafety.19 requires typed_data >=1.3.0-nullsafety <1.3.0 or test_api 0.2.19-nullsafety.7.
And because test >=1.3.0 <1.12.0 depends on boolean_selector ^1.0.0 and test >=1.12.0 <1.13.0 depends on test_api 0.2.14, test <1.13.0-∞ or >=1.16.0-nullsafety <1.16.0-nullsafety.19 requires typed_data >=1.3.0-nullsafety <1.3.0 or test_api 0.2.14 or 0.2.19-nullsafety.7 or boolean_selector ^1.0.0.
And because test >=1.13.0 <1.14.5 depends on test_api 0.2.15 and test >=1.14.5 <1.15.0 depends on test_api 0.2.16, test <1.15.0-∞ or >=1.16.0-nullsafety <1.16.0-nullsafety.19 requires typed_data >=1.3.0-nullsafety <1.3.0 or test_api 0.2.14 or 0.2.15 or 0.2.16 or 0.2.19-nullsafety.7 or boolean_selector ^1.0.0.
And because test >=1.15.0 <1.15.3 depends on test_api 0.2.17 and test >=1.15.3 <1.15.5 depends on test_api 0.2.18, test <1.15.5-∞ or >=1.16.0-nullsafety <1.16.0-nullsafety.19 requires typed_data >=1.3.0-nullsafety <1.3.0 or test_api 0.2.14 or 0.2.15 or 0.2.16 or 0.2.17 or 0.2.18 or 0.2.19-nullsafety.7 or boolean_selector ^1.0.0.
And because test >=1.15.5 <1.16.0-nullsafety depends on test_api 0.2.18+1 and test >=1.16.0-nullsafety.19 <1.16.6 depends on test_api 0.2.19, test <1.16.6 requires test_api 0.2.14 or 0.2.15 or 0.2.16 or 0.2.17 or 0.2.18 or 0.2.18+1 or 0.2.19-nullsafety.7 or 0.2.19 or typed_data >=1.3.0-nullsafety <1.3.0 or boolean_selector ^1.0.0.
And because every version of flutter_test from sdk depends on both boolean_selector 2.1.0 and test_api 0.4.3, if flutter_test from sdk and test <1.16.6 then typed_data >=1.3.0-nullsafety <1.3.0.
And because every version of flutter from sdk depends on typed_data 1.3.0 and test >=1.16.6 depends on shelf_static ^1.0.0, if flutter_test from sdk and flutter from sdk and test any then shelf_static ^1.0.0.
And because shelf_static >=1.0.0 depends on convert ^3.0.0 and quick_blue >=0.2.0 depends on convert ^2.1.1, one of flutter_test from sdk or flutter from sdk or test any or quick_blue >=0.2.0 must be false.
And because psmc depends on both flutter from sdk and quick_blue ^0.2.0, flutter_test from sdk is incompatible with test.
So, because psmc depends on both test any and flutter_test from sdk, version solving failed.

LateInitializationError: Field '_instance@xxxxxxxx' has not been initialized.

Hi,

I have a class which performs some QuickBlue operations, (e.g. QuickBlue.scanResultStream.listen(), QuickBlue.setConnectionHandler() etc.), however when these commands are reached, I get a LateInitializationError on _instance :

LateInitializationError: Field '_instance@35118451' has not been initialized.

When the exception was thrown, this was the stack:
#0      QuickBluePlatform._instance (package:quick_blue_platform_interface/quick_blue_platform_interface.dart)
#1      QuickBluePlatform.instance (package:quick_blue_platform_interface/quick_blue_platform_interface.dart:29:44)
#2      QuickBlue.scanResultStream (package:quick_blue/quick_blue.dart:20:30)

If I put the same code in a StatefulWidget rather than a class, there is no error. Does QuickBlue have to operate inside a stateful widget or is this an error?

help with plugin documenation

Can you please tell me where did you find the documentation for windows plugins?
This is not an issue only a request for help

Messages (platform) should be checked for null

Version: quick_blue: ^0.5.0-dev.0

D/BluetoothGatt(24906): onConnectionUpdated() - Device=08:BE:AC:27:1A:38 interval=6 latency=0 timeout=500 status=0
D/BluetoothGatt(24906): onSearchComplete() = Device=08:BE:AC:27:1A:38 Status=0
V/QuickBluePlugin(24906): onServicesDiscovered 08:BE:AC:27:1A:38 0
V/QuickBluePlugin(24906): Service 00000000-4fc7-4d40-8e54-3956e5e4ffb9
V/QuickBluePlugin(24906):     Characteristic 0000afb1-4fc7-4d40-8e54-3956e5e4ffb9
V/QuickBluePlugin(24906):         Descriptor 00002902-0000-1000-8000-00805f9b34fb

======== Exception caught by services library ======================================================
The following _TypeError was thrown during a platform message callback:
type 'Null' is not a subtype of type 'List<dynamic>'

When the exception was thrown, this was the stack: 
#0      MethodChannelQuickBlue._handleConnectorMessage (package:quick_blue_platform_interface/method_channel_quick_blue.dart:82:23)

Basic code for the service handler is:

  QuickBlue.setServiceHandler((String deviceId, String serviceId) {
    if (serviceId != BLE_SERVICE_UUID) {
      logger.error('Machine does not have BLE service: $deviceId, $serviceId');
      _peripherals.removeWhere((key, value) => value.deviceId == deviceId);
    } else if (serviceId == BLE_SERVICE_UUID) {
      for (var k in _peripherals.entries ) {
        if (k.value.deviceId == deviceId) {
          _bleConnectionEvents.add(EventMachineFound(k.key, null, true));
          return;
        }
      }
    }
    logger.info('_handleServiceDiscovery $deviceId, $serviceId');
  });

On Writing command getting crash

Hello,

I am getting error on writing command , please help how can I write a command like change name

void updateFriendlyName() async{
var valuesKey = utf8.encode("F") ;
var values = utf8.encode(friendlyNameTextController.value.text) ;

await QuickBlue.writeValue(connectedDeviceId, "e5f50000-c0ec-46ba-bd1f-b4c9f0da4208", "e5f50001-c0ec-46ba-bd1f-b4c9f0da4208",
    Uint8List.fromList(valuesKey + values), BleOutputProperty.withResponse);

}

Application Specific Information:
quick_blue_macos/QuickBlueMacosPlugin.swift:32: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Thanks

[Windows] Getting a wrong service or characteristic causes the library to crash.

Is I try to get a non-existent service or characteristic then the library crashes on the Windows side. The problem lies in those 2 functions. Basically it never inserts a service or characteristic in the corresponding array and it tries to return null.

IAsyncOperation<GattDeviceService> GetServiceAsync(std::string service) {
    if (gattServices.count(service) == 0) {
      auto serviceResult = co_await device.GetGattServicesAsync();
      if (serviceResult.Status() != GattCommunicationStatus::Success)
        co_return nullptr;

      for (auto s : serviceResult.Services())
        if (to_uuidstr(s.Uuid()) == service)
          gattServices.insert(std::make_pair(service, s));
    }
    co_return gattServices.at(service);
  }
  IAsyncOperation<GattCharacteristic> GetCharacteristicAsync(std::string service, std::string characteristic) {
    if (gattCharacteristics.count(characteristic) == 0) {
      auto gattService = co_await GetServiceAsync(service);

      auto characteristicResult = co_await gattService.GetCharacteristicsAsync();
      if (characteristicResult.Status() != GattCommunicationStatus::Success)
        co_return nullptr;

      for (auto c : characteristicResult.Characteristics())
        if (to_uuidstr(c.Uuid()) == characteristic)
          gattCharacteristics.insert(std::make_pair(characteristic, c));
    }
    co_return gattCharacteristics.at(characteristic);
  }

run time error in windows

Hello Guys,

I am getting following issue onwindows when trying to run app.

NUGET.EXE not found.
CMake Error at flutter/ephemeral/.plugin_symlinks/quick_blue_windows/windows/CMakeLists.txt:10 (message):
Please install this executable, and run CMake again.

Exception: Unable to generate build files

please help me

Why request location?

Why does the package (like other packages) wanna use location, i don't wanna any location action, never, i just use bluetooth actions?

Exception when writing value on Windows

I am facing an exception and crash each time I try to do writeValue() to my device when running under Windows. Under Mac the same code works fine. The example app also crashes when I try to do writeValue().
The Flutter console does not print anything useful upon crashing. Running the .sln in Visual Studio gives me this:

Unhandled exception at 0x00007FF8BF42B382 (KernelBase.dll) in bt_remote.exe: 0xC000027B: An application-internal exception has occurred (parameters: 0x0000014B29305C30, 0x0000000000000002).

Screenshot 2022-03-05 214014

I replicated the behavior on two different computers (Surface Pro + PC with BT Dongle). Any idea what the problem might be?

I am on the latest master and latest Flutter.

[√] Flutter (Channel stable, 2.10.3, on Microsoft Windows [Version 10.0.19044.1526], locale en-DE)
[X] Android toolchain - develop for Android devices
    X Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/windows#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.11.9)
[!] Android Studio (not installed)
[√] VS Code (version 1.65.0)
[√] Connected device (3 available)
[√] HTTP Host Availability

! Doctor found issues in 2 categories.

WinRT method throws RaiseFailFastException

Sometimes, quick_blue will throw an error in the WinRT code. This causes the app to crash to desktop.

I've managed to get logging working with my app, so I've got a really good stacktrace of the error here: https://sentry.io/share/issue/07424e3a35e147db9ec78707d2e54678/

Unfortunately, I lack the C++ knowledge to work out why this is happening, but I thought maybe @Sunbreak or @kinyoklion would be able to use this stacktrace to possibly debug and fix the issue, and make quick_blue more stable for all 😊

[Windows] Crash on writeValue

Hi! This code gives me sigterm on Windows:

void handleConnection(String deviceId, BlueConnectionState state) {
    d.log('handleConnection ' + state.value);
    QuickBlue.discoverServices(deviceId);
    QuickBlue.setNotifiable(deviceId, SERVICE_MIBAND2, CHARACTERISTIC_AUTH,
        BleInputProperty.notification);
    QuickBlue.writeValue(deviceId, SERVICE_MIBAND2, CHARACTERISTIC_AUTH,
        Uint8List.fromList(key_cmd + key), BleOutputProperty.withResponse);
  }

  void handleService(String deviceId, String serviceId) {
    d.log('handleService ' + serviceId);
  }

  void handleValue(String deviceId, String characteristicId, Uint8List value) {
    d.log('handleValue ' + characteristicId);
  }

  @override
  void initState() {
    super.initState();
    QuickBlue.setConnectionHandler(handleConnection);
    QuickBlue.setServiceHandler(handleService);
    QuickBlue.setValueHandler(handleValue);

    QuickBlue.scanResultStream.listen((result) {
      d.log('onScanResult ' + result.name);

      if (result.name == "Mi Band 3" && !bandFound) {
        bandFound = true;

        d.log('onScanResult ' + result.name);
        QuickBlue.stopScan();
        QuickBlue.connect(result.deviceId);
      }
    });

    QuickBlue.startScan();
  }

The output:

Launching lib\main.dart on Windows in debug mode...
lib\main.dart:1
Connecting to VM Service at w[s://127.0.0.1:56503]()/sOU5DQmnXDg=/ws
flutter: startScan invokeMethod success
4[log] onScanResult [Monitor] Samsung M7 (32)
[log] onScanResult Amazfit GTS2 mini
[log] onScanResult [Monitor] Samsung M7 (32)
flutter: stopScan invokeMethod success
2[log] onScanResult Mi Band 3
[log] handleConnection connected
Lost connection to device.
Exited (sigterm)

How I can debug it?
I'm new to BLE maybe I do something wrong. I'm trying to port this project:
https://github.com/4lhc/MiBand_HRX/blob/master/base.py#L103

Is setNotifiable with BleInputProperty.notification the same as writing 0x01 to 0x2902 descriptor?

There's no crash if I set BleOutputProperty.withoutResponse for writeValue but no response from device too.

LateInitializationError

Hello,
I try to use the package but from the first line, for example :

final b=await QuickBlue.isBluetoothAvailable();

the error occurs:

E/flutter (28161): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: LateInitializationError: Field '_instance@1480118451' has not been initialized.
E/flutter (28161): #0      QuickBluePlatform._instance (package:quick_blue_platform_interface/quick_blue_platform_interface.dart)
E/flutter (28161): #1      QuickBluePlatform.instance (package:quick_blue_platform_interface/quick_blue_platform_interface.dart:29:44)
E/flutter (28161): #2      QuickBlue.isBluetoothAvailable (package:quick_blue/quick_blue.dart:13:67)
E/flutter (28161): #3      BleController.scan (package:clickygo/pages/test.dart:331:29)
etc

It looks like in QuickBluePlatform, _instance is not initialized :

  static late QuickBluePlatform _instance;
  static QuickBluePlatform get instance => _instance;

Any idea ?
Thanks

Failed to send request:

I ran into this problem after the first successful run for the "quick_blue_example" on windows
Failed to send request: {"jsonrpc":"2.0","id":"25","method":"ext.flutter.inspector.getSelectedSummaryWidget","params":{"objectGroup":"selection_5","isolateId":"isolates/751635408800707"}}

I couldn't also connect and send data to any device

[MacOs, iOS] deviceId is missing on notification callback

Using setNotifiable the code not work as expected.
In the log console appears this on every charateristic notification:

peripheral:didUpdateValueForForCharacteristic 2A6E {length = 2, bytes = 0x7d08} error: nil
flutter: _handleConnectorMessage {characteristicValue: {characteristic: 2a6e, value: [122, 8]}}

════════ Exception caught by services library ══════════════════════════════════
The following _TypeError was thrown during a platform message callback:
type 'Null' is not a subtype of type 'String'

And the handler setted in setValueHandler() it's never get called.
The exception is caused by line 75 of method_channel_quick_blue.dart file
The deviceId is required, but not received

OutputDebugString display

How do I see these messages printed using "OutputDebugString".
I see that when I run a standalone visual stuido project, the console displays them. But in flutter project, is there a way to enable these prints? Thank you

Support advanced methods for linux

Related to #29
Currently the linux implementation only supports isBluetoothAvailable and startScan/stopScan.
It would be useful if linux supports all other methods that windows, android and ios supports.

serviceHandler never triggered on windows?

Hi,
First thank you for providing this BLE package which will be very usefull :).
Nevertheless, Is there a complete implementation of the serviceHandler under windows?
When using it as described in the example, it seems not to be triggered. (see code below). May I did something wrong?

class CustomClient extends GenericClient(){
    CustomClient (){
        QuickBlue.setConnectionHandler(_handleConnectionChange);
        QuickBlue.setServiceHandler(_handleServiceDiscovery);
        QuickBlue.setValueHandler(_handleValueChange);
    }
    
     _handleConnectionChange(String deviceId, BlueConnectionState state){ //works well
        if(state == BlueConnectionState.connected){
            QuickBlue.discoverServices(deviceId);
        }
    }

    void _handleServiceDiscovery(String deviceId, String serviceId) { //never triggered
        print('_handleServiceDiscovery $deviceId, $serviceId');
    }

    void _handleValueChange(String deviceId, String characteristicId, Uint8List value) { //works well
        print('_handleValueChange $deviceId, $characteristicId, ${value.toList()}');
    }

}

Regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.