예제 #1
0
            private async void ConnectButton_Click()
            {
                ConnectButton.IsEnabled = false;

                if (!await ClearBluetoothLEDeviceAsync())
                {
                    rootPage.NotifyUser("Error: Unable to reset state, try again.", NotifyType.ErrorMessage);
                    ConnectButton.IsEnabled = true;
                    return;
                }

                try
                {
                    // BT_Code: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent.
                    bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(rootPage.SelectedBleDeviceId);

                    if (bluetoothLeDevice == null)
                    {
                        rootPage.NotifyUser("Failed to connect to device.", NotifyType.ErrorMessage);
                    }
                }
                catch (Exception ex) when(ex.HResult == E_DEVICE_NOT_AVAILABLE)
                {
                    rootPage.NotifyUser("Bluetooth radio is not on.", NotifyType.ErrorMessage);
                }

                if (bluetoothLeDevice != null)
                {
                    // Note: BluetoothLEDevice.GattServices property will return an empty list for unpaired devices. For all uses we recommend using the GetGattServicesAsync method.
                    // BT_Code: GetGattServicesAsync returns a list of all the supported services of the device (even if it's not paired to the system).
                    // If the services supported by the device are expected to change during BT usage, subscribe to the GattServicesChanged event.
                    GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached);

                    if (result.Status == GattCommunicationStatus.Success)
                    {
                        var services = result.Services;
                        rootPage.NotifyUser(String.Format("Found {0} services", services.Count), NotifyType.StatusMessage);
                        foreach (var service in services)
                        {
                            ServiceList.Items.Add(new ComboBoxItem {
                                Content = DisplayHelpers.GetServiceName(service), Tag = service
                            });
                        }
                        ConnectButton.Visibility = Visibility.Collapsed;
                        ServiceList.Visibility   = Visibility.Visible;
                    }
                    else
                    {
                        rootPage.NotifyUser("Device unreachable", NotifyType.ErrorMessage);
                    }
                }
                ConnectButton.IsEnabled = true;
            }
        public async void Connect(string id)
        {
            try
            {
                // BT_Code: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent.
                bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(id);

                if (bluetoothLeDevice == null)
                {
                    Log.d("Failed to connect to device.", NotifyType.ErrorMessage);
                    return;
                }

                bluetoothLeDevice.ConnectionStatusChanged += ConnectionStatusChangedHandler;

                mBluetoothGatt = await GattSession.FromDeviceIdAsync(bluetoothLeDevice.BluetoothDeviceId);

                mBluetoothGatt.MaintainConnection = true;
            }
            catch (Exception ex) when(ex.HResult == E_DEVICE_NOT_AVAILABLE)
            {
                Log.d("Bluetooth radio is not on.", NotifyType.ErrorMessage);
                return;
            }

            if (bluetoothLeDevice != null)
            {
                // Note: BluetoothLEDevice.GattServices property will return an empty list for unpaired devices. For all uses we recommend using the GetGattServicesAsync method.
                // BT_Code: GetGattServicesAsync returns a list of all the supported services of the device (even if it's not paired to the system).
                // If the services supported by the device are expected to change during BT usage, subscribe to the GattServicesChanged event.
                GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesForUuidAsync(RX_SERVICE_UUID);

                if (result.Status == GattCommunicationStatus.Success)
                {
                    _services.Clear();
                    _services.AddRange(result.Services);

                    Log.d(String.Format("Found {0} services", _services.Count), NotifyType.StatusMessage);
                    foreach (var service in _services)
                    {
                        Log.d("SERVICE: " + DisplayHelpers.GetServiceName(service));
                        GetCharachteristics(service);
                    }
                }
                else
                {
                    Log.d("Device unreachable", NotifyType.ErrorMessage);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// It looks for the compatible devices (discovery + analysis). Then, it asks
        /// for the user to choose the device. The selected device is returned
        /// through a CompatibleEndPoint object. It contains the id, service and
        /// characteristic name.
        /// </summary>
        /// <returns>The complete device id (or CompatibleEndPoint with all fields set as null if none were selected)</returns>
        static async Task <CompatibleEndPoint> AutomaticScan()
        {
            BleUtility.Discovery bleDiscovery = new BleUtility.Discovery();
            bleDiscovery.Start();

            LogHelper.Overwrite(true);
            LogHelper.NewLine(false);

            while (!bleDiscovery.HasEnded())
            {
                Thread.Sleep(50);
            }
            LogHelper.Overwrite(false);
            LogHelper.NewLine(true);
            LogHelper.Log("");

            LogHelper.Ok("Devices:");
            LogHelper.IncrementIndentLevel();
            List <DeviceInformation> devices = bleDiscovery.GetDevices();

            foreach (DeviceInformation device in devices)
            {
                LogHelper.Ok(device.Id + " " + device.Name);
            }
            LogHelper.DecrementIndentLevel();

            List <CompatibleEndPoint> compatibleEndPoints = new List <CompatibleEndPoint>();

            LogHelper.Pending("Checking compatibility of each device");
            LogHelper.IncrementIndentLevel();
            foreach (DeviceInformation device in devices)
            {
                LogHelper.Pending("Checking compatibility of device " + device.Id.Split("-").Last());
                LogHelper.IncrementIndentLevel();

                LogHelper.Pending("Connecting to device...");
                BluetoothLEDevice connection = await BleUtility.Connect(device.Id);

                if (connection == null)
                {
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Warn("Failed to connect (doesn't mean that it's incompatible)");
                    continue;
                }
                LogHelper.Ok("Connected");

                LogHelper.Pending("Looking for services...");
                IReadOnlyList <GattDeviceService> services = await BleUtility.GetServices(connection);

                if (services == null)
                {
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Warn("Gatt communication failed");
                    continue;
                }
                else if (services.Count == 0)
                {
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Warn("No services found");
                    continue;
                }
                LogHelper.Ok(services.Count + " service(s) found");

                LogHelper.Pending("Looking for characteristics for each service...");
                LogHelper.IncrementIndentLevel();
                foreach (GattDeviceService service in services)
                {
                    LogHelper.Pending("Looking for characteristics of service " + DisplayHelpers.GetServiceName(service));
                    LogHelper.IncrementIndentLevel();

                    IReadOnlyList <GattCharacteristic> characteristics = await BleUtility.GetCharacteristics(service);

                    if (characteristics == null)
                    {
                        LogHelper.DecrementIndentLevel();
                        LogHelper.Warn("Failed to retrieve characteristics");
                        service.Dispose();
                        continue;
                    }
                    else if (characteristics.Count == 0)
                    {
                        LogHelper.DecrementIndentLevel();
                        LogHelper.Warn("No characteristics found");
                        service.Dispose();
                        continue;
                    }
                    LogHelper.Ok(characteristics.Count + " characteristic(s) found");

                    LogHelper.Pending("Checking compatibility of each characteristic...");
                    LogHelper.IncrementIndentLevel();
                    int compatibleCpt = 0;
                    foreach (GattCharacteristic characteristic in characteristics)
                    {
                        LogHelper.Pending("Checking characteristic " + DisplayHelpers.GetCharacteristicName(characteristic) + "...");

                        if (BleUtility.IsWriteableCharateristic(characteristic))
                        {
                            CompatibleEndPoint endPoint = new CompatibleEndPoint(
                                device.Id,
                                device.Name,
                                DisplayHelpers.GetServiceName(service),
                                DisplayHelpers.GetCharacteristicName(characteristic)
                                );

                            compatibleCpt++;
                            compatibleEndPoints.Add(endPoint);
                            LogHelper.Ok("Compatible!");
                        }
                        else
                        {
                            LogHelper.Warn("Not compatible");
                        }
                    }

                    service.Dispose();
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Ok(compatibleCpt + " compatible endpoint(s) found");
                    LogHelper.DecrementIndentLevel();
                }
                LogHelper.Ok("Finished looking for characteristics");
                LogHelper.DecrementIndentLevel();

                LogHelper.Ok("Finished compatibility check of device " + device.Id.Split('-').Last());
                LogHelper.DecrementIndentLevel();
            }
            LogHelper.DecrementIndentLevel();
            LogHelper.Ok("Finished analyzing devices");

            if (compatibleEndPoints.Count == 0)
            {
                LogHelper.Error("No compatible device found");
                LogHelper.Error("Make sure that you're not already connected to it");
                return(new CompatibleEndPoint(null, null, null, null));
            }
            else
            {
                LogHelper.Ok("Compatible device(s):");
                LogHelper.IncrementIndentLevel();
                string[] ids = new string[compatibleEndPoints.Count];
                for (int i = 0; i < compatibleEndPoints.Count; i++)
                {
                    CompatibleEndPoint compatibleEndPoint = compatibleEndPoints.ElementAt(i);
                    LogHelper.Ok("name = '" + compatibleEndPoint.deviceName + "' id = '" + compatibleEndPoint.deviceId + "'");
                    ids[i] = compatibleEndPoint.deviceId + (compatibleEndPoint.deviceName != "" ? (" " + compatibleEndPoint.deviceName) : "");
                }
                LogHelper.DecrementIndentLevel();

                int choice = LogHelper.AskUserToChoose("Choose the device to use: ", ids);
                bleDiscovery.Dispose();
                return(compatibleEndPoints.ElementAt(choice));
            }
        }
예제 #4
0
        /// <summary>
        /// The actual program, needs to be waited
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static async Task Run(string[] args)
        {
            LogHelper.PrintHeader();

            LogHelper.PrintTitle("Configuration");
            bool configSucceed = await Configure(args);

            if (!configSucceed)
            {
                LogHelper.Error("Something went wrong during configuration");
            }
            else
            {
                #region connection

                LogHelper.PrintTitle("Connection");
                LogHelper.Pending("Looking for BLE device of id " + Configuration.device.deviceId);
                device = await BleUtility.Connect(Configuration.device.deviceId);

                if (device == null)
                {
                    LogHelper.Error("Failed to connect to device");
                }

                #endregion

                #region services

                GattDeviceService targettedService = null;
                if (device != null)
                {
                    LogHelper.PrintTitle("Services");
                    LogHelper.Pending("Looking for service " + Configuration.device.deviceServiceName + "...");

                    IReadOnlyList <GattDeviceService> services = await BleUtility.GetServices(device);

                    if (services != null)
                    {
                        LogHelper.Ok(String.Format("Found {0} service(s)", services.Count));
                        foreach (var service in services)
                        {
                            if (DisplayHelpers.GetServiceName(service) == Configuration.device.deviceServiceName)
                            {
                                LogHelper.Ok("Found service " + Configuration.device.deviceServiceName);
                                targettedService = service;
                                break;
                            }
                        }

                        if (targettedService == null)
                        {
                            LogHelper.Error("Couldn't find service " + Configuration.device.deviceServiceName);
                        }
                    }
                    else
                    {
                        LogHelper.Error("Device unreachable");
                    }
                }

                #endregion

                #region caracteristics

                GattCharacteristic characteristic = null;
                if (targettedService != null)
                {
                    LogHelper.PrintTitle("Caracteristics");
                    LogHelper.Pending("Looking for characteristic " + Configuration.device.deviceCharacteristicName + "...");
                    IReadOnlyList <GattCharacteristic> characteristics = await BleUtility.GetCharacteristics(targettedService);

                    if (characteristics == null)
                    {
                        LogHelper.Error("Could not find characteristics of " + Configuration.device.deviceName);
                    }
                    else
                    {
                        foreach (var charact in characteristics)
                        {
                            if (DisplayHelpers.GetCharacteristicName(charact) == Configuration.device.deviceCharacteristicName)
                            {
                                LogHelper.Ok("Found characteristic");
                                characteristic = charact;
                            }
                        }

                        if (characteristic == null)
                        {
                            LogHelper.Error("Could not find characteristic " + Configuration.device.deviceCharacteristicName);
                        }
                    }
                }

                #endregion

                #region show config

                LogHelper.PrintTitle("Save your config");
                LogHelper.Ok("Using configuration:");
                LogHelper.Log(Configuration.GetArgumentDetails());
                LogHelper.Log("\"" + Configuration.ToArgument() + "\"");
                LogHelper.Ok("Copy the line below, and run the program with this argument to [...]");
                LogHelper.Ok("[...] start the program automatically with the current configuration");

                #endregion

                #region communication

                if (characteristic != null)
                {
                    LogHelper.PrintTitle("Communication");

                    if (BleUtility.IsWriteableCharateristic(characteristic))
                    {
                        Loop(characteristic);
                    }
                    else
                    {
                        LogHelper.Error("This characteristic does not have either the 'Write' or 'WriteWithoutResponse' properties");
                    }
                }

                #endregion
            }

            #region cleanup

            LogHelper.PrintTitle("Cleanup");
            LogHelper.Pending("Exiting properly");
            device?.Dispose();
            LogHelper.Ok("Done. Type a key to exit");
            Console.ReadKey(true);

            #endregion
        }