예제 #1
0
 public async void TryStopCharacteristicNotifications()
 {
     if (characteristic != null)
     {
         await characteristic.StopUpdatesAsync();
     }
 }
        async Task ClearConnection()
        {
            _readerState = READERSTATE.READYFORDISCONNECT;
            // Stop Timer;
            await _characteristicUpdate.StopUpdatesAsync();

            _characteristicUpdate.ValueUpdated -= BLE_Recv;
            _adapter.DeviceConnectionLost      -= OnDeviceConnectionLost;

            _characteristicUpdate = null;
            _characteristicWrite  = null;
            _service = null;

            try
            {
                if (_device.State == DeviceState.Connected)
                {
                    await _adapter.DisconnectDeviceAsync(_device);
                }
            }
            catch (Exception ex)
            {
            }
            _device = null;

            _readerState = READERSTATE.DISCONNECT;
        }
예제 #3
0
 async protected override void OnDisappearing()
 {
     base.OnDisappearing();
     if (useNotify && (BleDevice.State == DeviceState.Connected))
     {
         await charLevel.StopUpdatesAsync();
     }
 }
예제 #4
0
 public async Task DisableNotification(ICharacteristic characteristic)
 {
     if (characteristic.CanUpdate)
     {
         characteristic.ValueUpdated -= OnValueAvailable;
         await characteristic.StopUpdatesAsync();
     }
 }
예제 #5
0
 async protected override void OnDisappearing()
 {
     base.OnDisappearing();
     if (BleDevice.State == DeviceState.Connected)
     {
         await charIQ.StopUpdatesAsync();
     }
 }
예제 #6
0
        View MakeReadView(ICharacteristic c)
        {
            var stack   = new StackLayout();
            var bar     = new StackLayout();
            var DataLog = new Editor
            {
                FontFamily        = Utils.GetMonoFamily(),
                VerticalOptions   = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.Fill,
                HeightRequest     = 200,
            };

            bar.Orientation = StackOrientation.Horizontal;
            bar.Padding     = 10;
            if (c.CanRead)
            {
                var b = new Button();
                b.Text     = "Read";
                b.Clicked += async(object sender, EventArgs e) =>
                {
                    var v = await c.ReadAsync();

                    ShowValue(DataLog, v);
                };
                bar.Children.Add(b);
            }
            c.ValueUpdated += (object sender, Plugin.BLE.Abstractions.EventArgs.CharacteristicUpdatedEventArgs e) =>
            {
                ShowValue(DataLog, e.Characteristic.Value);
            };

            if (c.CanUpdate)
            {
                var b = new Button();
                b.Text = "Subscribe";

                b.Clicked += async(object sender, EventArgs e) =>
                {
                    if (b.Text == "Subscribe")
                    {
                        await c.StartUpdatesAsync();

                        b.Text = "Unsubscribe";
                    }
                    else
                    {
                        await c.StopUpdatesAsync();

                        b.Text = "Subscribe";
                    }
                };
                bar.Children.Add(b);
            }
            stack.Children.Add(DataLog);
            stack.Children.Add(bar);
            return(stack);
        }
예제 #7
0
 async private void BtnS2MStop_Clicked(object sender, EventArgs e)
 {
     S2MRunning = false;
     if (charOutput != null)
     {
         try { await charOutput.StopUpdatesAsync(); } catch (Exception) { }
         CurS2MTpt.Text = "Stopped";
     }
 }
예제 #8
0
 async Task RUN_BLE_STOP_UPDATES(ICharacteristic c)
 {
     try
     {
         await c.StopUpdatesAsync();
     }
     catch (Exception ex)
     {
         Debug.WriteLine($"Characteristic {c.Uuid} stop updates failed with exception: {ex.Message}");
     }
 }
예제 #9
0
        public async Task Stop()
        {
            if (characteristic == null)
            {
                return;
            }

            try {
                await characteristic.StopUpdatesAsync();
            } catch (Exception) {
            }
        }
        private async void characteristicValueChange(Plugin.BLE.Abstractions.EventArgs.CharacteristicUpdatedEventArgs args, ICharacteristic characteristic1, IDevice device)
        {
            string x = args.Characteristic.StringValue;

            System.Diagnostics.Debug.WriteLine(x);
            await characteristic1.StopUpdatesAsync();

            await CrossBluetoothLE.Current.Adapter.DisconnectDeviceAsync(device);

            deviceToggle.IsToggled = x[0] == '1';
            return;
        }
예제 #11
0
        /// <summary>
        /// Disconnects from the device the app is currently paired with.
        /// </summary>
        /// <returns>Returns whether the disconnect was successful.</returns>
        public async Task <bool> DisconnectDevice()
        {
            try
            {
                await characteristic.StopUpdatesAsync();

                characteristic.ValueUpdated -= GetEncryptedMessagePortion;

                await adapter.DisconnectDeviceAsync(PairedDevice);

                PairedDevice = null;
                OnPropertyChanged("Devices");
                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
예제 #12
0
        /// <summary>
        /// Handles the receiving of the slave's respose
        /// It implements even the timeout mechanisms
        /// </summary>
        /// <returns>The messages.</returns>
        /// <param name="timeOut">Time out.</param>
        public async Task <ReceivedData> ListenMessages()
        {
            cts = new CancellationTokenSource(TIMEOUT);             // Set timeout
            receivedMessageData = new List <byte>(sizeOfMessage);
            receivedBytes       = false;

            readCharac.ValueUpdated -= ReadCharac_ValueUpdated;
            readCharac.ValueUpdated += ReadCharac_ValueUpdated;

            if (readCharac.CanUpdate == true)
            {
                await readCharac.StartUpdatesAsync();
            }
            else
            {
                return(new ReceivedData(receivedMessageData.ToArray(), TransmissionState.CharacteristicCantUpdate));
            }


            await Task.Run(() =>
            {
                while (!cts.Token.IsCancellationRequested)
                {
                    if (receivedBytes == true)
                    {
                        break;                                   //I've finished with the reading
                    }
                }
            }, cts.Token);

            await readCharac.StopUpdatesAsync();


            if (receivedBytes == false)
            {
                return(new ReceivedData(receivedMessageData.ToArray(), TransmissionState.TIMEOUT));
            }
            else
            {
                return(new ReceivedData(receivedMessageData.ToArray(), TransmissionState.OK));
            }
        }
예제 #13
0
        protected async Task StopTalk()
        {
            if (_read != null)
            {
                try
                {
                    await _read.StopUpdatesAsync();

                    _read.ValueUpdated -= OnValueUpdated;
                }
                catch
                {
                }
            }

            if (_device != null)
            {
                _bluetoothAdapter.DisconnectDeviceAsync(_device);
            }

            //IsConnectEnabled = true;
            //OnPropertyChanged(nameof(IsConnectEnabled));
        }
예제 #14
0
        public async Task <IBleResult> StopObservingAsync()
        {
            IBleResult result;

            try
            {
                if (_bleCharacteristic == null)
                {
                    result = BleResult.Failure(BleFailure.DeviceNotInitialized);
                }
                else if (!_bleCharacteristic.CanUpdate)
                {
                    result = BleResult.Failure(BleFailure.UpdateNotSupported);
                }
                else
                {
                    if (IsObserving)
                    {
                        await _bleCharacteristic.StopUpdatesAsync().ConfigureAwait(false);

                        IsObserving = false;
                        NotifyObservationCompleted();
                    }
                    result = BleResult.Success();
                }
            }
            catch (TimeoutException)
            {
                result = BleResult.Failure(BleFailure.OperationTimeout);
            }
            catch (Exception e)
            {
                result = BleResult.Failure(e);
            }

            return(result);
        }
예제 #15
0
        private async Task _disconnect()
        {
            try
            {
                _characteristicHR.ValueUpdated -= CharacteristicHR_ValueUpdated;
                await _characteristicHR.StopUpdatesAsync();

                await _adapter.DisconnectDeviceAsync(_device);

                _connectionRetry            = 0;
                _device                     = null;
                _serviceHR                  = null;
                _serviceBattery             = null;
                _characteristicHR           = null;
                _characteristicBatteryLevel = null;
                _currentValue               = null;

                _log("_disconnect", "disconnected");
            }
            catch (Exception e)
            {
                _log("_disconnect", e.Message);
            }
        }
        /// <summary>
        /// Closes the connection interface associated with this bluetooth device.
        /// </summary>
        /// <exception cref="XBeeException">If there is any XBee error.</exception>
        /// <seealso cref="IsOpen"/>
        /// <seealso cref="Open"/>
        public void Close()
        {
            Debug.WriteLine("----- Close");

            // Do nothing if the device is not open.
            if (!IsOpen)
            {
                return;
            }

            // Create a task to disconnect the device.
            Task task = Task.Run(async() =>
            {
                // Unsubscribe from the RX characteristic.
                rxCharacteristic.ValueUpdated -= DataReceived;
                try
                {
                    if (device != null && device.State == DeviceState.Connected)
                    {
                        await rxCharacteristic.StopUpdatesAsync();
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine("----- BLE interface - Error unsubscribing RX characteristic: " + e.Message);
                }

                // Disconnect the device.
                try
                {
                    if (device != null && device.State == DeviceState.Connected)
                    {
                        await adapter.DisconnectDeviceAsync(device);
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine("----- BLE interface - Error disconnecting the device: " + e.Message);
                }

                IsOpen = false;
                lock (disconnectLock)
                {
                    Monitor.Pulse(disconnectLock);
                }
            });

            if (!task.IsCompleted)
            {
                // Wait until the task finishes.
                lock (disconnectLock)
                {
                    Monitor.Wait(disconnectLock, DISCONNECTION_TIMEOUT);
                }
            }

            if (device != null && device.State != DeviceState.Disconnected && device.State != DeviceState.Limited)
            {
                // Set interface connection as closed (although there was a problem closing it...)
                IsOpen = false;
                throw new XBeeException(ERROR_DISCONNECTION);
            }
        }
예제 #17
0
        /// <summary>
        /// Connects to the specified device and completes encryption handshake/key generation.
        /// </summary>
        /// <param name="deviceName">Name of the device to connect to.</param>
        public async Task <bool> ConnectToDevice(string deviceName)  //, Func<bool> DisconnectedHanlder
        {
            //adapter.DeviceConnectionLost += (s, a) =>
            //{
            //    DisconnectedHanlder();
            //};

            try
            {
                IDevice device = null;
                foreach (IDevice i in deviceList)
                {
                    if (i.Name == deviceName)
                    {
                        device = i;
                        break;
                    }
                }
                await adapter.ConnectToDeviceAsync(device);

                OnPropertyChanged("BluetoothState");
                PairedDevice = device;
                var service = await device.GetServiceAsync(Guid.Parse("913CF3FD-7173-43A5-82F4-DFD6F61BAF5F"));

                characteristic = await service.GetCharacteristicAsync(Guid.Parse("44B1DF4E-15C8-4F97-9F34-123D33B0C29D"));

                X9ECParameters     x9        = ECNamedCurveTable.GetByName("secp256r1");
                ECCurve            curve     = x9.Curve;
                ECDomainParameters ecDomain  = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
                ECKeyPairGenerator generator = (ECKeyPairGenerator)GeneratorUtilities.GetKeyPairGenerator("ECDH");
                generator.Init(new ECKeyGenerationParameters(ecDomain, new SecureRandom()));
                AsymmetricCipherKeyPair appKeyPair    = generator.GenerateKeyPair();
                ECPublicKeyParameters   appPublicKey  = (ECPublicKeyParameters)appKeyPair.Public;
                ECPrivateKeyParameters  appPrivateKey = (ECPrivateKeyParameters)appKeyPair.Private;


                // Wait for Arduino Public Key
                characteristic.ValueUpdated += GetPubKeyPortion;
                await characteristic.StartUpdatesAsync();

                Task.Run(CheckIfKeyObtainComplete).Wait();

                // Once full Key has been obtained, stop reading characteristic and unregister handler
                await characteristic.StopUpdatesAsync();

                characteristic.ValueUpdated -= GetPubKeyPortion;

                // Cut off 'starting' padding from beginning of arduino's public key & convert to byte array
                ArdPubKeyStr = ArdPubKeyStr.Substring(8);

                // Now send the app's public key to arduino via same characteristic
                string appPublicKeyStr = appPublicKey.Q.ToString();
                string appPubKey_x     = appPublicKey.Q.XCoord.ToString();
                string appPubKey_y     = appPublicKey.Q.YCoord.ToString();

                for (int i = 0; i < 64 - appPubKey_x.Length; i++)
                {
                    appPubKey_x = "0" + appPubKey_x;
                }
                for (int i = 0; i < 64 - appPubKey_y.Length; i++)
                {
                    appPubKey_y = "0" + appPubKey_y;
                }

                appPublicKeyStr = appPubKey_x + appPubKey_y;
                char[] pubkey_chars = appPublicKeyStr.ToCharArray();
                byte[] pubkey_bytes = new byte[128];

                for (int i = 0; i < 128; i++)
                {
                    pubkey_bytes[i] = Convert.ToByte(pubkey_chars[i]);
                }

                byte[][] chunks = pubkey_bytes
                                  .Select((c, i) => new { Value = c, Index = i })
                                  .GroupBy(x => x.Index / 16)
                                  .Select(grp => grp.Select(x => x.Value).ToArray())
                                  .ToArray();

                foreach (byte[] b in chunks)
                {
                    await characteristic.WriteAsync(b);
                }

                BigInteger Q_x = new BigInteger(1, StringToByteArray(ArdPubKeyStr.Substring(0, 64)));
                BigInteger Q_y = new BigInteger(1, StringToByteArray(ArdPubKeyStr.Substring(64, 64)));
                ECPoint    Q   = curve.CreatePoint(Q_x, Q_y);

                ECPublicKeyParameters ArdPubKey = new ECPublicKeyParameters(Q, ecDomain);

                // Extract the shared secret for decryption
                IBasicAgreement agreement = new Org.BouncyCastle.Crypto.Agreement.ECDHBasicAgreement();
                agreement.Init(appPrivateKey);
                sharedKey = agreement.CalculateAgreement(ArdPubKey);
                Debug.WriteLine("Shared KEY: " + ByteArrayToString(sharedKey.ToByteArrayUnsigned()));

                characteristic.ValueUpdated += GetEncryptedMessagePortion;
                await characteristic.StartUpdatesAsync();

                return(true);
            }
            catch (DeviceConnectionException)
            {
                Debug.WriteLine("Could not connect to device");
                return(false);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                return(false);
            }
        }
예제 #18
0
        private async Task <byte[]> ReceiveFrame()
        {
            const UInt32 waitCommand    = 0x00040000;
            const UInt32 packetCommand  = 0x3F3F3F3F;
            const UInt32 bigFileCommand = 0x3F3F0001;

            try
            {
                if (!_isConnected)
                {
                    return(await Task.FromResult(new byte[0]));
                }
                else
                {
                    bool isWaitCommand = false;

                    do
                    {
                        await Task.Delay(100);

                        await _analyzerChar.StopUpdatesAsync();

                        if (_responseFrame == null || _responseFrame.Length == 0)
                        {
                            throw new Exception("dimensione della risposta errata!");
                        }

                        // Controllo il marker
                        string marker = Encoding.ASCII.GetString(_responseFrame, 0, 4);
                        if (marker != _frameMarker)
                        {
                            string tmp = "";
                            foreach (byte data in _responseFrame)
                            {
                                tmp += data.ToString("X2");
                            }

                            throw new Exception("invalid marker, received: " + tmp);
                        }

                        // Controllo il crc
                        UInt32 crcSent = ArrConverter.GetUInt32FromBuffer(_responseFrame, _responseFrame.Length - 4);
                        UInt32 crcCalc = Crc32_STM.CalculateFromBuffer(_responseFrame, _responseFrame.Length - 4);

                        if (crcSent != crcCalc)
                        {
                            throw new Exception("invalid crc");
                        }

                        // Controllo se ho una risposta con codice di errore
                        UInt32 errorCode = ArrConverter.GetUInt32FromBuffer(_responseFrame, 4);
                        if (errorCode != 0)
                        {
                            throw new Exception(errorCode.ToString());
                        }

                        if (_responseFrame.Length == 16)
                        {
                            if (ArrConverter.GetUInt32FromBuffer(_responseFrame, 8) == waitCommand)
                            {
                                isWaitCommand = true;
                            }
                        }
                        else if (_responseFrame.Length == 20)
                        {
                            if (ArrConverter.GetUInt32FromBuffer(_responseFrame, 8) == packetCommand)
                            {
                                int totalSize  = (int)ArrConverter.GetUInt32FromBuffer(_responseFrame, 12);
                                int packetsNum = ((totalSize % 20) == 0) ? (totalSize / 20) : ((totalSize / 20) + 1);

                                var fullResponse = new byte[totalSize];

                                // Il device cerca di trasmettere un pacchetto
                                await _analyzerChar.StartUpdatesAsync();
                                await SendCommand(packetCommand);

                                for (var packetIndex = 0; packetIndex < packetsNum; packetIndex++)
                                {
                                    await Task.Delay(100);

                                    await _analyzerChar.StopUpdatesAsync();

                                    if (_responseFrame == null || _responseFrame.Length == 0)
                                    {
                                        throw new Exception("dimensione della risposta errata!");
                                    }

                                    _responseFrame.CopyTo(fullResponse, 20 * packetIndex);

                                    await _analyzerChar.StartUpdatesAsync();
                                    await SendCommand(packetCommand);
                                }

                                return(await Task.FromResult(fullResponse));
                            }
                            else if (ArrConverter.GetUInt32FromBuffer(_responseFrame, 8) == bigFileCommand)
                            {
                                int totalSize      = (int)ArrConverter.GetUInt32FromBuffer(_responseFrame, 12);
                                int receivedLength = 0;

                                // Alloco un buffer per l'intero file e il preambolo
                                // Per adesso ignoro il preambolo e copio soltanto il buffer contenente il file
                                byte[] fullRespose = new byte[totalSize + 16];

                                // Il device cerca di trasmettere un pacchetto
                                await _analyzerChar.StartUpdatesAsync();
                                await SendCommand(packetCommand);

                                while (receivedLength < totalSize)
                                {
                                    await Task.Delay(100);

                                    await _analyzerChar.StopUpdatesAsync();

                                    if (_responseFrame == null || _responseFrame.Length == 0)
                                    {
                                        throw new Exception("dimensione della risposta errata!");
                                    }

                                    // Copio partendo da 12 e poi in base alla dimensione dei pacchetti ricevuti
                                    Buffer.BlockCopy(_responseFrame, 0, fullRespose, receivedLength + 12, _responseFrame.Length);

                                    MessagingCenter.Send <IAnalyzerDevice, double>(this, "DownloadFileProgress", (double)receivedLength / totalSize);

                                    receivedLength += _responseFrame.Length;

                                    await _analyzerChar.StartUpdatesAsync();
                                    await SendCommand(packetCommand);
                                }

                                return(await Task.FromResult(fullRespose));
                            }
                        }

                        await _analyzerChar.StartUpdatesAsync();
                    }while (isWaitCommand);
                }

                await _analyzerChar.StartUpdatesAsync();

                return(await Task.FromResult(_responseFrame));
            }
            catch (Exception ex)
            {
                await _analyzerChar.StartUpdatesAsync();

                throw ex;
            }
        }
예제 #19
0
 protected override void OnDisappearing()
 {
     _characteristicRcv?.StopUpdatesAsync();
     UrhoSurface.OnDestroy();
     base.OnDisappearing();
 }
예제 #20
0
        public async Task <bool> ConnectAsync()
        {
            try
            {
                await StopDiscover();

                await _adapter.ConnectToDeviceAsync(SelectedDevice);

                var serialIoService = await GetSerialIoService(SelectedDevice);

                var inBuf  = Guid.Parse(Settings.InBufCharacteristicsId);
                var outBuf = Guid.Parse(Settings.OutBufCharacteristicsId);
                _inBuf = await serialIoService.GetCharacteristicAsync(inBuf);

                _outBuf = await serialIoService.GetCharacteristicAsync(outBuf);

                _inBuf.ValueUpdated += ReadWrite_ValueUpdated;

                switch (_platform)
                {
                case Platform.Undefined:
                    await _inBuf.StartUpdatesAsync();

                    break;

                case Platform.iOS:
                    try
                    {
                        await _inBuf.StartUpdatesAsync();
                    }
                    catch (Exception e)
                    {
                        // This is to be expected on iOS if pair dialog is not dismissed in approx 4 seconds.
                        await _inBuf.StartUpdatesAsync();
                    }
                    break;

                case Platform.Android:
                    // The StartUpdatesAsync task hangs forever when we connect the first time and are paired through the OS.
                    var startUpdateTask = _inBuf.StartUpdatesAsync();
                    if (await Task.WhenAny(startUpdateTask, Task.Delay(2000)) != startUpdateTask)
                    {
                        await _inBuf.StopUpdatesAsync();

                        await _inBuf.StartUpdatesAsync();
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                Connected?.Invoke(this, SelectedDevice);
                return(true);
            }
            catch (Exception e)
            {
                OnError("Connect to device failed!", e.Message);
                OnDisconnected(e.Message);
            }

            return(false);
        }