elad-bar / DahuaVTO2MQTT

Listens to events from Dahua VTO unit and publishes them via MQTT Message
103 stars 39 forks source link

DahuaVTOClient doesn't handle packets larger than Ethernet frame. #37

Closed ToniRos closed 3 years ago

ToniRos commented 3 years ago

DahuaVTOClient extends class asyncio.BufferedProtocol(BaseProtocol) this in general is ok, but with larger than 1500 bytes packets produces error like: ERROR main Failed to read data: b' ..... , error: Unterminated string starting at: line 1 column 1397 (char 1396), Line: 323 ERROR main Failed to handle message, error: 'NoneType' object has no attribute 'get', Line: 170

I found the problem, you can change asyncio.BufferedProtocol(BaseProtocol) with class asyncio.BufferedProtocol(BaseProtocol) implement the buffer and create methods to handle the buffer: get_buffer and buffer_updated the code can be found in my fork https://github.com/ToniRos/DahuaVTO2MQTT.

NimlothPL commented 3 years ago

Hi Toni, nice fix - tested and works ... but I think that problem is not with packet larger than 1500 bytes.

Check this message: 2021-04-01 09:16:57,500 DEBUG __main__ Keep alive 2021-04-01 09:16:57,506 DEBUG __main__ Buffer Received, bytes: 103, Message b' \x00\x00\x00DHIP\xf7\x1c\*{\x05\x00\x00G\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00{"id":1403,"params":{"timeout":55},"result":true,"session":1453661431}\n' 2021-04-01 09:16:57,507 DEBUG __main__ Buffer Content, bytes: 103, Message bytearray(b' \x00\x00\x00DHIP\xf7\x1c\xa5V{\x05\x00\x00G\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00{"id":1403,"params":{"timeout":55},"result":true,"session":1453661431}\n') 2021-04-01 09:16:57,507 ERROR __main__ Failed to read data: bytearray(b' \x00\x00\x00DHIP\xf7\x1c\xa5V{\x05\x00\x00G\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00{"id":1403,"params":{"timeout":55},"result":true,"session":1453661431}\n'), error: Expecting property name enclosed in double quotes: line 1 column 2 (char 1), Line: 365 2021-04-01 09:16:57,507 DEBUG __main__ Data received: None 2021-04-01 09:16:57,507 ERROR __main__ Failed to handle message, error: 'NoneType' object has no attribute 'get', Line: 210

Of course this 1st message won't be processed due to "{" symbol in "x1c\xa5V{\x05" as it treats it as JSON opening ... next iteration will increase buffer ... until > 2200 will kick in and reset it. So fix is working, just not solving main issue.

Next message will be 103 bytes + 267 bytes: 2021-04-01 09:17:15,440 DEBUG __main__ Buffer Received, bytes: 267, Message b' \x00\x00\x00DHIP\xf7\x1c\xa5V\x03\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x00\x00{"id":3,"method":"client.notifyEventStream","params":{"SID":513,"eventList":[{"Action":"Pulse","Code":"SIPRegisterResult","Data":{"LocaleTime":"2021-04-01 11:17:15","Success":true,"UTC":1617272235.0},"Index":0}]},"session":1453661431}\n' 2021-04-01 09:17:15,441 DEBUG __main__ Buffer Content, bytes: 370, Message bytearray(b' \x00\x00\x00DHIP\xf7\x1c\xa5V{\x05\x00\x00G\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00{"id":1403,"params":{"timeout":55},"result":true,"session":1453661431}\n \x00\x00\x00DHIP\xf7\x1c\xa5V\x03\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x00\x00{"id":3,"method":"client.notifyEventStream","params":{"SID":513,"eventList":[{"Action":"Pulse","Code":"SIPRegisterResult","Data":{"LocaleTime":"2021-04-01 11:17:15","Success":true,"UTC":1617272235.0},"Index":0}]},"session":1453661431}\n') 2021-04-01 09:17:15,442 ERROR __main__ Failed to read data: bytearray(b' \x00\x00\x00DHIP\xf7\x1c\xa5V{\x05\x00\x00G\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00{"id":1403,"params":{"timeout":55},"result":true,"session":1453661431}\n \x00\x00\x00DHIP\xf7\x1c\xa5V\x03\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x00\x00{"id":3,"method":"client.notifyEventStream","params":{"SID":513,"eventList":[{"Action":"Pulse","Code":"SIPRegisterResult","Data":{"LocaleTime":"2021-04-01 11:17:15","Success":true,"UTC":1617272235.0},"Index":0}]},"session":1453661431}\n'), error: Expecting property name enclosed in double quotes: line 1 column 2 (char 1), Line: 365 2021-04-01 09:17:15,442 DEBUG __main__ Data received: None 2021-04-01 09:17:15,442 ERROR __main__ Failed to handle message, error: 'NoneType' object has no attribute 'get', Line: 210 and so on

ToniRos commented 3 years ago

Yes is correct, I'm working in improve the fix, but at the moment i'm using your code, it only fails in the first connection, and the rest works Ok. My first solution with BufferProtocol also doesn't worked.