Using HIDAPI, how can you query the raw report descriptor? - hid

I'd like to deconstruct the raw reports received from the hid_read function of hidapi.
As I understand, this can be achieved using the information from the device's report descriptors. But when trying to query for those descriptors, I get lost somewhere between the HID Spec and using the methods available in hidapi.
I would love to see a concrete C or node-hidapi based example that queries and enumerates all the report descriptors for a device — perhaps a mouse to keep things simple?

I asked Alan Ott by email about this, and he responded with no as follows:
HIDAPI does not provide functions for getting or parsing the report
descriptor. Since HIDAPI is for talking to a custom devices, these
devices will likely contain all or mostly vendor-defined report items
anyway.

This isn't exactly what you're looking for, but it will get the same job done. I highly recommend you use libusbx over any other hid library. If you are willing to do so, here is a very blatant example of device enumeration.
Edit:
It appears that libusbx has been merged back into libusb. This is awesome! As the above link is broken, here is the new link.

I had success with using both https://github.com/Orochimarufan/HIDRAW/tree/master/HIDRAW_test (that is hopefully the C code example that you asked about) and RDD! USB HID Report Descriptor Decoder for more descriptive output.

Related

Possibility of a multilanguage 'source' name with Twincat Eventlogger

Roald has written an excellent guide for the Twincat Eventlogger.
https://roald87.github.io/twincat/2020/11/03/twincat-eventlogger-plc-part.html
https://roald87.github.io/twincat/2021/01/20/twincat-eventlogger-hmi-part.html
For us this is exactly what we want, there is however 1 thing I haven't figured out. How to get the sourcename of the alarm in multiple languages in the HMI. params::sourceName gives the path in the software (example: MAIN.fbConveyor1.Cylinder1) This path can be customized when initializing the alarm (as Roald has shown). This doesn't work in my case, since I would like to define a generic alarm (example: "Cilinder not retracted within maximum time") that is instantiated multiple times.
I was thinking of using the source as a way to show the operator where the alarm occurs. We use this way (path) already for saving machine settings among other things. The machines we build are installed all over the world, so multilanguage is a must.
Beckhoff does support multilanguage alarm names (when defined), but the source is not defined, but dynamically generated.
Anyone have an idea how this problem can be solved?
If I understand your question correctly, then being able to parameterize the event text with information of the source of the problem should help you out.
If you define the event text as Cylinder {0} has not retracted in time. then you can add the arguments of that text during runtime.
IF bRaiseAlarm THEN
bRaiseAlarm := FALSE;
fbAlarm.ipArguments.Clear().AddString('Alice');
fbAlarm.Raise(0);
END_IF
However, since this also stated in the articles you mentioned, I am unsure if this would solve your problem.
'Alice' in this example, can be hard to localize. The following options come to my mind.
The string can be based on an ENUM. Enums can have textlist support, so if you add your translations there, that should allow multilingual output. However... this does require a lot of setup, placing translations inside your code, and making sure the PLC application is aware of the language that the parameter should use.
Use tags to mark the source device, as tags can be language invariant. It is not the most user-friendly method, but it could work for you. It would become something like: "Cylinder 'AA.1123' did not retract in time.". 'AA.1123' as a tag would have to be stored inside your PLC code as a string. You will have to trust that your operator can relate the tag back to the actual source.
Hopefully, this helped, or else please help me understand the problem better.

Text from UIAutomation property value truncated to 4k

I'm using UIAutomation from a 32-bit C++ application on Windows 7 to get the text content of windows of other processes. I noticed that the API always returns strings truncated to exactly 4096 characters if the text in the windows is longer than that. This happens both with the GetCachedPropertyValue() and the GetCurrentPropertyValue() calls, for both the UIA_ValueValuePropertyId and UIA_LegacyIAccessibleValuePropertyId property Ids.
Tested, among others, against 32- and 64-bit Notepad.
When I retrieve the text using SendMessage and the WM_GETTEXTLENGTH and WM_GETTEXT messages, the complete, untruncated text is returned. (This I currently use as a workaround.)
Looking through the documentation, I can nowhere find any mention of this limitation or how to get around it, which I would expect if truncation was by design.
I found a similar question on stackoverflow but there truncation was apparently due to the Visual Studio debugger, not to the UIAutomation API. However, this question makes it clear that UIAutomation should be able to return very long texts.
Googling the issue leads to another question on stackoverflow that also mentions the 4096 character limit, but unfortunately that question and any possible answer is deleted.
Perhaps the properties UIA_ValueValuePropertyId or UIA_LegacyIAccessibleValuePropertyId are not the correct one to use, but I failed to identify a better one.
Can anyone point me out what I'm doing wrong, or have suggestions for what I could try? Pointers to pieces of documentation that I obviously missed are welcome, too.
TIA
The exposition of the value is here for convenience but has limited capabilities. Instead, you must use TextPattern and it's DocumentRange property. This is explicitly specified here.
From it you can use the GetText(-1) method to retrieve your data.
You can code it like that :
string GetText(AutomationElement ae)
{
return (ae.GetCurrentPattern(TextPattern.Pattern) as TextPattern)?.DocumentRange.GetText(-1);
}

NodeId as string in ModelCompiler OPC UA

I am trying to develop a OPC UA server on my own, but since I am quite a newbie in coding, it is quite hard for me.
I have started from the QuickstartApplication found here: https://github.com/OPCFoundation/UA-.NET-Legacy
in particular I edit the ModelDesign.xml file to customize it as I wish
https://github.com/OPCFoundation/UA-.NET-Legacy/blob/master/ComIOP/Common/Common/ModelDesign.xml
I would like to define some nodes with NodeId as string (all the NodeId in the ModelDesign.xml in the example are numeric)
Following this xsd, I have found "StringId" and "NumericId" that look like what was looking for
https://github.com/OPCFoundation/UA-ModelCompiler/blob/master/ModelCompiler/UA%20Model%20Design.xsd
but changing their value in ModelDesign.xml does nothing about the NodeId. There is no error, just the compiler assigns new NodeIds (all numeric) as if it does not consider the changes I have made.
As a compiler, I am using the ModelCompiler found on GitHub
https://github.com/OPCFoundation/UA-ModelCompiler
Can somebody help me, please? How can I customize the NodeId of the nodes?
Thank you
Edo
the best suggestion that I can offer at this stage is to clone the UA-.NETStandard and run the NetCoreConsoleServer in
UA-.NETStandard/SampleApplications/Samples/NetCoreConsoleServer
through the debugger. The boiler node manager, if my memory serves me well, uses stringIDs. The Interface INodeIdFactory in ISystemContext.cs offers some insight in how ID's are generated.
IMHO, the model designer has no switch to enforce string ID's as you know. So you'll need to programmatically allocate stringID's rather than numeric ID's to nodes upon server boot. I haven't figured it out yet either.
So, you may set breakpoints in the BoilerNodeManager.cs and see how the nodeID is actually constructed.

Xcode (10.7) -- clGetProgramBinaries results unreadable

I have an OpenCL kernel that runs well but I want to look at the intermediate code. I use getprograminfo to pull out the binary and save it to a text file. I've tried this with nVidia, AMD, an i7 and a Xeon.
In all of these cases the binary is unreadable.
I understand that on OS X the chunk of data returned is actually a binary plist. I've found instructions for using plutil to convert it to xml, and they work.
It's still unreadable ... though I've seen instructions online that this is where you find the PTX code (in the case of my AMD 5870). There's the expected clBinaryData key but the data under that key is still one big chunk of stuff, not readable IL instructions in text form.
I'd really like to examine the intermediate language to assess inefficiencies in my use of the gpu. Is this simply not possible under Xcode? Or, what am I doing wrong?
Thanks for any information!...
If you run your program with following environmental variable set you should see .IL and .ISA files in your directory.
$ GPU_DUMP_DEVICE_KERNEL=3 ./my-program
Another way is to use AMD APP Kernel Analyzer (which comes along with AMD APP SDK) to look at the Intermediate file i.e IL and ISA.
(I am not sure whether AMD APP SDK available for MAC or not).
One more option according to APP SDK documentation, put the below in your host code.
putenv("GPU_DUMP_DEVICE_KERNEL=3");
References
AMD OpenCL Programming Guide
AMD Devgurus forum
(Making this a top-level answer so I can do some formatting.)
ocluser's answer was very helpful, in that it was enlightening and caused great learning, though it did not, alas, solve the problem.
I've verified that the environment variable described is being set, and is available to my application when run from within xcode. However, it does not have (under OSX) the highly desirable effect it has under Linux.
But, I now know how to set environment variables in 7 of 8 different ways. I also set "tracer" envars to tell me which methods are effective within the scope of my application. From the below, you can see that both the method of "edit scheme" to add arguments works, as does the "putenv" suggested by ocluser. What didn't set it in that scope: ~/.MACOS/environment.plist, app-specific plist, .profile, and adding a build phase to run a custom script (I found at least one other way within xcode to set one but forgot what I called the tracer and can't find it now; maybe it's on another machine....)
GPU_DUMP_DEVICE_KERNEL is 3
GPU_DUMP_TRK_ENVPLIST is (null)
GPU_DUMP_TRK_APPPLIST is (null)
GPU_DUMP_TRK_DOTPROFILE is (null)
GPU_DUMP_TRK_RUNSCRIPT is (null)
GPU_DUMP_TRK_SCHARGS is 1
GPU_DUMP_TRK_PUTENV is 1
... so, no this doesn't really answer the question, but expands on it a bit. Sorry if poor form. Thanks!
Have not given up and shall provide an actual problem-solver if I find one.

Open source MIDI libraries

I would like to know about open source libraries that could be used to perform some simple tasks on MIDI files:
reading a file one note - or chord - at a time;
extracting a given instrument to re-encode it separately in a new file;
allow to produce a "customizable" score -- by that I mean that I should be able to alter the way the sheet music is produced from the midi using the libraries ... I assume this will require an interaction with Lilypond or Musixtex.
I don't really have a preferred language, as long as it is not too painful to make the app cross-platform. Other advice is welcome -- better to learn it now rather than when I've already written a lot of code. So far, I've been trying to dig in MuseScore's (C++) source code, but it seems that GUI code permeates most files and although spotting relevant files was easy, it is difficult for me to extract just what I need (I'm only aiming for a command line application right now, I'll see about interfaces later).
Any ideas?
Thanks!
Well, I'm just getting started, but this (in Python) seems promising.
If you're still working on the project and language isn't a problem, you might try Python's cross-platform music21 which can parse midi files into Note, Chord, Instrument, etc., objects, lets you manipulate the scores, and then R/T back to MIDI or output to Lilypond, etc. (full disclosure, I'm the author of the toolkit; but I don't know of many others in any language that will take MIDI in and put Lilypond out while giving you a chance to treat the MIDI elements as objects to manipulate in the meantime.).
Sample code to screw up all the instrument sounds in a MIDI file and then play it and make a lilypond.pdf from it:
import music21
mf = music21.converter.parse('pathToMidiFile.mid')
for x in mf.recurse():
if 'Instrument' in x.classes:
x.midiProgram = (x.midiProgram * 2) % 128
mf.show('midi')
mf.show('lily.pdf')
Hope that helps.