public async Task <uint> WriteReportAsync(byte[] data, byte reportId, CancellationToken cancellationToken = default) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (DataReceiver.HasData) { Logger.LogWarning("Writing to device but data has already been received that has not been read"); } var tranformedData = _writeTransferTransform(data, reportId); var buffer = tranformedData.AsBuffer(); //We pass the report id. All this does is sets the array at index zero to the report id //This gets overwritten by the tranform anyway //It would probably be nice to set the values in outReport.Data from index 1-Length but it doesn't seem possible to do that var outReport = ConnectedDevice.CreateOutputReport(reportId); outReport.Data = buffer; try { var operation = ConnectedDevice.SendOutputReportAsync(outReport); var count = await operation.AsTask(cancellationToken); if (count == tranformedData.Length) { //Get the actual data sent, and the actual number of bytes written and log them var transferResult = new TransferResult(outReport.Data.ToArray(), count); Logger.LogDataTransfer(new Trace(true, transferResult)); } else { Logger.LogError(Messages.GetErrorMessageInvalidWriteLength(tranformedData.Length, count) + "{length} {count}", tranformedData.Length, count, GetType().Name); throw new IOException(Messages.GetErrorMessageInvalidWriteLength(tranformedData.Length, count)); } return(count); } catch (ArgumentException ex) { //TODO: Check the string is nasty. Validation on the size of the array being sent should be done earlier anyway if (string.Equals(ex.Message, "Value does not fall within the expected range.", StringComparison.Ordinal)) { throw new IOException("It seems that the data being sent to the device does not match the accepted size. Try specifying a write transfer transform", ex); } throw; } }
public async Task WriteReportAsync(byte[] data, byte?reportId) { if (data == null) { throw new ArgumentNullException(nameof(data)); } byte[] bytes; if (DataHasExtraByte) { bytes = new byte[data.Length + 1]; Array.Copy(data, 0, bytes, 1, data.Length); bytes[0] = reportId ?? DefaultReportId; } else { bytes = data; } var buffer = bytes.AsBuffer(); var outReport = ConnectedDevice.CreateOutputReport(); outReport.Data = buffer; try { var operation = ConnectedDevice.SendOutputReportAsync(outReport); var count = await operation.AsTask(); if (count == bytes.Length) { Tracer?.Trace(true, bytes); } else { var message = Messages.GetErrorMessageInvalidWriteLength(bytes.Length, count); Logger?.Log(message, GetType().Name, null, LogLevel.Error); throw new IOException(message); } } catch (ArgumentException ex) { //TODO: Check the string is nasty. Validation on the size of the array being sent should be done earlier anyway if (string.Equals(ex.Message, "Value does not fall within the expected range.", StringComparison.Ordinal)) { throw new IOException("It seems that the data being sent to the device does not match the accepted size. Have you checked DataHasExtraByte?", ex); } throw; } }
public async Task InitializeAsync(CancellationToken cancellationToken = default) { //TODO: Put a lock here to stop reentrancy of multiple calls using var loggerScope = Logger?.BeginScope("DeviceId: {deviceId} Region: {region}", DeviceId, nameof(UwpHidDeviceHandler)); Logger.LogInformation("Initializing Hid device {deviceId}", DeviceId); try { if (disposed) { throw new ValidationException(Messages.DeviceDisposedErrorMessage); } Logger.LogDebug(Messages.InformationMessageInitializingDevice); await GetDeviceAsync(DeviceId, cancellationToken); if (_writeBufferSize == null) { //I can't figure out how to get device descriptors for Hid on UWP... //We can create an output report and get the length which should give us the size the write buffer size //and then we guess that the read buffer size is the same? var hidOutputReport = ConnectedDevice.CreateOutputReport(); _writeBufferSize = (ushort)hidOutputReport.Data.ToArray().Length; _readBufferSize = _writeBufferSize; } if (ConnectedDevice != null) { ConnectedDevice.InputReportReceived += ConnectedDevice_InputReportReceived; } else { throw new DeviceException($"The device {DeviceId} failed to initialize"); } } catch (Exception ex) { Logger.LogError(ex, Messages.ErrorMessageCouldntIntializeDevice); throw; } }
public async Task WriteReportAsync(byte[] data, byte?reportId) { byte[] bytes; if (DataHasExtraByte) { bytes = new byte[data.Length + 1]; Array.Copy(data, 0, bytes, 1, data.Length); bytes[0] = reportId ?? DefaultReportId; } else { bytes = data; } var buffer = bytes.AsBuffer(); var outReport = ConnectedDevice.CreateOutputReport(); outReport.Data = buffer; try { var operation = ConnectedDevice.SendOutputReportAsync(outReport); await operation.AsTask(); Tracer?.Trace(false, bytes); } catch (ArgumentException ex) { //TODO: Check the string is nasty. Validation on the size of the array being sent should be done earlier anyway if (string.Equals(ex.Message, "Value does not fall within the expected range.", StringComparison.Ordinal)) { throw new Exception("It seems that the data being sent to the device does not match the accepted size. Have you checked DataHasExtraByte?", ex); } throw; } }