public static async IAsyncEnumerable <IHidReport> GetReadReportStreamAsync(this IHidDevice device, [EnumeratorCancellation] CancellationToken token = default)
        {
            if (device == null)
            {
                throw new ArgumentNullException($"{nameof(device)} is null");
            }

            while (!token.IsCancellationRequested)
            {
                yield return(await device.ReadReportAsync(token).ConfigureAwait(false));
            }
        }
예제 #2
0
        public async Task <FootpedalStatus> ReadStatusAsync()
        {
            var report = await _rs28Device.ReadReportAsync();

            byte statusBits = report.Data[STATUS_INDEX];

            return(new FootpedalStatus(
                       0 != (statusBits & LEFT_MASK),
                       0 != (statusBits & RIGHT_MASK),
                       0 != (statusBits & MIDDLE_MASK)
                       ));
        }
예제 #3
0
        private async Task <byte[]> ReceiveResponseAsync(byte command)
        {
            var reportSize = CTAP_RPT_SIZE;

            HidReport report = null;
            var       resp   = Encoding.ASCII.GetBytes(".");

            int  loop_n           = 999;
            int  keepalivesleepms = 100;
            bool isGet            = false;

            if (this.ReceiveResponseTotalTimeoutMs > 0 && keepalivesleepms > 0)
            {
                loop_n = this.ReceiveResponseTotalTimeoutMs / keepalivesleepms;
            }

            for (int intIc = 0; intIc < loop_n; intIc++)
            {
                report = await hidDevice.ReadReportAsync(CallTimeoutMs);

                if (report.ReadStatus != HidDeviceData.ReadStatus.Success)
                {
                    throw new Exception("Error reading from device");
                }

                System.Diagnostics.Debug.WriteLine($"recv Packet: ({report.Data.Length}):{BitConverter.ToString(report.Data)}");

                resp = report.Data;

                // error check
                if (resp[4] == (byte)(CTAP_FRAME_INIT | CTAPHID_ERROR))
                {
                    throw new Exception("Error in response header");
                }
                else if (resp[4] == (byte)(CTAP_FRAME_INIT | CTAPHID_KEEPALIVE))
                {
                    System.Diagnostics.Debug.WriteLine("keep alive");

                    KeepAlive?.BeginInvoke(this, EventArgs.Empty, null, null);
                    await Task.Delay(keepalivesleepms);

                    continue;
                }
                isGet = true;
                break;
            }
            if (isGet == false)
            {
                // timeout
                System.Diagnostics.Debug.WriteLine("timeout");
                isReceiveResponseTotalTimeout = true;
                return(null);
            }

            var dataLength  = (report.Data[5] << 8) + report.Data[6];
            var payloadData = report.Data.Skip(7).Take(Math.Min(dataLength, reportSize)).ToList();

            dataLength -= (int)payloadData.Count;

            var seq = 0;

            while (dataLength > 0)
            {
                report = await hidDevice.ReadReportAsync(CallTimeoutMs);

                if (report.ReadStatus != HidDeviceData.ReadStatus.Success)
                {
                    throw new Exception("Error reading from device");
                }

                if (!report.Data.Take(4).SequenceEqual(cid))
                {
                    throw new Exception("Wrong CID from device");
                }
                if (report.Data[4] != (byte)(seq & 0x7f))
                {
                    throw new Exception("Wrong SEQ from device");
                }
                seq++;
                var packetData = report.Data.Skip(5).Take(Math.Min(dataLength, reportSize)).ToList();

                dataLength -= packetData.Count;

                payloadData.AddRange(packetData);
            }

            var result = payloadData.ToArray();

            return(result);
        }
예제 #4
0
        private async Task <byte[]> ReadResponseAsync(byte command)
        {
            //Log.Debug("ReadResponse");

            //var reportSize = hidDevice.Capabilities.OutputReportByteLength;
            var reportSize = HID_RPT_SIZE;

            var byteArrayBuilder = new ByteArrayBuilder();

            byteArrayBuilder.Append(cid);
            byteArrayBuilder.Append((byte)(TYPE_INIT | command));

            var resp   = Encoding.ASCII.GetBytes(".");
            var header = byteArrayBuilder.GetBytes();

            HidReport report = null;

            while (!resp.Take(header.Length).SequenceEqual(header))
            {
                report = await hidDevice.ReadReportAsync(HidTimeoutMs);

                if (report.ReadStatus != HidDeviceData.ReadStatus.Success)
                {
                    throw new Exception("Error reading from device");
                }

                resp = report.Data;

                byteArrayBuilder.Clear();
                byteArrayBuilder.Append(cid);
                byteArrayBuilder.Append(STAT_ERR);

                if (resp.Take(header.Length).SequenceEqual(byteArrayBuilder.GetBytes()))
                {
                    throw new Exception("Error in response header");
                }
            }

            var dataLength = (report.Data[5] << 8) + report.Data[6];

            var payloadData = report.Data.Skip(7).Take(Math.Min(dataLength, reportSize)).ToArray();

            //Log.Debug($"Payload data: {BitConverter.ToString(payloadData)}");

            byteArrayBuilder.Clear();
            byteArrayBuilder.Append(payloadData);
            dataLength -= (int)byteArrayBuilder.Length;

            var seq = 0;

            while (dataLength > 0)
            {
                report = await hidDevice.ReadReportAsync(HidTimeoutMs);

                if (report.ReadStatus != HidDeviceData.ReadStatus.Success)
                {
                    throw new Exception("Error reading from device");
                }

                if (!report.Data.Take(4).SequenceEqual(cid))
                {
                    throw new Exception("Wrong CID from device");
                }
                if (report.Data[4] != (byte)(seq & 0x7f))
                {
                    throw new Exception("Wrong SEQ from device");
                }
                seq++;
                payloadData = report.Data.Skip(5).Take(Math.Min(dataLength, reportSize)).ToArray();
                //Log.Debug($"Payload data: {BitConverter.ToString(payloadData)}");

                dataLength -= payloadData.Length;
                byteArrayBuilder.Append(payloadData);
            }

            var result = byteArrayBuilder.GetBytes();

            return(result);
        }