public async Task <bool> SetPosition(byte position, byte speed) { try { if (!await Initialize()) { return(false); } GattWriteOption option = SendCommandsWithResponse ? GattWriteOption.WriteWithResponse : GattWriteOption.WriteWithoutResponse; IBuffer buffer = GetBuffer(position, speed); GattCommunicationStatus result = await _writeCharacteristics.WriteValueAsync(buffer, option); return(result == GattCommunicationStatus.Success); } catch (Exception e) { Debug.WriteLine(e.Message); OnDisconnected(e); return(false); } }
private GattWriteOption PreferredWriteOption() { GattWriteOption writeOption = GattWriteOption.WriteWithResponse; if (Characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.WriteWithoutResponse)) { writeOption = GattWriteOption.WriteWithoutResponse; } return(writeOption); }
async Task _WriteValueAsync(ReadOnlyMemory <byte> data, GattWriteOption option) { if (option == GattWriteOption.WriteWithoutResponse) { var(fd, mtu) = await proxy.AcquireWriteAsync(new Dictionary <string, object>()); // do low level file I/O in background task await Task.Run(() => { try { using (var dataHandle = data.Pin()) { unsafe { var written = 0; while (written < data.Length) { var ret = write((int)fd.DangerousGetHandle(), dataHandle.Pointer, (UIntPtr)data.Length); if ((int)ret == -1) { var err = Marshal.GetLastWin32Error(); if (err == EINTR || err == EAGAIN) { continue; } // TODO: marshal other errors to more specific exceptions throw new Exception($"IO error: {Marshal.PtrToStringAnsi(strerror(err))}"); } written += (int)ret; } } } } finally { fd.Close(); } }); } else { if (data.Length <= 20) { await proxy.WriteValueAsync(data.ToArray(), new Dictionary <string, object>()); } else { var options = new Dictionary <string, object> { { "offset", (ushort)0 } }; for (ushort i = 0; i < data.Length; i += 20) { options["offset"] = i; await proxy.WriteValueAsync(data.Slice(i, Math.Min(data.Length - i, 20)).ToArray(), options); } } } }
/// <summary> /// Performs a Characteristic Value write to a Bluetooth LE device. /// </summary> /// <param name="value">A byte array object which contains the data to be written to the Bluetooth LE device.</param> /// <returns>The object that manages the asynchronous operation, which, upon completion, returns the status with which the operation completed.</returns> private async Task <GattCommunicationStatus> DoWriteValueAsync(byte[] value, GattWriteOption writeOption) { bool success = _characteristic.SetValue(value); if (_service.Device._bluetoothGatt.WriteCharacteristic(_characteristic)) { return(GattCommunicationStatus.Success); } return(GattCommunicationStatus.Unreachable); }
private async Task <GattCommunicationStatus> DoWriteValueAsync(byte[] value, GattWriteOption writeOption) { try { _characteristic.Value = NSData.FromArray(value); _characteristic.Service.Peripheral.WriteValue(NSData.FromArray(value), _characteristic, writeOption == GattWriteOption.WriteWithResponse ? CBCharacteristicWriteType.WithResponse : CBCharacteristicWriteType.WithoutResponse); return(GattCommunicationStatus.Success); } catch { return(GattCommunicationStatus.Unreachable); } }
private async Task DoIncrementWriteTapped(GattWriteOption WriteOption) { var oldValue = uiValueShow.Text; var characteristic = Characteristic; try { if (characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Read)) { var buffer = await characteristic.ReadValueAsync(); if (buffer.Status == GattCommunicationStatus.Success) { var data = buffer.Value.ToArray(); for (int i = data.Length - 1; i >= 0; i--) { if (data[i] < 0xFF) { data[i]++; break; } else { data[i] = 0; // And carry the one to the next byte. } } var dataBuffer = data.AsBuffer(); var newAsString = ValueParser.ConvertToStringHex(dataBuffer); uiValueShow.Text = newAsString; var status = await Characteristic.WriteValueWithResultAsync(dataBuffer, WriteOption); } } } catch (Exception) { ; //TODO: show exception to user! } }
private async Task DoWriteAsync(GattWriteOption writeOption) { try { var cvc = new CharacteristicEditorControl(NC, writeOption); await cvc.InitAsync(Service, Characteristic); var dlg = new ContentDialog() { Title = "Edit Value", Content = cvc, CloseButtonText = "Done", }; await dlg.ShowAsync(); // Update the value if possible. Some writable values are not readable at all. await DoReadAsync(false); // not a readable item? then just move on with life! } catch (Exception ex) { uiValueShow.Text = "Unable to write"; System.Diagnostics.Debug.WriteLine($"Exception: unable to write to characteristic ({ex.Message})"); } }
async Task _WriteValueAsync(ReadOnlyMemory <byte> data, GattWriteOption option) { // REVISIT: copying everything twice var writer = new DataWriter(); writer.WriteBytes(data.ToArray()); switch (option) { case GattWriteOption.WriteWithResponse: var result = await characteristic.WriteValueWithResultAsync(writer.DetachBuffer()); switch (result.Status) { case Win.GattCommunicationStatus.Success: return; default: throw new Exception(); } case GattWriteOption.WriteWithoutResponse: var result2 = await characteristic.WriteValueAsync(writer.DetachBuffer(), Win.GattWriteOption.WriteWithoutResponse); switch (result2) { case Win.GattCommunicationStatus.Success: return; default: throw new Exception(); } default: throw new ArgumentException("Invalid write option", nameof(option)); } }
private async void OnEditTapped(object sender, TappedRoutedEventArgs e) { GattWriteOption writeOption = PreferredWriteOption(); await DoWriteAsync(writeOption); }
/// <summary> /// Primary method used to for any bluetooth characteristic WriteValueAsync() calls. /// There's only one characteristic we use, so just use the one global. /// </summary> /// <param name="method" ></param> /// <param name="command" ></param> /// <returns></returns> private async Task WriteCommandAsync(int characteristicIndex, string method, byte[] command, GattWriteOption writeOption) { GattCommunicationStatus result = GattCommunicationStatus.Unreachable; try { result = await Characteristics[characteristicIndex].WriteValueAsync(command.AsBuffer(), writeOption); } catch (Exception) { result = GattCommunicationStatus.Unreachable; } Status.ReportStatus(method, result); if (result != GattCommunicationStatus.Success) { // NOTE: should add a way to reset } }
/// <summary> /// Performs a Characteristic Value write to a Bluetooth LE device. /// </summary> /// <param name="value">A byte array object which contains the data to be written to the Bluetooth LE device.</param> /// <param name="writeOption">Specifies what type of GATT write should be performed.</param> /// <returns>The object that manages the asynchronous operation, which, upon completion, returns the status with which the operation completed.</returns> public Task <GattCommunicationStatus> WriteValueAsync(byte[] value, GattWriteOption writeOption) { return(DoWriteValueAsync(value, writeOption)); }
Task _WriteValueAsync(ReadOnlyMemory <byte> data, GattWriteOption option = GattWriteOption.WriteWithResponse) => throw new NotImplementedException();
private async Task <GattCommunicationStatus> DoWriteValueAsync(byte[] value, GattWriteOption writeOption) { return(await _characteristic.WriteValueAsync(value.AsBuffer(), (Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteOption) writeOption).AsTask() == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success ? GattCommunicationStatus.Success : GattCommunicationStatus.Unreachable); }
private async Task <GattCommunicationStatus> DoWriteValueAsync(byte[] value, GattWriteOption writeOption) { throw new PlatformNotSupportedException(); }
/// <summary> /// Issues a request to write the value of the characteristic. /// </summary> public Task WriteValueAsync(ReadOnlyMemory <byte> data, GattWriteOption option = GattWriteOption.WriteWithResponse) => _WriteValueAsync(data, option);