Esempio n. 1
0
        private void FabOnClick(object sender, EventArgs eventArgs)
        {
            device.CancelConnection();
            View view = (View)sender;

            Snackbar.Make(view, "Zatrzymano", Snackbar.LengthLong)
            .SetAction("Action", (View.IOnClickListener)null).Show();
            Finish();
            StartActivity(this.Intent);
        }
Esempio n. 2
0
        /// <summary>
        /// Connect and manage connection as well as hook into your required characterisitcs with all proper cleanups necessary
        /// </summary>
        /// <param name="device"></param>
        /// <param name="serviceUuid"></param>
        /// <param name="characteristicUuids"></param>
        /// <returns></returns>
        public static IObservable <CharacteristicGattResult> ConnectHook(this IDevice device, Guid serviceUuid, params Guid[] characteristicUuids)
        => Observable.Create <CharacteristicGattResult>(ob =>
        {
            var sub = device
                      .WhenConnected()
                      .Select(_ => device.WhenKnownCharacteristicsDiscovered(serviceUuid, characteristicUuids))
                      .Switch()
                      .Select(x => x.RegisterAndNotify(false, false))
                      .Switch()
                      .Subscribe(
                ob.OnNext,
                ob.OnError
                );

            var connSub = device
                          .WhenConnectionFailed()
                          .Subscribe(ob.OnError);

            device.ConnectIf();

            return(() =>
            {
                device.CancelConnection();
                sub?.Dispose();
                connSub?.Dispose();
            });
        });
Esempio n. 3
0
        public async Task CancelConnection_And_Watch()
        {
            await this.Setup(true);

            device.CancelConnection();
            await device.WhenDisconnected().Timeout(TimeSpan.FromSeconds(5)).Take(1).ToTask();
        }
Esempio n. 4
0
        public async Task Start(IDevice device, Stream FirmwarePacket, Stream InitPacket)
        {
            DFUStartTime = DateTime.Now;
            IDevice newDevice = null;

            try
            {
                if (FirmwarePacket == null || InitPacket == null)
                {
                    throw new Exception(GlobalErrors.FILE_STREAMS_NOT_SUPPLIED.ToString());
                }
                newDevice = await ButtonlessDFUWithoutBondsToSecureDFU(device);

                // Run firmware upgrade when device is switched to secure dfu mode
                await RunSecureDFU(newDevice, FirmwarePacket, InitPacket);

                DFUEvents.OnSuccess?.Invoke(DateTime.Now - DFUStartTime);
            }
            catch (Exception ex)
            {
                DFUEvents.OnError?.Invoke(ex.ToString());
                Debug.WriteLineIf(LogLevelDebug, ex.StackTrace);

                newDevice?.CancelConnection();
                device?.CancelConnection();
            }
        }
Esempio n. 5
0
 public void Disconnect()
 {
     if (CrossBleAdapter.Current.IsScanning)
     {
         scan.Dispose();
     }
     connectedDevice.CancelConnection();
 }
Esempio n. 6
0
        /// <summary>
        /// Disconnects device.
        /// </summary>
        public override void Disconnect()
        {
            if (_bleDevice != null && _bleDevice.IsConnected())
            {
                _bleDevice.CancelConnection();
            }

            Connected = false;
        }
Esempio n. 7
0
        /// <summary>
        /// Waits for connection to actually happen
        /// </summary>
        /// <param name="device"></param>
        /// <returns></returns>
        public static IObservable <IDevice> ConnectWait(this IDevice device)
        => Observable.Create <IDevice>(ob =>
        {
            var sub1 = device
                       .WhenConnected()
                       .Take(1)
                       .Subscribe(_ => ob.Respond(device));

            var sub2 = device
                       .WhenConnectionFailed()
                       .Subscribe(ob.OnError);

            device.ConnectIf();
            return(() =>
            {
                sub1.Dispose();
                sub2.Dispose();
                if (device.Status != ConnectionStatus.Connected)
                {
                    device.CancelConnection();
                }
            });
        });
Esempio n. 8
0
        /// <summary>
        /// Connect and manage connection as well as hook into your required characteristics with all the proper cleanups necessary
        /// </summary>
        /// <param name="device"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static IObservable <CharacteristicGattResult> ConnectHook(this IDevice device, ConnectHookArgs args)
        => Observable.Create <CharacteristicGattResult>(ob =>
        {
            var sub = device
                      .WhenConnected()
                      .Select(_ => device.WhenKnownCharacteristicsDiscovered(args.ServiceUuid, args.CharacteristicUuids))
                      .Switch()
                      .Select(x => x.RegisterAndNotify(args.UseIndicateIfAvailable))
                      .Switch()
                      .Subscribe(ob.OnNext);

            device.ConnectIf();

            return(() =>
            {
                if (args.DisconnectOnUnsubscribe)
                {
                    device.CancelConnection();
                }

                sub.Dispose();
            });
        });
Esempio n. 9
0
        /// <summary>
        /// Switch device in Secure DFU state
        /// ! IMPORTANT, assumes that each device has different name !
        /// </summary>
        /// <param name="device"></param>
        /// <returns>Device which is in buttonles state</returns>
        private async Task <IDevice> ButtonlessDFUWithoutBondsToSecureDFU(IDevice device)
        {
            Debug.WriteLineIf(LogLevelDebug, String.Format("Start of Buttonless switching"));

            //await RefreshGattAsync(device);

            IGattCharacteristic buttonlessCharacteristic          = null;
            TaskCompletionSource <CharacteristicGattResult> notif = null;

            device.Connect();
            device = await device.ConnectWait().Timeout(DeviceConnectionTimeout);

            buttonlessCharacteristic = await device.GetKnownCharacteristics(DfuService, DfuButtonlessCharacteristicWithoutBonds).Timeout(OperationTimeout);

            await buttonlessCharacteristic.EnableNotifications(true).Timeout(OperationTimeout);

            // Change device Name

            // Advertisment name should not be longer than 20 symbols
            var newFullName = device.Name + "DFU";
            var newName     = new string(newFullName.Take(20).ToArray());

            byte[] name       = Encoding.ASCII.GetBytes(newName);
            int    newNameLen = name.Length;

            byte[] newNameCommand = new byte[newNameLen + 1 + 1];
            newNameCommand[0] = CChangeAdvertisedName;
            newNameCommand[1] = (byte)(uint)newNameLen;
            name.CopyTo(newNameCommand, 2);

            var nameChangeNotif = GetTimedNotification(buttonlessCharacteristic);
            await buttonlessCharacteristic.Write(newNameCommand).Timeout(OperationTimeout);

            var nameChangeResult = await nameChangeNotif.Task;

            Debug.WriteLineIf(LogLevelDebug, String.Format("Device name change response {0}", nameChangeResult.Data != null ? BitConverter.ToString(nameChangeResult.Data) : "Empty"));

            // Jump from the main application to Secure DFU bootloader (Secure DFU mode)
            notif = GetTimedNotification(buttonlessCharacteristic);
            await buttonlessCharacteristic.Write(CEnterDFU).Timeout(OperationTimeout);

            var result = await notif.Task;

            Debug.WriteLineIf(LogLevelDebug, String.Format("Restart response {0}", result.Data != null ? BitConverter.ToString(result.Data) : "Empty"));

            await buttonlessCharacteristic.DisableNotifications();

            /*
             * The response received from the DFU device contains:
             * +---------+--------+----------------------------------------------------+
             * | byte no | value  | description                                        |
             * +---------+--------+----------------------------------------------------+
             * | 0       | 0x20   | Response code                                      |
             * | 1       | 0x01   | The Op Code of a request that this response is for |
             * | 2       | STATUS | Status code                                        |
             * +---------+--------+----------------------------------------------------+
             */
            int status = result.Data[2];

            if (status != ButtonlessSwitchSuccessCode)
            {
                throw new Exception("Init status not correct " + status);
            }


            bool        alreadyRestarted = false;
            IDisposable dispose          = null;

            dispose = device.WhenStatusChanged().Subscribe(res =>
            {
                if (res == ConnectionStatus.Disconnected || res == ConnectionStatus.Disconnecting)
                {
                    alreadyRestarted = true;
                }
                Debug.WriteLine("###################### STAT {0}", res);
            });


            dispose?.Dispose();
            if (!alreadyRestarted)
            {
                await device.WhenDisconnected().Take(1).Timeout(DeviceRestartTimeout);

                device.CancelConnection();
            }

            IDevice newDevice = await ScanDFUDevice(device, newName);

            Debug.WriteLineIf(LogLevelDebug, String.Format("End of Buttonless switching"));

            return(newDevice);
        }
Esempio n. 10
0
        /// <summary>
        /// Upload Init package (*.dat)
        /// </summary>
        /// <param name="device">Device in DFU mode</param>
        /// <param name="InitFilePath">Init package path (*.dat)</param>
        /// <param name="controlPoint">Secure DFU control point characteristic [Commands / Notifications]</param>
        /// <param name="packetPoint">Secure DFU packet point characteristic [Data of images]</param>
        /// <returns></returns>
        private async Task SendInitPacket(IDevice device, Stream InitPacket, IGattCharacteristic controlPoint, IGattCharacteristic packetPoint)
        {
            Debug.WriteLineIf(LogLevelDebug, "Start of init packet send");
            //FileStream file = new FileStream(InitFilePath, FileMode.Open, FileAccess.Read);
            var   file      = InitPacket;
            int   imageSize = (int)file.Length;// Around ?~ 130bytes
            var   MTU       = Math.Min(device.MtuSize, DFUMaximumMTU);
            CRC32 crc       = new CRC32();

            ObjectInfo info = await SelectCommand(controlPoint, SecureDFUSelectCommandType.CommmandObject);

            bool resumeSendingInitPacket = false;

            if (info.offset > 0 && info.offset <= imageSize)
            {
                // Check if remote sent content is valid
                byte[] buffer = new byte[info.offset];

                file.Seek(0, SeekOrigin.Begin);
                file.Read(buffer, 0, (int)info.offset);

                crc.Update(buffer);

                if (crc.Value == (uint)info.CRC32)
                {
                    if (info.offset == imageSize)
                    {
                        Debug.WriteLineIf(LogLevelDebug, "Init packet already sent and valid");
                        await ExecuteCommand(controlPoint);

                        Debug.WriteLineIf(LogLevelDebug, "End of init packet send");
                        return;
                    }
                    else
                    {
                        Debug.WriteLineIf(LogLevelDebug, String.Format("-> " + info.offset + " bytes of Init packet were sent before"));
                        resumeSendingInitPacket = true;
                        Debug.WriteLineIf(LogLevelDebug, String.Format("Resuming sending Init packet..."));
                    }
                }
                else
                {
                    crc.Reset();
                    info.offset = 0;
                }
            }
            await SetPRN(controlPoint, 0);

            for (int attempt = 1; attempt <= MaxRetries;)
            {
                if (!resumeSendingInitPacket)
                {
                    // Allocate new object
                    await CreateCommand(controlPoint, SecureDFUCreateCommandType.CommmandObject, imageSize);
                }
                await TransferData(packetPoint, crc, file, offsetStart : info.offset, MTU : MTU, offsetEnd : imageSize);

                ObjectChecksum check = await ReadChecksum(controlPoint);

                info.offset = check.offset;
                info.CRC32  = check.offset;
                Debug.WriteLineIf(LogLevelDebug, String.Format("Checksum received (Offset = {0}, CRC = {1})", check.offset, check.CRC32));

                uint localcrc  = (uint)crc.Value;
                uint remotecrc = (uint)check.CRC32;
                if (localcrc == remotecrc)
                {
                    // Everything is OK, we can proceed
                    break;
                }
                else
                {
                    if (attempt < MaxRetries)
                    {
                        attempt++;
                        Debug.WriteLineIf(LogLevelDebug, String.Format("CRC does not match! Retrying...(" + attempt + "/" + MaxRetries + ")"));

                        // Restart
                        resumeSendingInitPacket = false;
                        info.offset             = 0;
                        info.CRC32 = 0;
                        file.Seek(0, SeekOrigin.Begin);
                        crc.Reset();
                    }
                    else
                    {
                        Debug.WriteLineIf(LogLevelDebug, String.Format("CRC does not match!"));
                        device.CancelConnection();
                        return;
                    }
                }
            }
            await ExecuteCommand(controlPoint);

            Debug.WriteLineIf(LogLevelDebug, "End of init packet send");
        }
Esempio n. 11
0
        /// <summary>
        /// Close connections, try to reenter standart mode, unsubscribe notifications
        /// </summary>
        /// <returns></returns>
        private async Task Cleanup(IGattCharacteristic controlPoint, IDevice device)
        {
            await controlPoint.DisableNotifications();

            device.CancelConnection();
        }
 public void Disconnect()
 {
     car.CancelConnection();
 }
 public void Disconnect()
 {
     device.CancelConnection();
 }