sbozarth / homebridge-lc7001

Homebridge plugin to communicate with Legrand LC7001. (RFLC, Adorne, and On-Q)
MIT License
20 stars 9 forks source link

JSON Parsing Errors #7

Open jcgorla-dev opened 4 years ago

jcgorla-dev commented 4 years ago

Having trouble with getting the latest version to work on HOOBS. I'm getting continual JSON parsing errors. Any ideas if this is a bug in the plugin or configuration?

Buffer Contents: 6/14/2020, 4:33:31 PM 8DBF4302B1B882D522F53491F54A0DA3 0026EC02EE11Hello V1 6/14/2020, 4:33:31 PM Error parsing JSON. 6/14/2020, 4:33:31 PM SyntaxError: Unexpected token F in JSON at position 1 6/14/2020, 4:33:31 PM at JSON.parse () 6/14/2020, 4:33:31 PM at Object. (/home/hoobs/.hoobs/node_modules/homebridge-lc7001/lib/lc7001.js:273:34) 6/14/2020, 4:33:31 PM at Array.forEach () 6/14/2020, 4:33:31 PM at Object. (/home/hoobs/.hoobs/node_modules/homebridge-lc7001/lib/lc7001.js:270:12) 6/14/2020, 4:33:31 PM at Socket.emit (events.js:210:5) 6/14/2020, 4:33:31 PM at addChunk (_stream_readable.js:309:12) 6/14/2020, 4:33:31 PM at readableAddChunk (_stream_readable.js:286:13) 6/14/2020, 4:33:31 PM at Socket.Readable.push (_stream_readable.js:224:10) 6/14/2020, 4:33:31 PM at TCP.onStreamRead (internal/stream_base_commons.js:182:23) 6/14/2020, 4:33:31 PM Buffer Contents: 6/14/2020, 4:33:31 PM 7F158C6E56C3627E 6/14/2020, 4:33:31 PM Error parsing JSON. 6/14/2020, 4:33:31 PM SyntaxError: Unexpected token F in JSON at position 1 6/14/2020, 4:33:31 PM at JSON.parse () 6/14/2020, 4:33:31 PM at Object. (/home/hoobs/.hoobs/node_modules/homebridge-lc7001/lib/lc7001.js:273:34) 6/14/2020, 4:33:31 PM at Array.forEach () 6/14/2020, 4:33:31 PM at Object. (/home/hoobs/.hoobs/node_modules/homebridge-lc7001/lib/lc7001.js:270:12) 6/14/2020, 4:33:31 PM at Socket.emit (events.js:210:5) 6/14/2020, 4:33:31 PM at addChunk (_stream_readable.js:309:12) 6/14/2020, 4:33:31 PM at readableAddChunk (_stream_readable.js:286:13) 6/14/2020, 4:33:31 PM at Socket.Readable.push (_stream_readable.js:224:10) 6/14/2020, 4:33:31 PM at TCP.onStreamRead (internal/stream_base_commons.js:182:23) 6/14/2020, 4:33:31 PM Buffer Contents: 6/14/2020, 4:33:31 PM 7F158C6E56C3627E557DE4B7BA6FD4A3 6/14/2020, 4:33:31 PM Error parsing JSON. 6/14/2020, 4:33:31 PM SyntaxError: Unexpected token F in JSON at position 1 6/14/2020, 4:33:31 PM at JSON.parse () 6/14/2020, 4:33:31 PM at Object. (/home/hoobs/.hoobs/node_modules/homebridge-lc7001/lib/lc7001.js:273:34) 6/14/2020, 4:33:31 PM at Array.forEach () 6/14/2020, 4:33:31 PM at Object. (/home/hoobs/.hoobs/node_modules/homebridge-lc7001/lib/lc7001.js:270:12) 6/14/2020, 4:33:31 PM at Socket.emit (events.js:210:5) 6/14/2020, 4:33:31 PM at addChunk (_stream_readable.js:309:12) 6/14/2020, 4:33:31 PM at readableAddChunk (_stream_readable.js:286:13) 6/14/2020, 4:33:31 PM at Socket.Readable.push (_stream_readable.js:224:10) 6/14/2020, 4:33:31 PM at TCP.onStreamRead (internal/stream_base_commons.js:182:23) 6/14/2020, 4:33:31 PM Buffer Contents: 6/14/2020, 4:33:31 PM 7F158C6E56C3627E557DE4B7BA6FD4A3 0026EC02EE11

sttomic commented 4 years ago

I'm having the exact same issue. I'm new to Homebridge and am trying to figure this out. The code is trying to parse JSON but it's only receiving Hex values. The second hex value in many cases is actually your MAC address.

theiding commented 4 years ago

Which version of the LC7001 are you running?

jcgorla-dev commented 4 years ago

My LC7001 is running firmware 4.1.0-59-g96b3 which is the latest update available on the Legrand Light Control iOS app.

theiding commented 4 years ago

My firmware is 4.1.2 and it is running without problems if that helps in any way (and to clarify - I am not running this project, but used it as the basis for a Java based implementation of an OpenHAB binding https://github.com/openhab/openhab-addons/pull/6553. Over the past 2 years - including version 4.1.2 now - I have not seen any changes in the JSON format that the hub sends).

sttomic commented 4 years ago

My firmware is 4.1.2 NodeJS is 12.17.0 Homebridge - just upgraded to 1.1.1 homebridge-lc7001 is 0.6.3

I still have the problem though. It appears that the hub is only returning HEX instead of JSON. Not sure why. Some of the Hex values include the MAC address of the Hub. I want to try and troubleshoot by sending some REST requests directly to the Hub with Postman. Does anyone have any suggestions for REST requests to try? I can't find any API documentation and since I'm new the Homebridge it will take me a little while to reverse engineer the code to determine the proper request format.

sttomic commented 4 years ago

Knowing that Node is known for introducing breaking changes, I downgraded Node to 10.17.0, which is the earliest version that Homebridge claims to support. So with the earliest possible Node version, but with the latest firmware, latest homebridge version, and latest homebridge-lc7001, I still have this problem. I'd really love to get this to work but am stumped. My only option at this point is to try and reverse engineer the code to figure out what the API is so that I can start troubleshooting. If anyone has any pointers that would be really helpful!!

sttomic commented 4 years ago

Anyone have any thoughts on this problem? I have a hunch that Legrand started to encrypt their API. The responses in the log look like encrypted data. I also looked at the Legrand app release history and found an entry for v 4.1 (5 months ago) that says: "For existing users, this app update features miscellaneous bug fixes and updates. For new users, in order to enhance the security of the device, users will be required to create a unique system password to set up the system." My thought is that the "secure" password is being used to encrypt the connection. If that's the case, it's probably just a matter of time before they require all users to use a password and encrypt the connection. This would only affect new users for now.

Note that I am not using HOOBS as was mentioned in the original comment. This appears to be a general issue.

jcgorla-dev commented 4 years ago

Looks like the latest update to the LC7001 may have solved the JSON errors. My LC7001 is now running 4.1.2-7-gb79ba without any errors reported to the log!

sttomic commented 4 years ago

@jcgorla-dev, I am running the same firmware version and still have this problem. I think I always was running that version. It turns out that 4.1.2 is the iOS app version and 4.1.2-7-gb79ba is the firmware version on the hub. Did you do anything else to get it working? Is it working correctly with HomeKit now?

jcgorla-dev commented 4 years ago

Sorry to report it is back to reporting the same errors. I just see today v1.0.0 was posted. I'm using HOOBS, but it doesn't show the new version being available.

BarryValdost commented 4 years ago

I have a similar JSON parsing issue, but I am not using HOOBS. My LC7001, homebridge, and this plugin are running the latest version. Homebridge console log follows:

[9/20/2020, 14:45:06] [LC7001] Error on connection to LC7001. [9/20/2020, 14:45:06] [LC7001] Error: read ECONNRESET at TCP.onStreamRead (internal/stream_base_commons.js:205:27) { errno: 'ECONNRESET', code: 'ECONNRESET', syscall: 'read' } [9/20/2020, 14:45:06] [LC7001] Connection to LC7001 closed. [9/20/2020, 14:45:06] [LC7001] Reconnecting to LC7001. [9/20/2020, 14:45:06] [LC7001] Connection to LC7001 established. Error parsing JSON. SyntaxError: Unexpected token H in JSON at position 0 at JSON.parse () at Object. (/usr/local/lib/node_modules/homebridge-lc7001/lib/lc7001.js:273:34) at Array.forEach () at Object. (/usr/local/lib/node_modules/homebridge-lc7001/lib/lc7001.js:270:12) at Socket.emit (events.js:315:20) at addChunk (_stream_readable.js:295:12) at readableAddChunk (_stream_readable.js:267:11) at Socket.Readable.push (_stream_readable.js:212:10) at TCP.onStreamRead (internal/stream_base_commons.js:186:23) Buffer Contents: Hello V1 Error parsing JSON. SyntaxError: Unexpected token D in JSON at position 1 at JSON.parse () at Object. (/usr/local/lib/node_modules/homebridge-lc7001/lib/lc7001.js:273:34) at Array.forEach () at Object. (/usr/local/lib/node_modules/homebridge-lc7001/lib/lc7001.js:270:12) at Socket.emit (events.js:315:20) at addChunk (_stream_readable.js:295:12) at readableAddChunk (_stream_readable.js:267:11) at Socket.Readable.push (_stream_readable.js:212:10) at TCP.onStreamRead (internal/stream_base_commons.js:186:23) Buffer Contents: 0D65E10D6C9E46C29F53A1362820BD76 Error parsing JSON. SyntaxError: Unexpected token D in JSON at position 1

These messages loop infinitely. I'm unsure what to do about this. Any suggestions?

aep61 commented 4 years ago

I did some packet sniffing and it appears that when connecting, the LC first sends "Hello V1 <32 char hex> <12 char hex>", where the first string varies but the second is the same each time. The Legrand program responds with a 32 char hex result. Encrypted or hashed with saved device password is my guess. LC then responds with [OK]\lf\cr\lf\0 string. From then on it appears that everything else continues on in plain text with ReportSystemProperties etc.

sttomic commented 4 years ago

I did some packet sniffing and it appears that when connecting, the LC first sends "Hello V1 <32 char hex> <12 char hex>", where the first string varies but the second is the same each time. The Legrand program responds with a 32 char hex result. Encrypted or hashed with saved device password is my guess. LC then responds with [OK]\lf\cr\lf\0 string. From then on it appears that everything else continues on in plain text with ReportSystemProperties etc.

The second hex value in many cases is the LC7001 MAC address.

aep61 commented 4 years ago

It is the MAC address. Did a quick python script to pretend to be the LC and log a reply. MAC address is ignored and only first 23 of the 32 characters affect the reply.

jcgorla-dev commented 4 years ago

Upgraded today to HOOBS v3.2.8, and the JSON error persists. 10/21/2020, 4:33:51 PM [LC7001] Connecting to LC7001.... 10/21/2020, 4:33:51 PM [LC7001] Connection to LC7001 established. 10/21/2020, 4:33:51 PM [LC7001] Unable to parse JSON: Hello V1 10/21/2020, 4:33:54 PM [LC7001] Unable to parse JSON: BE8CC4CA127A3F9C3D4CF2A4D7C0EBE5 0026EC02EE11[INVALID] 10/21/2020, 4:33:57 PM [LC7001] Error on LC7001 connection: Error: read ECONNRESET 10/21/2020, 4:33:57 PM [LC7001] Connection to LC7001 closed due to error. Waiting 30 seconds to reconnect....

fsalum commented 4 years ago

Having the same issue here:

[10/21/2020, 6:46:45 PM] [LegrandHub] Connecting to LC7001....
[10/21/2020, 6:46:45 PM] [LegrandHub] Connection to LC7001 established.
[10/21/2020, 6:46:45 PM] [LegrandHub] Unable to parse JSON:
 Hello V1 
[10/21/2020, 6:46:48 PM] [LegrandHub] Unable to parse JSON:
 BB0BE0C34915674AA87554702486348A 0026EC02D64E[INVALID]
[10/21/2020, 6:46:51 PM] [LegrandHub] Error on LC7001 connection: Error: read ECONNRESET
[10/21/2020, 6:46:51 PM] [LegrandHub] Connection to LC7001 closed due to error. Waiting 30 seconds to reconnect....
aep61 commented 4 years ago

Unless someone figures out the handshake for the initial connection, we may be SOL. For example, if the password is "aaaaaaaa" and I send these strings pretending to be an LC7001 to the Legrand Light Control app, here is what gets returned:

sending: Hello V1 00000000000000000000000000000000 000000000000
received: "BBE791C8534BD8DFBC0F5AE57BB1027D"

sending: Hello V1 00000000000000000000000000000001 000000000000
received: "10F8EB44513AAAAA73D0A61E5A61407F"

sending: Hello V1 00000000000000000000000000000002 000000000000
received: "82AF567C204A02F6ABB071F84AE1D4AA"

etc.

The LC7001 sends a random 128 bit value, the app takes the value mixes in the password and returns a new (hashed?) string. The returned string is compared against the expected value and if it doesn't match, the controller drops the connection. I have emailed Legrand tech support on the faint hope they will provide the algorithm that they use to validate the password. Another option would be downgrade the firmware on the LC somehow.

fsalum commented 4 years ago

Hi guys,

I got from Legrand technical team the document explaining how the new authentication is done so we can fix the plugin. Since I'm short on time to work on the fix I hope any of you guys can take a look before me. There is also a doc explaining the API, with that I think we can go above and beyond using the LC7001 directly as well, some doors are open now :)

https://www.dropbox.com/sh/mof0fr2bqbfovv5/AAB4L7LNx6b3BqZvHwbV0HNka?dl=0

Felipe

aep61 commented 4 years ago

I got from Legrand technical team the document explaining how the new authentication is done so we can fix the plugin. Since I'm short on time to work on the fix I hope any of you guys can take a look before me. There is also a doc explaining the API, with that I think we can go above and beyond using the LC7001 directly as well, some doors are open now :)

Outstanding! Thanks Felipe.

jcgorla-dev commented 4 years ago

This is great news, and exactly what we need. I've read through both the security addendum and the ICD. They're pretty straight forward. The security addendum has all the details on the challenge protocol to login.

Thanks Felipe!

fsalum commented 4 years ago

Just made a proof of concept in python and got the authentication working.

$ python legrand.py
Socket Created
Socket Connected to LCM1.local on ip 192.168.1.112
Challenge: 049464DA7B188260344A659EAF0B9B22
Encrypted Response F1996FE3A5A2EEAF1672E3EB9A405BDD
[OK]

{"ID":0,"Service":"ping","CurrentTime":1605073644,"PingSeq":1,"Status":"Success"}

I just don't know how to port it to javascript as my JS knowledge is close to none :)

jcgorla-dev commented 4 years ago

Do we know in which source file the challenge/handshake occurs? I looked through the code, but haven't found it yet.

fsalum commented 4 years ago

In case somebody wants to take a look in the authentication code in python I put it here: https://github.com/fsalum/legrand-lc7001/blob/main/legrand.py

Basically I get the challenge key from the Hello message, encrypt it with AES 128 using the MD5 of my LC7001 user password and the result is sent back to the Hub.

aep61 commented 4 years ago

Don't really know JavaScript but it looks like when the connection comes up (see lc7001.ts:118-120 interface.on('ready'), it currently sends the command to get the initial info from the LC. This is the old behaviour. Instead, the code would first need to check if there is an incoming message after connecting. If the message starts with "Hello V1", get the challenge hex string, generate the response, and wait for "[OK]" before carrying on the same as before by sending cmdGetSystemInfo(). Anyone know the JavaScript library/functions for MD5 and AES128.ECB available?

aep61 commented 4 years ago

The code to check for "Hello V1" looks like it would need to be in processBuffer() before it tries to JSON the data.

fsalum commented 4 years ago

Is @sbozarth still active in developing this plugin?

sbozarth commented 4 years ago

I am. Was not aware there was a whole issue thread going on GitHub. (Guess I have notifications off?)

I might be able to go read the thread later today.

On Nov 13, 2020, at 8:25 AM, Felipe Salum notifications@github.com wrote:

 Is @sbozarth still active in developing this plugin?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

sbozarth commented 4 years ago

So, it looks like starting 2020-01-01, changes were made to require authentication of some kind. My person system is “non-compliant” because I added devices prior to 2020-01-01. Thus, my personal system does not require authentication and I had no idea about this.

I will take a look at the Python script linked above and see if I can recreate in TS/JS. I’m not really jazzed to turn authentication on for my personal system. Does anyone want to volunteer to test?

aep61 commented 4 years ago

Sure.

jcgorla-dev commented 4 years ago

I'd be happy to help test.

fsalum commented 4 years ago

Should we keep the issue open for testing ?

jcgorla-dev commented 4 years ago

My bad, closed it by mistake.

sbozarth commented 4 years ago

Okay, I have created a new branch "1.1.x" containing my first crack at coding the authentication portion.

I am flying blind with absolutely no way to test this, and I really do not want to break my setup at this moment. For testing purposes, you may wish to uncomment this line (145) from lib/lc7001.js:

//this.platform.log.debug('Using password hash:',this.passwordHash.toString('hex').toUpperCase());

I did a few tests using examples from @aep61. Using password "aaaaaaaa" I received the following:

Challenge: 00000000000000000000000000000000 Password hash: 3DBE00A167653A1AAEE01D93E77E730E Answer: CF2A47F5DA9ACD35AD8C93578FED25CB

Challenge: 00000000000000000000000000000001 Password hash: 3DBE00A167653A1AAEE01D93E77E730E Answer: 2A5E276CE949E0DD456B80C1F0C467C2

Challenge: 00000000000000000000000000000002 Password hash: 3DBE00A167653A1AAEE01D93E77E730E Answer: BCE5F93835B5FA7BEC1D652B40B4B629

This clearly does not match, but I cannot troubleshoot more without knowing the hash @aep61 got (or that "aaaaaaaa" was not actually the password).

Same problem with the example from @fsalum: Without the password, I cannot reproduce.

@fsalum, can you provide me with a confirmed:

1) password 2) hash of password 3) challenge 4) correct answer

I can then check my use of the cryptographic functions.

fsalum commented 4 years ago

@sbozarth

my LC7001 password is 12345678

$ python legrand.py
Socket Created
Socket Connected to LCM1.local on ip 192.168.1.112
Challenge: 680CFDC8257A174606198DE7AB0CC282
Password MD5 25d55ad283aa400af464c76d713c07ad
Encrypted Response 8EA25157CD5BC8A41671A7F391FE87C3
[OK]

{"ID":0,"Service":"ping","CurrentTime":1605321209,"PingSeq":1,"Status":"Success"}{"ID":0,"Service":"ping","CurrentTime":1605321214,"PingSeq":2,"Status":"Success"}{"ID":0,"Service":"ping","CurrentTime":1605321219,"PingSeq":3,"Status":"Success"}
sbozarth commented 4 years ago

My results:

[LC7001] Using challenge: 680CFDC8257A174606198DE7AB0CC282 [LC7001] Using password hash: 25D55AD283AA400AF464C76D713C07AD [LC7001] Answer generated: 8EA25157CD5BC8A41671A7F391FE87C3

We have a match! The cyrpto calls work. They are dependent on Node.js crypto module, which is itself apparently dependent on OpenSSL. Some Node.js implementations are compiled without crypto support. I did not test for any of that.

Hopefully someone can test this code with an authentication-enabled LC7001.

aep61 commented 4 years ago

The regular expression doesn't seem to match. I added some code

            this.platform.log.error('Raw:', data);
            this.platform.log.error('Equal:', /Hello V1/.test(data));
            this.platform.log.error('Equal1:', /Hello V1 [0-9A-F]{32} [0-9A-F]{12}/.test(data));
            this.platform.log.error('Equal2:', /^Hello V1 [0-9A-F]{32} [0-9A-F]{12}/.test(data));

Here's the log

11/13/2020, 9:07:20 PM [LC7001] Data received from LC7001 (stringified): "Hello V1 \u0000480B4489DDBBA926A5D604DF0C0054DA 0026EC02F57E" 11/13/2020, 9:07:20 PM [LC7001] Raw: Hello V1 480B4489DDBBA926A5D604DF0C0054DA 0026EC02F57E 11/13/2020, 9:07:20 PM [LC7001] Equal: true 11/13/2020, 9:07:20 PM [LC7001] Equal1: false 11/13/2020, 9:07:20 PM [LC7001] Equal2: false

aep61 commented 4 years ago

Also, note that sometimes the Hello string comes in separate packets so they need to be merged. Also, if I use the simplest match for 'Hello V1', it fails to generate an answer string

[LC7001] Raw: Hello V1 4982273C6C9928E06A61075B7AED0B3B 0026EC02F57E 11/13/2020, 9:39:11 PM [LC7001] Equal: true 11/13/2020, 9:39:11 PM [LC7001] Equal1: false 11/13/2020, 9:39:11 PM [LC7001] Equal2: false 11/13/2020, 9:39:11 PM [LC7001] splitData: [ 'Hello', 'V1', '\u00004982273C6C9928E06A61075B7AED0B3B', '0026EC02F57E' ] 11/13/2020, 9:39:11 PM [LC7001] LC7001 has sent an authentication challenge: 4982273C6C9928E06A61075B7AED0B3B 11/13/2020, 9:39:11 PM [LC7001] answerCipher: Cipheriv { _decoder: null, _options: undefined, [Symbol(kHandle)]: {} } 11/13/2020, 9:39:11 PM [LC7001] Hash: <Buffer 81 02 47 41 90 84 c8 2d 03 80 9f c8 86 fe da ad> 11/13/2020, 9:39:11 PM [LC7001] challenge: 11/13/2020, 9:39:11 PM [LC7001] Answer:

aep61 commented 4 years ago

I was looking a the incoming packets and it appears that the data sent includes a NULL character (\u0000) after the V1. You need to trim() that off before sending the challenge. This regexp matches: /^Hello V1 \u0000[0-9A-F]{32} [0-9A-F]{12}/

sbozarth commented 4 years ago

\u0000 is the delimiter. This was not mentioned in the documentation, but easily handled as I am already splitting the buffer at the delimiter.

Can you give me any idea how the challenge gets split across packets? If 'Hello V1 ' is in one packet and the hex in another, that is not a problem. If the 'Hello V1 ' or hex is split....that's going to be a pain.

aep61 commented 4 years ago

It looks like it can be delivered split up in different ways depending on timing, based on when you ask for the data. I have seen all 3 cases:

Data received from LC7001 (stringified): "Hello V1 \u0000610D37B3AF8DE6BD9A8F711D9ECF02F8 0026EC02F57E"

Data received from LC7001 (stringified): "Hello V1 \u0000" Data received from LC7001 (stringified): "6573619582EB3747" Data received from LC7001 (stringified): "238225D133D7B025 0026EC02F57E"

[LC7001] Data received from LC7001 (stringified): "Hello V1 \u0000" [LC7001] Data received from LC7001 (stringified): "8AA4FF85A26247D4" [LC7001] Data received from LC7001 (stringified): "B37F3FA90EB4F304" [LC7001] Data received from LC7001 (stringified): " 0026EC02F57E"

Looks like you'll have to check the length and fetch new data until the string is long enough.

aep61 commented 4 years ago

Also don't know why Buffer.from(splitData[2], 'hex') generates an empty buffer.

sbozarth commented 4 years ago

Probably because it has the leading \u0000. That is not a hex character, so it cannot generate a clean binary buffer.

If you simply removed the \u0000 it would probably work fine.....as long as it came in one full packet.

aep61 commented 4 years ago

Yup. I thought trim() would get it but it doesn't. substring(1) fixes it. Now it generates the correct reply but it's still returning [INVALID]. The string sent can't include a termination byte. Don't know if this.interface.write(answer, 'ascii'); does that.

fsalum commented 4 years ago

@sbozarth how do I install your branch into my homebridge for testing? Can you maybe generate a package to install via homebridge?

Also are you planning to add a config via the homebridge UI so we can set our own passwords?

Looking forward to use this plugin :)

fsalum commented 4 years ago

By the way in all my tests I never get a split Hello message from LC7001. It always came at once.

sbozarth commented 4 years ago

I did a config for Homebridge UI. I even added the password field. Do you not see it? Most of that was part of 1.0.x.

Getting the branch for testing..... That's a more complicated matter. I am not proficient in git, so don't blame me if this is not correct.

You'd do a git pull to retrieve the repository. You'd do a git checkout 1.1.x to switch to the 1.1.x branch. Then you'd do a "npm link" in the root of my project to have npm link the 1.1.0 version rather than install it.

If you are on Windows, I don't know if any of that works.

When you are done, you npm unlink in the root of the project to return to the installed version.

aep61 commented 4 years ago

The split seems to happen after the first failed attempt to connect.

On Nov 13, 2020, at 11:37 PM, Felipe Salum notifications@github.com wrote:

By the way in all my tests I never get a split Hello message from LC7001. It always came at once.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sbozarth/homebridge-lc7001/issues/7#issuecomment-727161127, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARHDS2GGHXSLG6FSOMTXPV3SPYXR3ANCNFSM4N5TNPYQ.

sbozarth commented 4 years ago

this.interface.write(answer, 'ascii') should not send a termination byte.

When sending JSON commands, I build the command and add the \u0000 delimiter at the end. I then send that string the same way I am sending "answer". So, since I do not add the termination byte to "answer", it should not send it.

I do see where the python script that @fsalum sent picked up on the incoming \u0000, but I do not see him adding anything to the outgoing string.

I don't suppose you can packet sniff it?

fsalum commented 4 years ago

Correct I had to clean the \u0000 from the Hello message but you don’t need to add anything to the challenge answer just the Ascii hex.

I will test the npm link tomorrow. Thanks for working on the fix. 🤞🏻

On Fri, Nov 13, 2020 at 11:59 PM sbozarth notifications@github.com wrote:

this.interface.write(answer, 'ascii') should not send a termination byte.

When sending JSON commands, I build the command and add the \u0000 delimiter at the end. I then send that string the same way I am sending "answer". So, since I do not add the termination byte to "answer", it should not send it.

I do see where the python script that @fsalum https://github.com/fsalum sent picked up on the incoming \u0000, but I do not see him adding anything to the outgoing string.

I don't suppose you can packet sniff it?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sbozarth/homebridge-lc7001/issues/7#issuecomment-727163302, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMBOO2LXE6G2AV5OX6VESDSPY2EPANCNFSM4N5TNPYQ .

-- Sent from Gmail Mobile

sbozarth commented 4 years ago

I made a lot of changes to the processBuffer function to try to deal with split authentication messages. I now blindly prepend any carryover from the previous data received. I doubt there was really ever anything in there, but I used to check if the new data was complete without it and then only prepend if it was not. Now it is just blindly doing it and we will see what happens.

This was committed to the 1.1.x branch.

If the LC7001 is giving an [INVALID] ....

I literally print exactly what it sends in the log. You can try changing this line

this.platform.log.debug('Answer generated:',answer);

to

this.platform.log.debug('Answer generated:',JSON.stringify(answer));

That will uncover any hidden characters.