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
134 stars 71 forks source link

Multiple PD’s in a single piece of code #69

Closed vk2tds closed 3 years ago

vk2tds commented 3 years ago

The basic issue is that I am wanting to write some code that interfaces to an alarm system with an OSDP bus, and have my code implement four PD’s. As far as I can tell, all the code assumes a single PD per instance.

Running multiple instances of the code, or using multiple instances of the library could work I guess but I am assuming this would involve ‘connections’ to the serial port which depending on platform would be exclusive to a single connection.

Assuming this is an enhancement, I am not sure what the cleanest way to implement this would be. Thanks.

sidcha commented 3 years ago

Each PD is tied to a osdp_t *ctx object; no part of LibOSDP assumes a single PD (except for the log level). So you are free to do,

#define NUM_PDS 4

osdp_t *pd_ctx[NUM_PDS];

for (i = 0; i < NUM_PDS; i++) {
    pd_ctx[i] = osdp_pd_setup();
}

As a side benefit to this, if you have distinct channels for each PD, then you can run each PD in a separate thread.

vk2tds commented 3 years ago

Thanks for this. As soon as I get the hardware I will check this out.

vk2tds commented 3 years ago

I am still coming up to speed with the library, and I am having some issues with the how to set up the physical layer. I am probably going to want to write my PD code for Zephyr, but it might be Linux. Regardless, I really cannot work out how to extend the base C example PD code to interface to the hardware.

I am guessing this will need, in the case of a UART, to reference channel_open(), channel_read() and others. It will also need to reference setting up the pd_send and pd_recv functions.

I also went looking for the c-utils documentation, but the c-utils link on the page to documentation points to https://c-utils.gotomain.io/ which is 404.

Once again, thanks for your help.

sidcha commented 3 years ago

I am probably going to want to write my PD code for Zephyr

There is already a port of this library on Zephyr RTOS upstream. It has not received much attention lately but still fully functional.

I really cannot work out how to extend the base C example PD code to interface to the hardware.

If you are using Linux, you can use the python bindings or the included OSDPCtl tool to setup your PD. If it is Zephyr, physical layer is already implemented for you. For some other platform (or if you want to integrate LibOSDP to your own Linux application) see #40 for some tips.

sidcha commented 3 years ago

I also went looking for the c-utils documentation, but the c-utils link on the page to documentation points to https://c-utils.gotomain.io/ which is 404.

This is expected. Long back, I was about to setup a documentation page for it but got distracted. In that land code is the best documentation.

vk2tds commented 3 years ago

Thanks for this. I will definitely check out Zephyr - it looks like an interesting project. It looks like it will do most of what I need.

vk2tds commented 2 years ago

As a first pass, I have been working on compiling libospd for the STM32 Nucleo 64 using the Arduino toolchain with some degree of success as a PD. It is compiling and running, but alas, is not actually working. I am still working through where the issue is. My code is likely the issue in there as the existing device on the OSDP bus on my InnerRange alarm is going offline with some regularity when my code is running.

That as it is, I have an update to the pd_receive_and_process_command() function in ospd.c. What I have found, at least in my toolchain, is that often there are multiple packets in the buffer that need to be processed. This code appears to correctly extract them. I am not saying this is perfect, but it is seeming to work at the moment.

I have also found a case where I get the following bitstream 0xFF 0x53 0x00 0xFF 0x53 and things stall until there is a timeout. I have a fix for this but suspect I have another underlying bug to work on.

As soon as I get something running I will release the code. It is SOOOO close. Thanks.


    do {
        err = pd_decode_packet(pd, &len);
        if (err == OSDP_PD_ERR_NO_DATA) 
            break;
        LOG_ERR ("Removing %d bytes from buffer with len %d err %lx", len, pd->rx_buf_len, err);
        if (pd->rx_buf_len >= 6){
            if ((pd->rx_buf[0]==0xff) && (pd->rx_buf[1]==0x53)){
                LOG_ERR ("...Address=%d LEN=%d MCI=%x", pd->rx_buf[2], pd->rx_buf[3] + (256*pd->rx_buf[4]), pd->rx_buf[5]);
            }
        }
        /* We are done with the packet (error or not). Remove processed bytes */
        remaining = pd->rx_buf_len - len;
        if (remaining > 0) {
            memmove(pd->rx_buf, pd->rx_buf + len, remaining);
        }

        /**
         * Store remaining length that needs to be processed.
         * State machine will be updated accordingly.
         */
        pd->rx_buf_len = remaining;
    //} while ( (err != 0xffffffff) && (err != 0xfffffffe));
    //} while ( (pd->rx_buf_len > 0) && (err != OSDP_ERR_PKT_WAIT) && (err != OSDP_ERR_PKT_FMT));
    } while ( (pd->rx_buf_len > 0) && (err != OSDP_ERR_PKT_WAIT) );

Just for information, where I am up to at the moment is that keys are exchanged, then we get CMD: ID(61) and send REPLY: PDID(45). Soon after that I get errors for sequence repeat and soon the devices attempt to handshake again. I will let you know as soon as I get anywhere.


OSDP: WARN : PD[14]: PD: SCBK not provided. PD is in INSTALL_MODE
OSDP: PD: Setup complete - @PROJECT_NAME@-@PROJECT_VERSION@ @GIT_BRANCH@ (@GIT_TAG@)
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 05 09 00 04 62                              |.S....b         |
OSDP: PD[14]: Received pd_receive_and_process_command [a] =>
    0000  ff 53 05 09 00 04 62 00  92 70                    |.S....b..p      |
OSDP: ERROR: PD[14]: PD: Removing 10 bytes from buffer with len 10 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=5 LEN=9 MCI=4
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 0c 09 00 04 62                              |.S....b         |
OSDP: PD[14]: Received pd_receive_and_process_command [a] =>
    0000  ff 53 0c 09 00 04 62 00  70 38                    |.S....b.p8      |
OSDP: ERROR: PD[14]: PD: Removing 10 bytes from buffer with len 10 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=12 LEN=9 MCI=4
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 0e 09 00 04 62                              |.S....b         |
OSDP: PD[14]: Received pd_receive_and_process_command [a] =>
    0000  ff 53 0e 09 00 04 62 00  30 b3                    |.S....b.0.      |
OSDP: ERROR: PD[14]: PHY: None vk2tds
OSDP: CMD: CAP(62) [1] =>
    0000  62                                                |b               |
OSDP: DEBUG: PD[14]: PD: CMD: CAP(62) REPLY: PDCAP(46)
OSDP: ERROR: PD[14]: PD: Removing 10 bytes from buffer with len 10 err 0
OSDP: ERROR: PD[14]: PD: ...Address=14 LEN=9 MCI=4
OSDP: REPLY: PDCAP(46) [1b] =>
    0000  01 01 01 02 01 01 03 02  01 04 01 01 05 01 01 08  |................|
    0010  01 00 09 01 00 0a 00 02  0d 01 01                 |...........     |
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 0e 13 00 0d 03                              |.S.....         |
OSDP: PD[14]: Received pd_receive_and_process_command [14] =>
    0000  ff 53 0e 13 00 0d 03 11  00 76 a1 56 8b 5e a9 c3  |.S.......v.V.^..|
    0010  c9 10 34 35                                       |..45            |
OSDP: ERROR: PD[14]: PHY: None vk2tds
OSDP: CMD: CHLNG(76) [8] =>
    0000  76 a1 56 8b 5e a9 c3 c9                           |v.V.^...        |
OSDP: DEBUG: PD[14]: PD: CMD: CHLNG(76) REPLY: CCRYPT(76)
OSDP: ERROR: PD[14]: PD: Removing 20 bytes from buffer with len 20 err 0
OSDP: ERROR: PD[14]: PD: ...Address=14 LEN=19 MCI=d
OSDP: REPLY: CCRYPT(76) [20] =>
    0000  71 fa af 00 8d 93 13 00  84 22 65 ee 44 fe 6e 1b  |q........"e.D.n.|
    0010  38 52 62 cc aa 19 f7 d9  77 12 34 0a 2e e7 9b 4f  |8Rb.....w.4....O|
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 0e 1b 00 0e 03                              |.S.....         |
OSDP: PD[14]: Received pd_receive_and_process_command [1c] =>
    0000  ff 53 0e 1b 00 0e 03 13  00 77 46 63 6f 0f 64 d5  |.S.......wFco.d.|
    0010  8f a3 c3 d7 a9 35 e5 94  fe a5 a0 f0              |.....5......    |
OSDP: ERROR: PD[14]: PHY: None vk2tds
OSDP: CMD: SCRYPT(77) [10] =>
    0000  77 46 63 6f 0f 64 d5 8f  a3 c3 d7 a9 35 e5 94 fe  |wFco.d......5...|
OSDP: DEBUG: PD[14]: PD: CMD: SCRYPT(77) REPLY: RMAC_I(78)
OSDP: ERROR: PD[14]: PD: Removing 28 bytes from buffer with len 28 err 0
OSDP: ERROR: PD[14]: PD: ...Address=14 LEN=27 MCI=e
OSDP: WARN : PD[14]: PD: SC Active with SCBK-D
OSDP: REPLY: RMAC_I(78) [10] =>
    0000  81 f7 1b 8f 81 9c 0d 98  76 9b 56 96 4e d3 7a 11  |........v.V.N.z.|
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 0f 09 00 04 62 00  90                       |.S....b..       |
OSDP: PD[14]: Received pd_receive_and_process_command [a] =>
    0000  ff 53 0f 09 00 04 62 00  90 f6                    |.S....b...      |
OSDP: ERROR: PD[14]: PD: Removing 10 bytes from buffer with len 10 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=15 LEN=9 MCI=4
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 01 09 00 04 62 00  33                       |.S....b.3       |
OSDP: PD[14]: Received pd_receive_and_process_command [a] =>
    0000  ff 53 01 09 00 04 62 00  33 76                    |.S....b.3v      |
OSDP: ERROR: PD[14]: PD: Removing 10 bytes from buffer with len 10 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=1 LEN=9 MCI=4
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 02 08 00 00 62 00  41                       |.S....b.A       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=2 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 0e 1e 00 0f 02 17  61                       |.S......a       |
OSDP: PD[14]: Received pd_receive_and_process_command [1f] =>
    0000  ff 53 0e 1e 00 0f 02 17  61 b2 b1 58 ca a0 0c e2  |.S......a..X....|
    0010  28 ec d3 9a bc 47 d3 e5  7b 39 35 6f 0e c7 91     |(....G..{95o... |
OSDP: ERROR: PD[14]: PHY: None vk2tds
OSDP: CMD: ID(61) [1] =>
    0000  61                                                |a               |
OSDP: DEBUG: PD[14]: PD: CMD: ID(61) REPLY: PDID(45)
OSDP: ERROR: PD[14]: PD: Removing 31 bytes from buffer with len 31 err 0
OSDP: ERROR: PD[14]: PD: ...Address=14 LEN=30 MCI=f
OSDP: REPLY: PDID(45) [c] =>
    0000  71 fa 19 af 02 8d 93 13  00 0a 0b 0c              |q...........    |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 0e 1e 00 0d 02 17  80                       |.S.......       |
OSDP: PD[14]: Received pd_receive_and_process_command [1f] =>
    0000  ff 53 0e 1e 00 0d 02 17  80 14 8a bd f8 3a 17 2c  |.S...........:.,|
    0010  c3 1a 45 e3 66 f0 d2 3a  46 30 2c f0 50 c3 82     |..E.f..:F0,.P.. |
OSDP: ERROR: PD[14]: PHY: None vk2tds
OSDP: CMD: MFG(80) [5] =>
    0000  80 00 11 b9 15                                    |.....           |
PD: CMD 7
OSDP: ERROR: PD[14]: PD: ...Address=14 LEN=30 MCI=d
OSDP: REPLY: ACK(40) [0] =>
    0000  00                                                |.               |
OSDP: PD[14]: Received pd_receive_and_process_command [3f] =>
    0000  ff 53 0e 1e 00 0d 02 17  80 14 8a bd f8 3a 17 2c  |.S...........:.,|
    0010  c3 1a 45 e3 66 f0 d2 3a  46 30 2c f0 50 c3 82 ff  |..E.f..:F0,.P...|
    0020  53 0e 1e 00 0d 02 17 80  14 8a bd f8 3a 17 2c c3  |S...........:.,.|
    0030  1a 45 e3 66 f0 d2 3a 46  30 2c f0 50 c3 82 ff     |.E.f..:F0,.P... |
OSDP: ERROR: PD[14]: PHY: osdp_phy_check_packet - seq-repeat/reply-resend not supported!
OSDP: ERROR: PD[14]: PD: Removing 31 bytes from buffer with len 63 err fffffffd
OSDP: ERROR: PD[14]: PD: ...Address=14 LEN=30 MCI=d
OSDP: ERROR: PD[14]: PHY: osdp_phy_check_packet - seq-repeat/reply-resend not supported!
OSDP: ERROR: PD[14]: PD: Removing 31 bytes from buffer with len 32 err fffffffd
OSDP: ERROR: PD[14]: PD: ...Address=14 LEN=30 MCI=d
OSDP: PD[14]: Received pd_receive_and_process_command [f] =>
    0000  ff ff 53 7f 0d 00 04 80  00 11 b9 00 00 86 8e     |..S............ |
OSDP: ERROR: PD[14]: PHY: osdp_phy_check_packet - Invalid SOM 0xff
OSDP: ERROR: PD[14]: PD: Removing 14 bytes from buffer with len 15 err fffffffe
OSDP: ERROR: PD[14]: PD: CMD receive error/timeout - err:-2
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 80 0c 00 04 40                              |.S....@         |
OSDP: PD[14]: Received pd_receive_and_process_command [d] =>
    0000  ff 53 80 0c 00 04 40 7b  63 0c 00 4a b1           |.S....@{c..J.   |
OSDP: ERROR: PD[14]: PD: Removing 13 bytes from buffer with len 13 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=128 LEN=12 MCI=4
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 03 08 00 00 62                              |.S....b         |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 03 08 00 00 62 00  40                       |.S....b.@       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=3 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 03 08 00 00 61                              |.S....a         |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 03 08 00 00 61 00  41                       |.S....a.A       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=3 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 03 08 00 00 61                              |.S....a         |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 03 08 00 00 61 00  41                       |.S....a.A       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=3 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 03 08 00 00 61                              |.S....a         |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 03 08 00 00 61 00  41                       |.S....a.A       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=3 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 03 08 00 00 61                              |.S....a         |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 03 08 00 00 61 00  41                       |.S....a.A       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=3 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 03 08 00 00 61                              |.S....a         |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 03 08 00 00 61 00  41                       |.S....a.A       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=3 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 03 08 00 00 61                              |.S....a         |
OSDP: PD[14]: Received pd_receive_and_process_command [9] =>
    0000  ff 53 03 08 00 00 61 00  41                       |.S....a.A       |
OSDP: ERROR: PD[14]: PD: Removing 9 bytes from buffer with len 9 err fffffffc
OSDP: ERROR: PD[14]: PD: ...Address=3 LEN=8 MCI=0
OSDP: PD[14]: Received pd_receive_and_process_command [7] =>
    0000  ff 53 06 09 00 04 62                              |.S....b         |
OSDP: PD[14]: Received pd_receive_and_process_command [a] =>
    0000  ff 53 06 09 00 04 62 00  72 be                    |.S....b.r.      |```
sidcha commented 2 years ago

I'm having a hard time understating the issue you are having :). I expect things to work as they are with modifications to build setup. If thats now what you are seeing, can you post me the logs as described here.

I have also found a case where I get the following bitstream 0xFF 0x53 0x00 0xFF 0x53 and things stall until there is a timeout.

This is expected. LibOSDP expects at least header length bytes in the buffer to start processing it. This is an acceptable tradeoff since these bytes will be flushed after the timeout or when more garbage data is received sooner.