<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[James's Programming Page — Generic HID: EventHandler for incoming data?]]></title>
		<link>https://swforum.seekye.com/topic/10131/</link>
		<atom:link href="https://swforum.seekye.com/feed/rss/topic/10131/" rel="self" type="application/rss+xml" />
		<description><![CDATA[The most recent posts in Generic HID: EventHandler for incoming data?.]]></description>
		<lastBuildDate>Mon, 12 Aug 2019 20:25:44 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Generic HID: EventHandler for incoming data?]]></title>
			<link>https://swforum.seekye.com/post/13082/#p13082</link>
			<description><![CDATA[<p>OK I think I&#039;ve got it sorted out, it was at the end of the day a pretty dumb problem entirely on my end with the microcontroller firmware.</p><p>I tried using the HidStream.BeginRead() and ASyncCallback method of reading and while the callback would fire, it was only because the timeout was elapsing.&nbsp; I was still getting no bytes on EP1.&nbsp; While perusing the code on both ends I had a real facedesk moment when it jumped out at me in my firmware: </p><p>It was an issue with the the length parameter in the function to load EP1 .&nbsp; I&#039;m doing 64 Bytes each way, and my IN Endpoint buffer on the microcontroller side I was trying to load 65 bytes rather than 64 into EP1.&nbsp; Since I was just passing this info into an API function that doesn&#039;t have a return status, I&#039;m guessing it just didn&#039;t exchange data on this endpoint when I passed it a bad length parameter.&nbsp; Either that or maybe something was getting clobbered in the overrun, I need to have a deeper look into why this failed in the way that it did.</p><p>I think in writing my code I just put 65 bytes because in my winforms application my buffers have to be 65-bytes long (since the interface # is always the leading byte, followed by the data bytes).</p><p>As soon as I got that squared away, reading the IN Endpoint worked immediately.&nbsp; Both using the InputReceiver, as well as using HidStream.BeginRead() and IAsyncCallback.</p>]]></description>
			<author><![CDATA[null@example.com (KTrenholm)]]></author>
			<pubDate>Mon, 12 Aug 2019 20:25:44 +0000</pubDate>
			<guid>https://swforum.seekye.com/post/13082/#p13082</guid>
		</item>
		<item>
			<title><![CDATA[Generic HID: EventHandler for incoming data?]]></title>
			<link>https://swforum.seekye.com/post/13081/#p13081</link>
			<description><![CDATA[<p>Hello,</p><p>I&#039;m currently trying to write a .NET Winforms application to exchange some configuration info with microcontroller (and in the future, probably do logging and other data exchange as well).&nbsp; The device enumerates in windows, and I am able to find it in my application and open the HID stream.&nbsp; I&#039;m also able to send data to the device.&nbsp; Where I&#039;m running into problems is receiving data from the device.</p><p>My device is a generic HID with 2 Endpoints:<br />EP1: 64-Bytes INT, 20mS<br />EP2: 64-Bytes, INT, 20mS</p><p>My code to find and open the device is below, both upon loading of the form, and whenever the device list changes:</p><p>Load:<br /></p><div class="codebox"><pre><code>/*On form load, check for our device and set up the listChanged event*/
        private void Form1_Load(object sender, EventArgs e)
        {

            var hidDeviceList = list.GetHidDevices().ToArray();

            deviceFound = false;
            foreach (HidDevice dev in hidDeviceList)
            {

                if ((dev.VendorID == 0x0000) &amp;&amp; (dev.ProductID == 0x0505))
                {
                    device = dev;

                    /*We found our device*/
                    if (device.TryOpen(out hidStream))
                    {

                        using (hidStream)
                        {
                            
                            deviceFound = true;

                        }

                    }

                }

            }

            if (deviceFound)
            {
                lbl_connStatus.Text = &quot;CONNECTED&quot;;

                reportDescriptor = device.GetReportDescriptor();
                inputReceiver = reportDescriptor.CreateHidDeviceInputReceiver();
                deviceItem = reportDescriptor.DeviceItems[0];
                inputParser = deviceItem.CreateDeviceItemInputParser();
                list.Changed += new EventHandler&lt;DeviceListChangedEventArgs&gt;(DeviceListChanged);
                inputReceiver.Received += new EventHandler(ReceivedData);
                inputReceiver.Start(hidStream);
            }
            else
            {
                lbl_connStatus.Text = &quot;NOT FOUND&quot;;
            }

        }</code></pre></div><p>DeviceListChanged Event:<br /></p><div class="codebox"><pre><code>/*On any change to list of connected devices, scan for our device*/
/*if not present, unregister ReceivedData event handler*/
        private void DeviceListChanged(object sender, EventArgs e)
        {

            var hidDeviceList = list.GetHidDevices().ToArray();

            deviceFound = false;
            foreach (HidDevice dev in hidDeviceList)
            {
                if ((dev.VendorID == 0x0000) &amp;&amp; (dev.ProductID == 0x0505))
                {
                    device = dev;
                    /*We found our interface*/
                    if (device.TryOpen(out hidStream))
                    {
                        deviceFound = true;
                    }
                    
                }

            }

            if (deviceFound)
            {
                lbl_connStatus.Invoke((MethodInvoker) delegate
                {
                    lbl_connStatus.Text = &quot;CONNECTED&quot;;
                });
                using (hidStream)
                {
                    reportDescriptor = device.GetReportDescriptor();
                    inputReceiver = reportDescriptor.CreateHidDeviceInputReceiver();
                    deviceItem = reportDescriptor.DeviceItems[0];
                    inputParser = deviceItem.CreateDeviceItemInputParser();
                    inputReceiver.Start(hidStream);
                    inputReceiver.Received += new EventHandler(ReceivedData);
                }

            }
            else
            {
                inputReceiver.Received -= ReceivedData;
                lbl_connStatus.Invoke((MethodInvoker)delegate
                {
                    lbl_connStatus.Text = &quot;NOT FOUND&quot;;
                });
            }

        }</code></pre></div><p>DataReceived Event Handler<br /></p><div class="codebox"><pre><code>        private void ReceivedData(object sender, EventArgs e)
        {
            HidSharp.Reports.Report report;

            if(inputReceiver.TryRead(inputReportBuffer,0,out report))
            {

                if (inputParser.TryParseReport(inputReportBuffer, 0, report))
                {
                    /*TODO: Read the data here, send to main thread*/

                }

            }

        }</code></pre></div><br /><p>I was under the impression that this would fire my ReceivedData event when I get data in my IN endpoint, but it does not fire (I never hit a breakpoint placed inside).&nbsp; Does inputReceiver.Received not do what I&#039;m expecting it to do perhaps?&nbsp; Maybe I&#039;m set up fine and it&#039;s the microcontroller code I need to look deeper at?</p><p>I based my DataReceived handler off this snippet in the example code:<br /></p><div class="codebox"><pre><code>    inputReceiver.Received += (sender, e) =&gt;
    {
         Report report;
         while (inputReceiver.TryRead(inputReportBuffer, 0, out report))
         {
              // Parse the report if possible.
              // This will return false if (for example) the report applies to a different DeviceItem.
              if (inputParser.TryParseReport(inputReportBuffer, 0, report))
              {
                  // If you are using Windows Forms, you could call BeginInvoke here to marshal the results
                  // to your main thread.
                  WriteDeviceItemInputParserResult(inputParser);
              }
          }
      };</code></pre></div><p>Thanks in advance for the help!</p>]]></description>
			<author><![CDATA[null@example.com (KTrenholm)]]></author>
			<pubDate>Mon, 12 Aug 2019 18:05:01 +0000</pubDate>
			<guid>https://swforum.seekye.com/post/13081/#p13081</guid>
		</item>
	</channel>
</rss>
