PORTS Forum

Ports and Interfaces => USB => Topic started by: jain1.anuj on February 09, 2012, 11:36:59 pm

Title: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 09, 2012, 11:36:59 pm
hello everyone,

i had a device that work as a usb keyboard. it has a ultra sonic proximity sensor which detects the person. if the user goes out of the range it fires the keystrokes for locking the computer that are stored in it. when the user comes in it's range, it again fires the keystrokes for unlocking the computer.
when i try to get the handle to the device for reading/writing purpose, application is throwing me the error

"Attempted to read or write protected memory. this is often an indication that other memory is corrupted"

can anyone help me in resolving this error?
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 10, 2012, 11:42:13 am
Windows 2000 and later have exclusive read/write access via CreateFile for HIDs that are configured as a system keyboards or mice.

Use RawInput instead.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 12, 2012, 11:41:01 pm
Thanks JAN for your reply. If i use RAWINPUT than i will not be able to write data to the device. I want to perform both read/write operations.

here is the code for creating handle to the device with GUID as:-
Code: [Select]
GUID_DEVINTERFACE_KEYBOARD = new Guid("884b96c3-56ef-11d1-bc8c-00a0c91405dd");
create file method as :-

Code: [Select]
deviceHandle = CreateFile(devicePathName[0], 0/*GENERIC_WRITE | GENERIC_READ*/ , FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero,
            OPEN_EXISTING, 0, IntPtr.Zero);


code for getting capabilities and HID Usage is as follows:-

Code: [Select]
Capabilities = GetDeviceCapabilities(deviceHandle);

                    MessageBox.Show("capabilities: " + Capabilities.ToString());

                    hidUsage = GetHidUsage(Capabilities);

                    MessageBox.Show("usage : " + hidUsage);

                   internal HIDP_CAPS GetDeviceCapabilities(SafeFileHandle hidHandle)
        {
            IntPtr preparsedData = new System.IntPtr();
            Int32 result = 0;
            Boolean success = false;
           
            try
            {
                success = HidD_GetPreparsedData(hidHandle, ref preparsedData);

                result = HidP_GetCaps(preparsedData, ref Capabilities);
                if ((result != 0))
                {
                    MessageBox.Show("");
                    MessageBox.Show("  Usage: " + Convert.ToString(Capabilities.Usage, 16));
                    MessageBox.Show("  Usage Page: " + Convert.ToString(Capabilities.UsagePage, 16));
                    MessageBox.Show("  Input Report Byte Length: " + Capabilities.InputReportByteLength);
                    MessageBox.Show("  Output Report Byte Length: " + Capabilities.OutputReportByteLength);
                    MessageBox.Show("  Feature Report Byte Length: " + Capabilities.FeatureReportByteLength);
                    MessageBox.Show("  Number of Link Collection Nodes: " + Capabilities.NumberLinkCollectionNodes);
                    MessageBox.Show("  Number of Input Button Caps: " + Capabilities.NumberInputButtonCaps);
                    MessageBox.Show("  Number of Input Value Caps: " + Capabilities.NumberInputValueCaps);
                    MessageBox.Show("  Number of Input Data Indices: " + Capabilities.NumberInputDataIndices);
                    MessageBox.Show("  Number of Output Button Caps: " + Capabilities.NumberOutputButtonCaps);
                    MessageBox.Show("  Number of Output Value Caps: " + Capabilities.NumberOutputValueCaps);
                    MessageBox.Show("  Number of Output Data Indices: " + Capabilities.NumberOutputDataIndices);
                    MessageBox.Show("  Number of Feature Button Caps: " + Capabilities.NumberFeatureButtonCaps);
                    MessageBox.Show("  Number of Feature Value Caps: " + Capabilities.NumberFeatureValueCaps);
                    MessageBox.Show("  Number of Feature Data Indices: " + Capabilities.NumberFeatureDataIndices);

                    Int32 vcSize = Capabilities.NumberInputValueCaps;
                    Byte[] valueCaps = new Byte[vcSize];

                    result = HidP_GetValueCaps(HidP_Input, valueCaps, ref vcSize, preparsedData);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace.ToString());
               
            }
            finally
            {
             

                if (preparsedData != IntPtr.Zero)
                {
                    success = HidD_FreePreparsedData(preparsedData);
                }
            }

            return Capabilities;
        }         

          internal String GetHidUsage(HIDP_CAPS MyCapabilities)
        {
            Int32 usage = 0;
            String usageDescription = "";

            try
            {
                MessageBox.Show("page : " + Capabilities.UsagePage.ToString());
                usage = MyCapabilities.UsagePage * 256 + MyCapabilities.Usage;

                MessageBox.Show("usage in method : " + usage.ToString());

                if (usage == Convert.ToInt32(0X102))
                {
                    usageDescription = "mouse";
                }

                if (usage == Convert.ToInt32(0X106))
                {
                    usageDescription = "keyboard";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            MessageBox.Show("description : " + usageDescription);
            return usageDescription;
           
        }         




code for read and write handle is as follows:-

Code: [Select]
readHandle = CreateFile(devicePathName[0],0 /*GENERIC_READ*/, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero);

                MessageBox.Show("read handle : " + readHandle.DangerousGetHandle().ToString());
                if (readHandle.IsInvalid)
                {
                    exclusiveAccess = true;
                }
                else
                {
                    writeHandle = CreateFile(devicePathName[0], GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

                    MessageBox.Show("write handle : " + writeHandle.DangerousGetHandle().ToString());

                    Boolean res = HidD_FlushQueue(deviceHandle);

                    MessageBox.Show("flush quese: " + res.ToString());


                }




Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 13, 2012, 09:53:55 am
Did you try my previous advice:

http://www.janaxelson.com/forum/index.php?topic=700.msg2636#msg2636

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 13, 2012, 10:48:14 pm
Thanks JAN

I followed your advice but it was not working with my device. As i told you that my device works as a USB KEYBOARD. So please help me in this regard.

I am getting the error that i had specified in my first post in the following code:-

Code: [Select]
Capabilities = GetDeviceCapabilities(deviceHandle);

           hidUsage = GetHidUsage(Capabilities);
         

 
           internal HIDP_CAPS GetDeviceCapabilities(SafeFileHandle hidHandle)
        {
            IntPtr preparsedData = new System.IntPtr();
            Int32 result = 0;
            Boolean success = false;
           
            try
            {
                success = HidD_GetPreparsedData(hidHandle, ref preparsedData);

                result = HidP_GetCaps(preparsedData, ref Capabilities);
                if ((result != 0))
                {
                    MessageBox.Show("");
                    MessageBox.Show("  Usage: " + Convert.ToString(Capabilities.Usage, 16));
                    MessageBox.Show("  Usage Page: " + Convert.ToString(Capabilities.UsagePage, 16));
                    MessageBox.Show("  Input Report Byte Length: " + Capabilities.InputReportByteLength);
                    MessageBox.Show("  Output Report Byte Length: " + Capabilities.OutputReportByteLength);
                    MessageBox.Show("  Feature Report Byte Length: " + Capabilities.FeatureReportByteLength);
                    MessageBox.Show("  Number of Link Collection Nodes: " + Capabilities.NumberLinkCollectionNodes);
                    MessageBox.Show("  Number of Input Button Caps: " + Capabilities.NumberInputButtonCaps);
                    MessageBox.Show("  Number of Input Value Caps: " + Capabilities.NumberInputValueCaps);
                    MessageBox.Show("  Number of Input Data Indices: " + Capabilities.NumberInputDataIndices);
                    MessageBox.Show("  Number of Output Button Caps: " + Capabilities.NumberOutputButtonCaps);
                    MessageBox.Show("  Number of Output Value Caps: " + Capabilities.NumberOutputValueCaps);
                    MessageBox.Show("  Number of Output Data Indices: " + Capabilities.NumberOutputDataIndices);
                    MessageBox.Show("  Number of Feature Button Caps: " + Capabilities.NumberFeatureButtonCaps);
                    MessageBox.Show("  Number of Feature Value Caps: " + Capabilities.NumberFeatureValueCaps);
                    MessageBox.Show("  Number of Feature Data Indices: " + Capabilities.NumberFeatureDataIndices);

                    Int32 vcSize = Capabilities.NumberInputValueCaps;
                    Byte[] valueCaps = new Byte[vcSize];

                    result = HidP_GetValueCaps(HidP_Input, valueCaps, ref vcSize, preparsedData);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace.ToString());
               
            }
            finally
            {
             

                if (preparsedData != IntPtr.Zero)
                {
                    success = HidD_FreePreparsedData(preparsedData);
                }
            }

            return Capabilities;
        }




internal String GetHidUsage(HIDP_CAPS MyCapabilities)
        {
            Int32 usage = 0;
            String usageDescription = "";

            try
            {
                MessageBox.Show("page : " + Capabilities.UsagePage.ToString());
                usage = MyCapabilities.UsagePage * 256 + MyCapabilities.Usage;

                MessageBox.Show("usage in method : " + usage.ToString());

                if (usage == Convert.ToInt32(0X102))
                {
                    usageDescription = "mouse";
                }

                if (usage == Convert.ToInt32(0X106))
                {
                    usageDescription = "keyboard";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            MessageBox.Show("description : " + usageDescription);
            return usageDescription;
           
        }         




When i call the GetDeviceCapabilities() method, it gives me the the error specified in my first post. Can you help me in this problem ?



ANUJ
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 14, 2012, 10:26:07 am
To send data to the device with WriteFile, you need to redesign the device as a generic HID or add a generic HID interface in addition to the keyboard interface.

Another option for sending data to the device is to define a Feature report and open a handle without read/write access. See my example code.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 15, 2012, 04:10:22 am
Thanks a lot JAN!!!
 
Now my device is reading and writing the Feature Reports. :)

Now can i read and write the Input/Output Reports too?
Or it is with the help of feature report i can do my task? i am little bit confused.

my aim is to read/write data from the device and save it in the file.
can you help me in this regard? Waiting for your reply.

Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 15, 2012, 10:37:38 am
To read Input reports from a device that enumerates as a system keyboard, use Raw Input or Feature reports.

To read reports from a generic HID, you can also use ReadFile.

To write reports to a device that enumerates as a system keyboard, use Feature reports.

To write reports to a generic HID, you can also use WriteFile.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 15, 2012, 10:33:19 pm
Thanks again JAN

As my device enumerates as a Keyboard, so i must use Feature Report to read/write data to the device ??

I don't want to use RAW INPUT because it only reads data. So i must concentrate on Feature Reports. :)

At present, i am using FileStream to Write data to the device and it is working fine. I am able to write the values to the device. But the problem i am facing is the low outputBufferSize. It is only 2 bytes so i am unable to write the whole data. I want to read/write the keystrokes from the device that will be configured by the user through application.  

So, how can i manage the memory of outputBuffer to write the whole data that is needed by the user?
Also, what is the maximum size that i can generate for feature report?

When i use FileStream to read the data from the device, it gives me the error. it says that "ACCESS DENIED". So, how can i read the data to the device?

At present i am testing my application with only one device. This application will be distributed among many users, each would have there own devices. So, is it feasible to use only VendorID to detect the device? All the device are manufactured by the same company. So, i think that all the devices wiolud have the same VendorID.

Also i want my device to be detected automatically as soon as it is plugged in the system. How can i do that? At what point should i call the FindTheHid() method to proceed further?

If the device is removed in between, it should stop functioning and display the message that it has been removed from the system. How can i capture the surprise removal of device?
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 16, 2012, 11:40:36 pm
>So, how can i manage the memory of outputBuffer to write the whole data that is needed by the user?
Also, what is the maximum size that i can generate for feature report?

You can increase the buffer size. You will also want to define a longer report to fill the buffer. With firmware support, report data can use multiple transactions.

>When i use FileStream to read the data from the device, it gives me the error. it says that "ACCESS DENIED". So, how can i read the data to the device?

Use Feature reports. Open the handle without read/write access.

>At present i am testing my application with only one device. This application will be distributed among many users, each would have there own devices. So, is it feasible to use only VendorID to detect the device? All the device are manufactured by the same company. So, i think that all the devices wiolud have the same VendorID.

You might want to check the Product ID as well.

>Also i want my device to be detected automatically as soon as it is plugged in the system. How can i do that? At what point should i call the FindTheHid() method to proceed further?

See my HID example code, which detects device attachment and removal.

http://www.lvr.com/hidpage.htm#MyExampleCode

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 20, 2012, 01:07:21 am
Thanks JAN

You said to check Product ID as well.
If i talk about present scenario, i have the details about Vendor ID and Product ID so i am able to check them. But when the user will use the device, he will not be asked to enter the Product ID/Vendor ID in the application because the device gets detected automatically.
So how will i be able to check the Product ID in my application?

Only checking the Vendor ID can't make my device to gets detected ?

Note:- All the devices are manufactured by the same company.

My code for checking the Product/Vendor ID is below:-

Code: [Select]
        myProductID = Int32.Parse("2BFA", System.Globalization.NumberStyles.AllowHexSpecifier);
         myVendorID = Int32.Parse("18C8", System.Globalization.NumberStyles.AllowHexSpecifier);
        
         if ((DeviceAttributes.VendorID == myVendorID) && (DeviceAttributes.ProductID == myProductID))
                            {
                                MessageBox.Show("My device detected");

                                myDeviceDetected = true;
    
                                myDevicePathName = devicePathName[memberIndex];
                            }

Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 20, 2012, 10:34:28 am
Your code already checks the Product ID so I don't know what your question is.

You can use just the Vendor ID if that vendor has and will never have more than one product or multiple products that can use the same host software.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 20, 2012, 10:30:04 pm
My question is that this application will be distributed among many users, each would have there own devices. So, is it feasible to use only Vendor ID to detect the device? All the device are manufactured by the same company. So, i think that all the devices would have the same Vendor ID. User would not be asked to enter details like Vendor/Product ID.

One more thing i need to ask is that can i control the LED lights on my device.
My device has a LED which changes it's color according to the status.
If the person is in range of device than it will be in Green color.
If the person is out of range of device than it will be in Red color.
There is one transition state which changes the color to Yellow.

Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 21, 2012, 09:48:04 am
The product ID is in the device descriptor. The user doesn't set it.

Use a Feature report for the LEDs.

Jan



Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 21, 2012, 11:38:37 pm
Thanks a lot JAN.

Can you please refer me any example or guide me how i can use Feature Report for LED controlling? I had never done this before.
Can i control the Proximity sensor too using Feature report?
My device has a Proximity sensor which detects the position of the user. If the user is out of range from the device, than the device will fire the keystrokes that are configured by the user using the application.
How can i determine the correct position of the user?
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 22, 2012, 10:31:08 am
MY HID example code includes Feature reports:

http://www.lvr.com/hidpage.htm#MyExampleCode

The device firmware reads the report and sets the LED accordingly.

You can send any kind of data in a Feature report.

How to read data from a proximity sensor is outside the scope of this forum! I would suggest starting with the sensor's data sheet.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 23, 2012, 12:06:56 am
Thanks JAN but i didn't get any code related to LED. Can you tell me which properties i need to use for controlling the LED. By what method i can access them?

Also i saw in your HID example that GetHidUsage() method can be modified to check other usage. How can i check for LED with the help of this method ? What modifications i need to do?

NOTE:- The usage for LED is -> 0X108
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 23, 2012, 10:46:01 am
You can add an LED usage to the report descriptor or just call it vendor defined as in my example. In either case, the device firmware will need to know what to do with the data.

The HID spec has an example keyboard report descriptor with LEDs.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 24, 2012, 04:29:43 am
Thanks JAN

I worked on it and make LED controlled by application.

But the problem is that the reports are not been saved in the device. Whenever i plug my device and search for Feature report, it says that no Feature report exists.
I need to write the Report again. As soon as device is unplugged, reports get deleted automatically.
How can i make my reports to be stored on device so that i need not to write them again and again?
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 24, 2012, 10:17:39 am
>But the problem is that the reports are not been saved in the device. Whenever i plug my device and search for Feature report, it says that no Feature report exists.

If you want the device to remember the last Feature report sent before device removal, you'll need to store the report's values in non-volatile memory in the device or resend the report on attachment.

If the values on attachment are always the same, the device firmware can initialize the LEDs to those values.

Jan

Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 27, 2012, 12:43:44 am
The data is not same every time. It can vary. Even the user can change the data saved in the device too. If he changes the saved values, than the altered values should get save in the device.

Moreover, i am not just concerned about the LEDs but the every piece of information that is been send to the device.

In the current scenario, the reports are not getting saved in my device if i remove it. Than how can i resend the reports on attachment ? How can i save the data in the non volatile memory of the device? Can you please throw some more light on it?

If i once Write the data to the device using HidD_SetFeature() method, doesn't it get saved on the device for future use, even if the device is been removed?

I also want to perform the Read operations when the device is been connected to the system automatically to display the values in the application which are saved previously in the device. How can i do the same?

Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 28, 2012, 05:40:55 pm
You will need to program the device firmware to save the values. If you aren't the developer of the device, you'll need to live with whatever capabilities the device has.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 28, 2012, 10:36:09 pm
I have an application which saves the data in the device even after it has been removed. But i don't have the code for it. It means device has memory to save the data.
How can i do the same? Isn't there any way to do it?
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 28, 2012, 10:41:56 pm
If you "have an application which saves the data in the device after it has been removed," why don't you use that application to save the data?

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on February 28, 2012, 11:29:10 pm
That application is developed in c++. I need to developed it again using c#. It's what client want. So i can't used that in my new application. I don't have the code for this application. So can't use it's functionality.
It's necessary to save the data in the device.
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on February 29, 2012, 10:32:25 am
If you are developing the device, you can examine the firmware to find out how it saves and uses the data from the last Feature report received.

If you aren't the developer of the device, you need some kind of documentation that shows how to do what you need to do.

A USB protocol analyzer will show the traffic that results from the application you have. From there, you could attempt to duplicate that traffic with an application you write.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on March 01, 2012, 03:15:49 am
I solved the problem.

I want to detect and read the data automatically as soon as device is plugged into the system. So should i call the FindTheHid() and Read() method when i get the Device Arrival message? Or is there some other way i can do it?

My device has only one LED which changes the color accordingly.

If the user is in range of device than it will show GREEN LED
If the user goes out of range from the device than it shows RED LED
There is a transition state also. When GREEN changes to RED or vice versa, it first changes to YELLOW than the appropriate color.

How can i manage there ON/OFF state.
Suppose if I OFF the GREEN LED, than there should not be any effect on other two. Same goes with all the LEDs. How can i do the same?
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on March 01, 2012, 09:57:09 am
See your device's schematic and the LED's data sheet to find out how to control the LED in device firmware.

Jan
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: jain1.anuj on March 01, 2012, 11:13:21 pm
Can you please explain it in the layman's language. I am a newbie to this kind of work.
 
Title: Re: Error while reading and writing the data to USB keyboard.
Post by: Jan Axelson on March 02, 2012, 10:29:41 am
Then I would suggest starting with web searches on the terms you don't know.

Here is a group with discussions on basic electronics:

http://groups.google.com/group/sci.electronics.basics/topics?lnk

Jan