From eaacfc6331b4e054f2eda899d7a5bf9246d90d49 Mon Sep 17 00:00:00 2001 From: Siddharth Chandrasekaran Date: Thu, 6 Jun 2024 23:24:29 +0200 Subject: [PATCH] API: Add new setup flag to guard notification events The newly added notification events may cause existing application which did not sign up for them to break. To avoid surprises, guard this event with a setup flag so application must explicitly ask for it. Signed-off-by: Siddharth Chandrasekaran --- include/osdp.h | 10 ++++++++++ python/osdp/constants.py | 1 + python/osdp_sys/module.c | 1 + src/osdp_cp.c | 17 +++++++++++------ tests/pytest/test_commands.py | 10 +++++----- tests/pytest/test_events.py | 2 +- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/include/osdp.h b/include/osdp.h index d93a902..d880e9b 100644 --- a/include/osdp.h +++ b/include/osdp.h @@ -52,6 +52,16 @@ extern "C" { */ #define OSDP_FLAG_IGN_UNSOLICITED 0x00040000 +/** + * @brief Enable LibOSDP notification events - @ref osdp_event_notification - to + * be reported using the event callback method registered by the application. + * + * @note These events, unlike others, are not generated by the PD. + * + * @note This is a CP mode only flag; in PD mode this flag has no use. + */ +#define OSDP_FLAG_ENABLE_NOTIFICATION 0x00080000 + /** * @brief Various PD capability function codes. */ diff --git a/python/osdp/constants.py b/python/osdp/constants.py index 3b6e421..0f9d58d 100644 --- a/python/osdp/constants.py +++ b/python/osdp/constants.py @@ -10,6 +10,7 @@ class LibFlag: EnforceSecure = osdp_sys.FLAG_ENFORCE_SECURE InstallMode = osdp_sys.FLAG_INSTALL_MODE IgnoreUnsolicited = osdp_sys.FLAG_IGN_UNSOLICITED + EnableNotification = osdp_sys.FLAG_ENABLE_NOTIFICATION class LogLevel: Emergency = osdp_sys.LOG_EMERG diff --git a/python/osdp_sys/module.c b/python/osdp_sys/module.c index 8a54ee8..bbba104 100644 --- a/python/osdp_sys/module.c +++ b/python/osdp_sys/module.c @@ -22,6 +22,7 @@ void pyosdp_add_module_constants(PyObject *module) ADD_CONST("FLAG_ENFORCE_SECURE", OSDP_FLAG_ENFORCE_SECURE); ADD_CONST("FLAG_INSTALL_MODE", OSDP_FLAG_INSTALL_MODE); ADD_CONST("FLAG_IGN_UNSOLICITED", OSDP_FLAG_IGN_UNSOLICITED); + ADD_CONST("FLAG_ENABLE_NOTIFICATION", OSDP_FLAG_ENABLE_NOTIFICATION); ADD_CONST("LOG_EMERG", OSDP_LOG_EMERG); ADD_CONST("LOG_ALERT", OSDP_LOG_ALERT); diff --git a/src/osdp_cp.c b/src/osdp_cp.c index 1c18165..a44c4b8 100644 --- a/src/osdp_cp.c +++ b/src/osdp_cp.c @@ -945,14 +945,16 @@ static void notify_sc_status(struct osdp_pd *pd) struct osdp *ctx = pd_to_osdp(pd); struct osdp_event evt; + if (!ctx->event_callback || + !ISSET_FLAG(pd, OSDP_FLAG_ENABLE_NOTIFICATION)) { + return; + } evt.type = OSDP_EVENT_NOTIFICATION; evt.notif.type = OSDP_EVENT_NOTIFICATION_SC_STATUS; evt.notif.arg0 = sc_is_active(pd); evt.notif.arg1 = ISSET_FLAG(pd, PD_FLAG_SC_USE_SCBKD); - if (ctx->event_callback) { - ctx->event_callback(ctx->event_callback_arg, pd->idx, &evt); - } + ctx->event_callback(ctx->event_callback_arg, pd->idx, &evt); } static void cp_keyset_complete(struct osdp_pd *pd) @@ -1218,6 +1220,11 @@ static void notify_command_status(struct osdp_pd *pd, int status) struct osdp_event evt; struct osdp *ctx = pd_to_osdp(pd); + if (!ctx->event_callback || + !ISSET_FLAG(pd, OSDP_FLAG_ENABLE_NOTIFICATION)) { + return; + } + switch (pd->cmd_id) { case CMD_OUT: app_cmd = OSDP_CMD_OUTPUT; break; case CMD_LED: app_cmd = OSDP_CMD_LED; break; @@ -1243,9 +1250,7 @@ static void notify_command_status(struct osdp_pd *pd, int status) evt.notif.arg0 = app_cmd; evt.notif.arg1 = status; - if (ctx->event_callback) { - ctx->event_callback(ctx->event_callback_arg, pd->idx, &evt); - } + ctx->event_callback(ctx->event_callback_arg, pd->idx, &evt); } static int state_update(struct osdp_pd *pd) diff --git a/tests/pytest/test_commands.py b/tests/pytest/test_commands.py index 34dde12..c027e07 100644 --- a/tests/pytest/test_commands.py +++ b/tests/pytest/test_commands.py @@ -26,8 +26,8 @@ ]) pd_info_list = [ - PDInfo(secure_pd_addr, f1_1, scbk=key, flags=[ LibFlag.EnforceSecure ]), - PDInfo(insecure_pd_addr, f2_1) + PDInfo(secure_pd_addr, f1_1, scbk=key, flags=[ LibFlag.EnforceSecure, LibFlag.EnableNotification ]), + PDInfo(insecure_pd_addr, f2_1, flags=[ LibFlag.EnableNotification ]) ] # TODO remove this. @@ -50,15 +50,15 @@ cp = ControlPanel(pd_info_list, log_level=LogLevel.Debug) -def cp_check_command_status(cmd): +def cp_check_command_status(cmd, expected_outcome=True): event = { 'event': Event.Notification, 'type': EventNotification.Command, 'arg0': cmd, - 'arg1': 1, + 'arg1': 1 if expected_outcome else 0, } while True: - e = cp.get_event(secure_pd.address, timeout=1) + e = cp.get_event(secure_pd.address) if (e['event'] == Event.Notification and e['type'] == EventNotification.Command): break diff --git a/tests/pytest/test_events.py b/tests/pytest/test_events.py index 363fd46..38e456a 100644 --- a/tests/pytest/test_events.py +++ b/tests/pytest/test_events.py @@ -31,7 +31,7 @@ ] cp = ControlPanel([ - PDInfo(101, f2, scbk=key, flags=[ LibFlag.EnforceSecure ]) + PDInfo(101, f2, scbk=key, flags=[ LibFlag.EnforceSecure, LibFlag.EnableNotification ]) ], log_level=LogLevel.Debug )