From 1d2868eba6522cd7d4072908d42f034a7953530e Mon Sep 17 00:00:00 2001 From: Nicholas Hahn Date: Wed, 13 Nov 2024 18:18:12 -0300 Subject: [PATCH] Add support to include CP after the initial configuration. --- include/osdp.h | 13 +++++++++ include/osdp.hpp | 5 ++++ src/osdp_cp.c | 75 +++++++++++++++++++++++++++++++----------------- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/include/osdp.h b/include/osdp.h index 9992ee9..3ccf102 100644 --- a/include/osdp.h +++ b/include/osdp.h @@ -1049,6 +1049,19 @@ void osdp_cp_teardown(osdp_t *ctx); OSDP_EXPORT int osdp_cp_send_command(osdp_t *ctx, int pd, const struct osdp_cmd *cmd); +/** + * @brief Adds more PD devices in the CP control list. + * + * @param num_pd Number of PDs connected to this CP. The `osdp_pd_info_t *` is + * treated as an array of length num_pd. + * @param info Pointer to info struct populated by application. + * + * @retval 0 on success + * @retval -1 on failure + */ +OSDP_EXPORT +int osdp_cp_add_pd(osdp_t *ctx, int num_pd, const osdp_pd_info_t *info); + /** * @brief Deletes all commands queued for a give PD * diff --git a/include/osdp.hpp b/include/osdp.hpp index ffeb13d..592f9f7 100644 --- a/include/osdp.hpp +++ b/include/osdp.hpp @@ -76,6 +76,11 @@ class OSDP_EXPORT ControlPanel : public Common { return _ctx != nullptr; } + int add_pd(int num_pd, osdp_pd_info_t *info) + { + return osdp_cp_add_pd(_ctx, num_pd, info); + } + void refresh() { osdp_cp_refresh(_ctx); diff --git a/src/osdp_cp.c b/src/osdp_cp.c index 61edf62..ee5169c 100644 --- a/src/osdp_cp.c +++ b/src/osdp_cp.c @@ -1387,33 +1387,29 @@ static int cp_detect_connection_topology(struct osdp *ctx) return 0; } -static struct osdp *__cp_setup(int num_pd, const osdp_pd_info_t *info_list) +static int cp_add_pd(struct osdp *ctx, int new_num_pd, + const osdp_pd_info_t *new_info_list) { - int i; - struct osdp_pd *pd = NULL; - struct osdp *ctx; + int i, old_num_pd; + struct osdp_pd *new_pd_array, *pd; const osdp_pd_info_t *info; - char name[24] = {0}; + char name[24] = { 0 }; - ctx = calloc(1, sizeof(struct osdp)); - if (ctx == NULL) { - LOG_PRINT("Failed to allocate osdp context"); - return NULL; + old_num_pd = ctx->_num_pd; + new_pd_array = realloc(ctx->pd, sizeof(struct osdp_pd) * (old_num_pd + new_num_pd)); + if (new_pd_array == NULL) { + LOG_PRINT("Failed to allocate new osdp_pd[] context"); + return -1; } - input_check_init(ctx); + ctx->pd = new_pd_array; + ctx->_num_pd = old_num_pd + new_num_pd; + bzero(&ctx->pd[old_num_pd], sizeof(struct osdp_pd) * new_num_pd); - ctx->pd = calloc(1, sizeof(struct osdp_pd) * num_pd); - if (ctx->pd == NULL) { - LOG_PRINT("Failed to allocate osdp_pd[] context"); - goto error; - } - ctx->_num_pd = num_pd; - - for (i = 0; i < num_pd; i++) { - info = info_list + i; - pd = osdp_to_pd(ctx, i); - pd->idx = i; + for (i = 0; i < new_num_pd; i++) { + info = new_info_list + i; + pd = osdp_to_pd(ctx, old_num_pd + i); + pd->idx = old_num_pd + i; pd->osdp_ctx = ctx; if (info->name) { strncpy(pd->name, info->name, OSDP_PD_NAME_MAXLEN - 1); @@ -1433,10 +1429,10 @@ static struct osdp *__cp_setup(int num_pd, const osdp_pd_info_t *info_list) } else if (is_enforce_secure(pd)) { LOG_PRINT("SCBK must be passed for each PD when" " ENFORCE_SECURE is requested."); - goto error; + return -1; } if (cp_cmd_queue_init(pd)) { - goto error; + return -1; } if (IS_ENABLED(CONFIG_OSDP_SKIP_MARK_BYTE)) { SET_FLAG(pd, PD_FLAG_PKT_SKIP_MARK); @@ -1453,14 +1449,33 @@ static struct osdp *__cp_setup(int num_pd, const osdp_pd_info_t *info_list) if (cp_detect_connection_topology(ctx)) { LOG_PRINT("Failed to detect connection topology"); - goto error; + return -1; } SET_CURRENT_PD(ctx, 0); + return 0; +} + +static struct osdp *__cp_setup(int num_pd, const osdp_pd_info_t *info_list) +{ + struct osdp *ctx; + + ctx = calloc(1, sizeof(struct osdp)); + if (ctx == NULL) { + LOG_PRINT("Failed to allocate osdp context"); + return NULL; + } + + input_check_init(ctx); + + if (cp_add_pd(ctx, num_pd, info_list)) { + goto error; + } + LOG_PRINT("CP Setup complete; LibOSDP-%s %s NumPDs:%d Channels:%d", - osdp_get_version(), osdp_get_source_info(), - num_pd, ctx->num_channels); + osdp_get_version(), osdp_get_source_info(), num_pd, + ctx->num_channels); return ctx; error: @@ -1479,6 +1494,14 @@ osdp_t *osdp_cp_setup(int num_pd, const osdp_pd_info_t *info_list) return (osdp_t *)__cp_setup(num_pd, info_list); } +int osdp_cp_add_pd(osdp_t *ctx, int num_pd, const osdp_pd_info_t *info) +{ + assert(ctx); + assert(info); + + return cp_add_pd(ctx, num_pd, info); +} + void osdp_cp_teardown(osdp_t *ctx) { input_check(ctx);