soldernerd / HID_Utility

This open source (GNU GPLv3) project is aimed at simplifying the development of C# applications that communicate with USB HID (Human Interface Device) devices.
https://soldernerd.com/2017/02/14/c-usb-hid-utility/
40 stars 10 forks source link

Non-blocking reading #3

Closed vostrenkov closed 4 years ago

vostrenkov commented 5 years ago

Hello and thank you for making this utility! Is there any way to have an event-based receiption of reports? I mean now if I try to read a report from a device, but device haven't sent it yet, the code stalls at WinAPI ReadFile function. So I unable neither read any reports nor write them to the device untill device send me something. I'm not sure, but can write/read report operations execute asynchronously?

soldernerd commented 5 years ago

Hi Yuri

Sorry for my late reply. Maybe I don’t understand correctly but the utility is not blocking in any way. You are asked by the utility if you want to receive a package from the device. You say yes or no and continue with whatever you were doing. You are then again informed once a package has been received. Same for sending a package to the device. You prepare the data and continue doing other things. You will then receive a notification if the transmission was successful or not. Also here no need to wait or block anything.

regards

lukas

From: Yuri Vostrenkov notifications@github.com Sent: 11.03.2019 16:16 To: soldernerd/HID_Utility HID_Utility@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: [soldernerd/HID_Utility] Non-blocking reading (#3)

Hello and thank you for making this utility! Is there any way to have an event-based receiption of reports? I mean now if I try to read a report from a device, but device haven't sent it yet, the code stalls at WinAPI ReadFile function. So I unable neither read any reports nor write them to the device untill device send me something. I'm not sure, but can write/read report operations exectute asynchronously?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/soldernerd/HID_Utility/issues/3 , or mute the thread https://github.com/notifications/unsubscribe-auth/ANb3AFu5eD7jYoLUpPFlBFIRqp3bn46Rks5vVnMZgaJpZM4bo2nC . https://github.com/notifications/beacon/ANb3AH_Xcoi_g1gja5-66A7Dm86jdA7Iks5vVnMZgaJpZM4bo2nC.gif

vostrenkov commented 5 years ago

Thanks for reply! Maybe i do it the wrong way, but if i say "yes" for receiving package i'm not able to send any packets until packet received. Here is my code:

        // HidUtility asks if a packet should be sent to the device
        // Prepare the buffer and request a transfer
        public void SendPacketHandler(object sender, UsbBuffer OutBuffer)
        {
                OutBuffer.clear();
                HidReport hreport = new HidReport(HidReport.ReportID.REPORT_ABORT);
                Array.Copy(hreport.ToByteArray(), OutBuffer.buffer, hreport.reportSize + 1);
                OutBuffer.RequestTransfer = true;
        }

        // HidUtility informs us if the requested transfer was successful
        // Schedule to request a packet if the transfer was successful
        public void PacketSentHandler(object sender, UsbBuffer OutBuffer)
        {

            if (OutBuffer.TransferSuccessful)
            {
                Console.WriteLine("Report sent");
            }
            else
            {
                Console.WriteLine("Report send failed");
            }

            OutBuffer.RequestTransfer = false;
        }

        // HidUtility asks if a packet should be requested from the device
        // Always wait for a packet
        public void ReceivePacketHandler(object sender, UsbBuffer InBuffer)
        {
                InBuffer.RequestTransfer = true;
        }

        // HidUtility informs us if the requested transfer was successful and provides us with the received packet
        public void PacketReceivedHandler(object sender, UsbBuffer InBuffer)
        {
            InBuffer.RequestTransfe = false;
            if (InBuffer.TransferSuccessful)
            {
                //taskSheduler.RemoveTask(timeoutTask, null);

                HidReport hr = new HidReport(InBuffer);
                switch (hr.reportID)
                {
                    case HidReport.ReportID.REPORT_ONLINE:
                        Console.WriteLine("Report received: ReportID = ONLINE, State = {0}", hr.state.ToString());
                        break;
                    case HidReport.ReportID.REPORT_CREATE:
                        ReaderID = hr.readerID;
                        Console.WriteLine("Report received: ReportID = CREATE, State = {0:X2}, ReaderID = 0x{1:X4}", hr.state.ToString(), hr.readerID);
                        break;
                    case HidReport.ReportID.REPORT_COPY:
                        DataSize = hr.dataSize;
                        Console.WriteLine("Report received: ReportID = COPY, State = {0:X2}, DataSize = 0x{1:X8}", hr.state.ToString(), hr.dataSize);
                        break;
                    case HidReport.ReportID.REPORT_DELETE:
                        Console.WriteLine("Report received: ReportID = DELETE, State = {0:X2}", hr.state.ToString());
                        break;
                    case HidReport.ReportID.REPORT_ABORT:
                        Console.WriteLine("Report received: ReportID = ABORT, State = {0:X2}", hr.state.ToString());
                        break;
                }

            }

        }
soldernerd commented 5 years ago

It’s been a while since I’ve worked on that code. What happens if you say “no” to sending a package until you’ve received one? Not sure if that solves your problem...

From: Yuri Vostrenkov notifications@github.com Sent: 19.03.2019 07:53 To: soldernerd/HID_Utility HID_Utility@noreply.github.com Cc: Lukas Fässler lfaessler@gmx.net; Comment comment@noreply.github.com Subject: Re: [soldernerd/HID_Utility] Non-blocking reading (#3)

Thanks for reply! Maybe i do it the wrong way, but if i say "yes" for receiving package i'm not able to send any packets until packet received. Here is my code:

    // HidUtility asks if a packet should be sent to the device
    // Prepare the buffer and request a transfer
    public void SendPacketHandler(object sender, UsbBuffer OutBuffer)
    {
            OutBuffer.clear();
            HidReport hreport = new HidReport(HidReport.ReportID.REPORT_ABORT);
            Array.Copy(hreport.ToByteArray(), OutBuffer.buffer, hreport.reportSize + 1);
            OutBuffer.RequestTransfer = true;
    }

    // HidUtility informs us if the requested transfer was successful
    // Schedule to request a packet if the transfer was successful
    public void PacketSentHandler(object sender, UsbBuffer OutBuffer)
    {

        if (OutBuffer.TransferSuccessful)
        {
            Console.WriteLine("Report sent");
        }
        else
        {
            Console.WriteLine("Report send failed");
        }

        OutBuffer.RequestTransfer = false;
    }

    // HidUtility asks if a packet should be requested from the device
    // Always wait for a packet
    public void ReceivePacketHandler(object sender, UsbBuffer InBuffer)
    {
            InBuffer.RequestTransfer = true;
    }

    // HidUtility informs us if the requested transfer was successful and provides us with the received packet
    public void PacketReceivedHandler(object sender, UsbBuffer InBuffer)
    {
        InBuffer.RequestTransfe = false;
        if (InBuffer.TransferSuccessful)
        {
            //taskSheduler.RemoveTask(timeoutTask, null);

            HidReport hr = new HidReport(InBuffer);
            switch (hr.reportID)
            {
                case HidReport.ReportID.REPORT_ONLINE:
                    Console.WriteLine("Report received: ReportID = ONLINE, State = {0}", hr.state.ToString());
                    break;
                case HidReport.ReportID.REPORT_CREATE:
                    ReaderID = hr.readerID;
                    Console.WriteLine("Report received: ReportID = CREATE, State = {0:X2}, ReaderID = 0x{1:X4}", hr.state.ToString(), hr.readerID);
                    break;
                case HidReport.ReportID.REPORT_COPY:
                    DataSize = hr.dataSize;
                    Console.WriteLine("Report received: ReportID = COPY, State = {0:X2}, DataSize = 0x{1:X8}", hr.state.ToString(), hr.dataSize);
                    break;
                case HidReport.ReportID.REPORT_DELETE:
                    Console.WriteLine("Report received: ReportID = DELETE, State = {0:X2}", hr.state.ToString());
                    break;
                case HidReport.ReportID.REPORT_ABORT:
                    Console.WriteLine("Report received: ReportID = ABORT, State = {0:X2}", hr.state.ToString());
                    break;
            }

        }

    }

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/soldernerd/HID_Utility/issues/3#issuecomment-474219897 , or mute the thread https://github.com/notifications/unsubscribe-auth/ANb3APYNSwPBfgYKRdTX39RRBxoZAk9Kks5vYIlZgaJpZM4bo2nC . https://github.com/notifications/beacon/ANb3AF3r_r6xU4zm73nN-LtWVf9hpRuJks5vYIlZgaJpZM4bo2nC.gif

vostrenkov commented 5 years ago

Everything work good if I say “no” to sending until I receive a packet. But in my application I have to “wait” for receiving and be able to sent packets and at the same time. I hoped I do something wrong and you was able to point me on this, but looks like my application is not suitable for your library. So nevermind, now I’m able to communicate properly using https://github.com/mikeobrien/HidLibrary with some modifications based on your code =) Thank you!