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); }
/// <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(); }); });
public async Task CancelConnection_And_Watch() { await this.Setup(true); device.CancelConnection(); await device.WhenDisconnected().Timeout(TimeSpan.FromSeconds(5)).Take(1).ToTask(); }
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(); } }
public void Disconnect() { if (CrossBleAdapter.Current.IsScanning) { scan.Dispose(); } connectedDevice.CancelConnection(); }
/// <summary> /// Disconnects device. /// </summary> public override void Disconnect() { if (_bleDevice != null && _bleDevice.IsConnected()) { _bleDevice.CancelConnection(); } Connected = false; }
/// <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(); } }); });
/// <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(); }); });
/// <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); }
/// <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"); }
/// <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(); }