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
128 stars 69 forks source link

PD responds with own address instead of broadcast address when replying to a broadcast. #143

Closed Sympatron closed 7 months ago

Sympatron commented 7 months ago

Describe the bug Currently a PD responds with it's own address when responding to a broadcast.

Expected behavior The spec says this:

Address 0x7F is reserved as a special "BROADCAST" address that each PD will accept and respond to, just as if it matched its communication address. The reply message will use 0x7F plus the reply flag (0x7F+0x80=0xFF) in its address field. Since each PD will respond to 0x7F, the use of the broadcast address should be limited to controlled (single PD) configurations.

Additional context Here the reply address is set to the device address unconditionally: https://github.com/goToMain/libosdp/blob/af47df7d46f081df17bd41f729dd3bc887a375f1/src/osdp_phy.c#L181-L181

The problem ist that you have no reference to the original request at this point, so I don't know how to fix this nicely. My workaround is to hack something into pd_send_reply() but this is quite hacky and I don't like it:

static int pd_send_reply(struct osdp_pd *pd)
{
    int ret, packet_buf_size = get_tx_buf_size(pd);

    uint8_t req_addr = pd->packet_buf[1];

    /* init packet buf with header */
    ret = osdp_phy_packet_init(pd, pd->packet_buf, packet_buf_size);
    if (ret < 0) {
        return OSDP_PD_ERR_GENERIC;
    }
    if (is_pd_mode(pd)) {
        // reply to broadcasts with broadcast address
        if (req_addr == 0x7f) pd->packet_buf[2] |= 0x7f;
    }
    // ...
}
sidcha commented 7 months ago

Indeed, thanks for reporting this issue. Fixed now.

sidcha commented 7 months ago

Also available from stable branch v2.4.x if you are not ready for all the fancy changes in latest master :)