-
-
Notifications
You must be signed in to change notification settings - Fork 365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Research fallout from usbhid-ups fix for LP64 bit maths #1138
Conversation
Adapting from original issue report in #1023:
From Jim: On my side, so far I did not reproduce this at least in the test program - with both implementations of |
I ran the new unittests, and also ran the more verbose version against my ups. in the unittest, the min/max values are correct: on the real hardware however those values are wrong, but I don't know how min/max are derived. if log in logmin/logmax means historical (logged) values, it will always be wrong as we don't have any previous values...
|
Code comments say it is "logical" Min/Max, and at/near https://github.com/networkupstools/nut/pull/1138/files#diff-8dc52da32d935c64c234bbd7955b6db39136d4d21ed30b6e0eca1a58ffb1311cL400 the parsed In your report, the "Unit" seems weird; wondering if it is at all initialized or random-memory bits, and how it did not impact in older code. And also the LogMin/LogMax seem bogus, but less bogus so to say. I'm away from computer now for the day, so can only guess these fields were ignored by older code, maybe?.. |
min max were always 0, -1 (which can't be correct) on the wrongly reported values. |
min/max 0,-1 triggered the following (old) code:
If I restore this ( |
Thanks for the posting; at least that would restore status-quo I guess,
while thinking about better fixes. Firmwares might also have cut corners,
cables might catch EMI noise, etc. so sanity checks are good and maybe
there just is no "fix" on our side.
I wonder if it makes sense to log that bail-out, maybe once to not spam
much, so e.g. firmware authors who might integrate with NUT would know they
did a sloppy job WRT protocol spec?..
…On Wed, Oct 20, 2021, 16:36 Stephan ***@***.***> wrote:
min/max 0,-1 triggered the following (old) code:
/* figure out how many bits are significant */ range = pData->LogMax -
pData->LogMin + 1; if (range <= 0) { /* makes no sense, give up */ *pValue
= value; return; }
If I restore this (
https://github.com/networkupstools/nut/pull/1139/files#diff-fd503d938f5fdf52c584c8643bacca0ed7b9dbdd2fc24c9f7c19abda651313deR467)
it works again as expected, but maybe there is a better, cleaner solution
to handle this.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1138 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAMPTFHCQSV5RRIAAO7A2KTUH3HWBANCNFSM5GLXCUSQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Thanks for the report. The thing to look for is where the Logical Minimum, and Logical Maximum are being derived. Units isn't involved at this stage (though it looks odd and it would be good to know if that value is actually correct). Your UPS is reporting back a 16-bit value, which is being correctly extracted, but because the logical maximum value is reported as a signed value (-1) rather than unsigned (65535) the newer code is going to honor that rather than throwing up its hands. |
Interesting point: LogMin/LogMax seem to be long's, so at least 32 bit long
anywhere, right?
…On Wed, Oct 20, 2021, 20:09 Nick Briggs ***@***.***> wrote:
Thanks for the report. The thing to look for is where the Logical Minimum,
and Logical Maximum are being derived. Units isn't involved at this stage
(though it looks odd and it would be good to know if that value is actually
correct). Your UPS is reporting back a 16-bit value, which is being
correctly extracted, but because the logical maximum value is reported as a
signed value (-1) rather than unsigned (65535) the newer code is going to
honor that rather than throwing up its hands.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1138 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAMPTFAPK44EOU4G6GD2K33UH4AXFANCNFSM5GLXCUSQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Thinking out loud here: LogMin and LogMax get set up in HIDParse (hidparser.c:305 et seq), which come from the report descriptor -- which I think was in your diagnostic output so I'll have a look. I'm a little suspicious of hidparser.c:FormatValue, which is ONLY used to extract the logical/physical x min/max values, and doesn't seem to be capable of returning +65535 from a 2-byte value... time to go read the spec. In the cases I was looking at for extracting item values correctly (based on the report descriptor + bytes read) all the report descriptors were correct. You've got a case here where the report descriptor is either plain wrong, or misinterpreted. |
As a size=16 bit (probably), does it have a way to signal signedness? Or
would it be prudent for us to assume/cast unsigned always for <=31 bits?
…On Wed, Oct 20, 2021, 20:56 Jim Klimov ***@***.***> wrote:
Interesting point: LogMin/LogMax seem to be long's, so at least 32 bit
long anywhere, right?
On Wed, Oct 20, 2021, 20:09 Nick Briggs ***@***.***> wrote:
> Thanks for the report. The thing to look for is where the Logical
> Minimum, and Logical Maximum are being derived. Units isn't involved at
> this stage (though it looks odd and it would be good to know if that value
> is actually correct). Your UPS is reporting back a 16-bit value, which is
> being correctly extracted, but because the logical maximum value is
> reported as a signed value (-1) rather than unsigned (65535) the newer code
> is going to honor that rather than throwing up its hands.
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#1138 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAMPTFAPK44EOU4G6GD2K33UH4AXFANCNFSM5GLXCUSQ>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
>
|
Don't know... that's why I need to read the spec and look at the data transmitted in the report descriptor. We may be chasing code that's throwing away information and then later trying to guess (sometimes incorrectly) what that information was. |
The values that are pulled out of the report descriptor (for the min/max) can be 1, 2, or 4 bytes long. That's independent of the size of the values in the items that are being sent later. For example, the descriptor could say in 4 bytes that the range is 0..65535 and then later the item value could be transmitted as 1 or 2 bytes as necessary to represent the instantaneous reading. I haven't got as far as reading the spec yet. Regardless, the code base could use a test interface to call the |
First: With respect to the Unit code, 15782177, (aka 0xF0D121) -- that is indeed the unit code for Volts. Second: I fed the report descriptor to USB Report Descriptor Parser -- an independent implementation of the HIDParser -- and this is the result: To pick one of the problematic items:
we see that:
which indeed says that the acceptable range is 0..-1. If they meant to say 0..65535, they should have described the LogicalMaximum in a 4-byte field (as they did in Report ID 9) instead of a 2-byte field:
which had a report descriptor of
(One could be forgiven for wondering why this report decoder thinks that FFFF0000 (little-endian 32-bit value) is 65534 not 65535!! -- I'm not going to read his Javascript to find out) I do notice that since I last visited the specs there has been an update to the USB Usage Tables for HID Power Devices (May 29, 2020) -- unfortunately I think the extent of the update is to newly disclaim responsibility for using the information it contains. :-( So... I think there are a few things to be done
Comments? |
Thanks @nbriggs for the fine research, I guess the "hack in the code" makes sense for the time being; at least it would make devices usable again even if with lesser peace of mind that the values are trustworthy protocol-wise. Unfortunately I do not have USB-connected UPSes currently, so might not be able to help with data-point collections in short term. |
…he two implementations better
…the two implementations better
dc3bec9
to
cc47d78
Compare
NOTE: Rebased over recent master with its bunch of recipe fixes; should make it easier to |
Thinking out loud: are you aware of any software emulators of UPS protocols - scripts, VMs, etc. that would talk on a Unix or network socket to act like a serial/snmp/... UPS? Maybe even something that would even "be" an USB device (maybe as a kernel driver emulating one, or something that can be "attached" to a VM vUSB port)? I suppose that would be very helpful for NUT driver debugging and unit-testing, especially around different CPU endianness and word size definitions (while interacting with the same bit stream on the cable). |
Closing the PR, since this is probably not something we would actually merge, and to avoid rebuilds whenever master changes. The branch remains available for testing if would be needed (and invoking CI automation to test in QEMU machines with many architectures). |
Follows up from #1023 (comment) and PRs #1040 and #1055
This PR increases logging detail for report posted in the issue (apparently impacted development on #616), and brings back code of implementation obsoleted by PR #1040 so it is easier to compare the two in real time.
Hopefully this branch will get tested for different endiannesses by the QEMU side of NUT CI farm.
CC @nbriggs @aquette @blecher-at