diff --git a/include/osdp.h b/include/osdp.h index 3f2aa527..1c82f593 100644 --- a/include/osdp.h +++ b/include/osdp.h @@ -997,6 +997,9 @@ const char *osdp_get_source_info(); /** * @brief Get a bit mask of number of PD that are online currently. + * When calling this function as a PD, only the first bit is valid. + * If the PD has not received a message from the CP recently, + * the status will be 0. * * @param ctx OSDP context * @param bitmask pointer to an array of bytes. must be as large as @@ -1007,6 +1010,7 @@ void osdp_get_status_mask(osdp_t *ctx, uint8_t *bitmask); /** * @brief Get a bit mask of number of PD that are online and have an active * secure channel currently. + * When calling this function as a PD, only the first bit is valid. * * @param ctx OSDP context * @param bitmask pointer to an array of bytes. must be as large as diff --git a/src/osdp_common.c b/src/osdp_common.c index 054c1860..c09532c9 100644 --- a/src/osdp_common.c +++ b/src/osdp_common.c @@ -265,8 +265,7 @@ void osdp_get_status_mask(osdp_t *ctx, uint8_t *bitmask) *mask = 0; } pd = osdp_to_pd(ctx, i); - if (ISSET_FLAG(pd, PD_FLAG_PD_MODE) || - pd->state == OSDP_CP_STATE_ONLINE) { + if (pd->state == OSDP_CP_STATE_ONLINE) { *mask |= 1 << pos; } } diff --git a/src/osdp_common.h b/src/osdp_common.h index 4f0ee07e..227dd6f2 100644 --- a/src/osdp_common.h +++ b/src/osdp_common.h @@ -304,12 +304,13 @@ struct osdp_pd { /* PD Capability; Those received from app + implicit capabilities */ struct osdp_pd_cap cap[OSDP_PD_CAP_SENTINEL]; - int state; /* FSM state (CP mode only) */ + int state; /* FSM state */ int phy_state; /* phy layer FSM state (CP mode only) */ uint32_t wait_ms; /* wait time in MS to retry communication */ int64_t tstamp; /* Last POLL command issued time in ticks */ int64_t sc_tstamp; /* Last received secure reply time in ticks */ int64_t phy_tstamp; /* Time in ticks since command was sent */ + int64_t rx_tstamp; /* Last time we rx a message in ticks */ uint16_t peer_rx_size; /* Receive buffer size of the peer PD/CP */ diff --git a/src/osdp_config.h.in b/src/osdp_config.h.in index d37eed44..171f9530 100644 --- a/src/osdp_config.h.in +++ b/src/osdp_config.h.in @@ -25,6 +25,7 @@ #define OSDP_PD_SC_RETRY_MS (600 * 1000) #define OSDP_PD_POLL_TIMEOUT_MS (50) #define OSDP_PD_SC_TIMEOUT_MS (800) +#define OSDP_PD_RX_TIMEOUT_MS (800) #define OSDP_RESP_TOUT_MS (200) #define OSDP_ONLINE_RETRY_WAIT_MAX_MS (300 * 1000) #define OSDP_CMD_RETRY_WAIT_MS (300) diff --git a/src/osdp_pd.c b/src/osdp_pd.c index 3e1f365f..11a01855 100644 --- a/src/osdp_pd.c +++ b/src/osdp_pd.c @@ -289,6 +289,8 @@ static int pd_decode_command(struct osdp_pd *pd, uint8_t *buf, int len) if (len != CMD_POLL_DATA_LEN) { break; } + pd->rx_tstamp = osdp_millis_now(); + pd->state = OSDP_CP_STATE_ONLINE; /* Check if we have external events in the queue */ if (pd_event_dequeue(pd, &event) == 0) { ret = pd_translate_event(pd, event); @@ -989,6 +991,16 @@ static void osdp_pd_update(struct osdp_pd *pd) osdp_millis_since(pd->sc_tstamp) > OSDP_PD_SC_TIMEOUT_MS) { LOG_INF("PD SC session timeout!"); sc_deactivate(pd); + pd->state = OSDP_CP_STATE_OFFLINE; + } + + /** + * Check if the session is valid(e.g. we have received a message in the recent past) + */ + if (pd->state == OSDP_CP_STATE_ONLINE && + osdp_millis_since(pd->rx_tstamp) > OSDP_PD_RX_TIMEOUT_MS) { + LOG_INF("PD session timeout!"); + pd->state = OSDP_CP_STATE_OFFLINE; } ret = pd_receive_and_process_command(pd); @@ -1094,6 +1106,7 @@ osdp_t *osdp_pd_setup(osdp_pd_info_t *info) pd->address = info->address; pd->flags = info->flags; pd->seq_number = -1; + pd->state = OSDP_CP_STATE_OFFLINE; memcpy(&pd->channel, &info->channel, sizeof(struct osdp_channel)); logger_get_default(&pd->logger);