goToMain / libosdp

Implementation of IEC 60839-11-5 OSDP (Open Supervised Device Protocol); provides a C library with support for C++, Rust and Python3
https://libosdp.sidcha.dev
Apache License 2.0
130 stars 69 forks source link

OSDP phy packet parse error "Invalid SOM 0xff" #84

Closed sidcha closed 2 years ago

sidcha commented 2 years ago

Cross posting issue reported by email:

Hello Siddharth,

We have been using libosdp for a while now and are very pleased with how it performs, so thank you for that.

We are having issues connecting to a Mercury panel and I wanted to share my findings with you.

With libosdp configured as a PD, it fails to connect to the panel and I get the following debug trace:

GLOBAL:
config_file: /home/default/osdp_pd_settings.cfg
mode: 2
conn_topology: 0
num_pd: 1
conf_pd_mapr: 08000000

PD-0:
channel_speed: 9600
channel_type: 1
channel_device: /dev/ttyS3
address: 1
scbk: 00000000000000000000000000000000

capabilities:
     FC-01 contact_status_monitoring -- [ 1, 0, 0 ]
     FC-02 output_control -- [ 2, 0, 0 ]
     FC-03 card_data_format -- [ 3, 1, 0 ]
     FC-04 reader_led_control -- [ 4, 0, 0 ]
     FC-05 reader_audible_control -- [ 5, 0, 0 ]
     FC-06 reader_text_output -- [ 6, 0, 0 ]
     FC-07 time_keeping -- [ 7, 0, 0 ]
     FC-08 check_character_support -- [ 8, 1, 0 ]
     FC-09 communication_security -- [ 9, 1, 1 ]
     FC-10 receive_buffersize -- [ 10, 0, 2 ]
     FC-11 largest_combined_message_size -- [ 11, 0, 16 ]
     FC-12 smart_card_support -- [ 12, 0, 0 ]
     FC-255 (null) -- [ 255, 0, 0 ]
version: 1
model: 1
vendor_code: 12578750
serial_number: 0xbfe51775
firmware_version: 17085696
osdp: PD: WARN : PD1: SCBK not provided. PD is in INSTALL_MODE 
osdp: PD: INFO : PD1: Setup complete - libosdp-2.1.0 HEAD (v2.1.0)
osdp: PD: DEBUG: PD1: CMD: ID(61) REPLY: PDID(45)
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PD: DEBUG: PD1: CMD: CAP(62) REPLY: PDCAP(46)
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PD: DEBUG: PD1: CAP check: LED(1) > cap->num_items(0)
osdp: PD: INFO : PD1: PD is not capable of handling CMD: LED(69); Reply with NAK_CMD_UNKNOWN
osdp: PD: DEBUG: PD1: CMD: LED(69) REPLY: NAK(41)
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PD: DEBUG: PD1: CMD: LSTAT(64) REPLY: LSTATR(48)
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PD: DEBUG: PD1: CMD: RSTAT(67) REPLY: RSTATR(4b)
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PD: DEBUG: PD1: CMD: ACURXSIZE(7b) REPLY: ACK(40)
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2
osdp: PHY: ERROR: PD1: Invalid SOM 0xff
osdp: PD: ERROR: PD1: CMD receive error/timeout - err:-2

Looking at the raw messages received by the PD on the UART, I am getting the following at 9600 and 115200:

Panel 9600:

RX[10]: ff 53 01 08 00 00 61 00 43 ff

Panel 115200:

RX[34]: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 53 01 09 00 04 61 00 60 23 fe

So issue 1 is there are multiple leading 0xff bytes and issue 2 is there is a trailing 0xff byte (or 0xfe at 115200)

The libosdp error messages look to be coming from osdp_phy_check_packet where only the first byte is checked to be 0xff and the next byte is assumed to be the SOM.

Would it make sense to have a while loop there instead, and drop all leading bytes until the SOM byte is found?

Regards, Rob

thecapn32 commented 2 years ago

I faced this problem in the beginning! "Would it make sense to have a while loop there instead, and drop all leading bytes until the SOM byte is found?" this is how I get the message in esp32! because you have to read whatever it's available from the uart buffer , I drop everything till I reach ff 53 and store it in a buffer according to the size that is provided by the higher function!

sidcha commented 2 years ago

Would it make sense to have a while loop there instead, and drop all leading bytes until the SOM byte is found?

Certainly. I just never had to face this situation before. Do you know why the CP flooding the RX buffer with FFs? It has to actively pull the line low to do this (so its no accident).

(or 0xfe at 115200)

Even if we workaround the issue above, this is problematic. This current packet will be fine, but the next one would be dropped.

rsgmodelworks commented 2 years ago

The mercury panel is not flooding the line. It sends two 0xFF frames. It is expected (and many other PD's) that your packet detection logic looks for the SOM to start a packet. You should not be looking for 0xFF 0x53.

sidcha commented 2 years ago

It sends two 0xFF frames. It is expected (and many other PD's) that your packet detection logic looks for the SOM to start a packet.

@rsgmodelworks, I agreed on the look for FF 53 for start of packet part. I do see a lot more than 2 0xFF in the 115200 capture sample. And there is also the tailing 0xFE which tells me something is amiss.

sidcha commented 2 years ago

Based on assessment, to correctly deal with this situation, a bit of rework is needed around how we manage the RX buffers altogether (it needs to become a circular buffer).

It would also mean we can get rid of memmove that we do after we are done processing the bytes which should speed things up quite a bit. :)

sidcha commented 2 years ago

Now LibOSDP will discard any number of leading mark bytes (and any other junk till it finds the SOM). It also extracts exactly one packet from the RX buffer so the tailing fe should be discarded as junk before processing the next packet.

This should resolve this ticket; feel free to reopen if it doesn't work.