From d4a16768bfd0ab0cf60ba7eb806ab1a8a1b18f2c Mon Sep 17 00:00:00 2001 From: Ryan Erickson Date: Wed, 1 Jun 2022 09:23:25 -0500 Subject: [PATCH] modem: hl7800: Enable multi-user callbacks Change callback registration so it can support multiple users. Signed-off-by: Ryan Erickson --- drivers/modem/hl7800.c | 34 +++++++++++++++++++++------ include/zephyr/drivers/modem/hl7800.h | 17 ++++++++++++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/drivers/modem/hl7800.c b/drivers/modem/hl7800.c index 350717cb4fc..3061939ed27 100644 --- a/drivers/modem/hl7800.c +++ b/drivers/modem/hl7800.c @@ -406,6 +406,7 @@ static uint8_t mdm_recv_buf[MDM_MAX_DATA_LENGTH]; static K_SEM_DEFINE(hl7800_RX_lock_sem, 1, 1); static K_SEM_DEFINE(hl7800_TX_lock_sem, 1, 1); +static K_MUTEX_DEFINE(cb_lock); /* RX thread structures */ K_THREAD_STACK_DEFINE(hl7800_rx_stack, CONFIG_MODEM_HL7800_RX_STACK_SIZE); @@ -557,7 +558,6 @@ struct hl7800_iface_ctx { enum hl7800_lpm low_power_mode; enum mdm_hl7800_network_state network_state; enum net_operator_status operator_status; - void (*event_callback)(enum mdm_hl7800_event event, void *event_data); struct tm local_time; int32_t local_time_offset; bool local_time_valid; @@ -578,6 +578,9 @@ struct cmd_handler { bool (*func)(struct net_buf **buf, uint16_t len); }; +static sys_slist_t hl7800_event_callback_list = + SYS_SLIST_STATIC_INIT(&hl7800_event_callback_list); + static struct hl7800_iface_ctx ictx; static size_t hl7800_read_rx(struct net_buf **buf); @@ -962,9 +965,17 @@ static void allow_sleep(bool allow) static void event_handler(enum mdm_hl7800_event event, void *event_data) { - if (ictx.event_callback != NULL) { - ictx.event_callback(event, event_data); + sys_snode_t *node; + struct mdm_hl7800_callback_agent *agent; + + k_mutex_lock(&cb_lock, K_FOREVER); + SYS_SLIST_FOR_EACH_NODE(&hl7800_event_callback_list, node) { + agent = CONTAINER_OF(node, struct mdm_hl7800_callback_agent, node); + if (agent->event_callback != NULL) { + agent->event_callback(event, event_data); + } } + k_mutex_unlock(&cb_lock); } void mdm_hl7800_get_signal_quality(int *rsrp, int *sinr) @@ -5476,12 +5487,21 @@ int32_t mdm_hl7800_power_off(void) return rc; } -void mdm_hl7800_register_event_callback(mdm_hl7800_event_callback_t cb) +void mdm_hl7800_register_event_callback(struct mdm_hl7800_callback_agent *agent) { - int key = irq_lock(); + k_mutex_lock(&cb_lock, K_FOREVER); + if (!agent->event_callback) { + LOG_WRN("event_callback is NULL"); + } + sys_slist_append(&hl7800_event_callback_list, &agent->node); + k_mutex_unlock(&cb_lock); +} - ictx.event_callback = cb; - irq_unlock(key); +void mdm_hl7800_unregister_event_callback(struct mdm_hl7800_callback_agent *agent) +{ + k_mutex_lock(&cb_lock, K_FOREVER); + (void)sys_slist_find_and_remove(&hl7800_event_callback_list, &agent->node); + k_mutex_unlock(&cb_lock); } /*** OFFLOAD FUNCTIONS ***/ diff --git a/include/zephyr/drivers/modem/hl7800.h b/include/zephyr/drivers/modem/hl7800.h index e4a26cc11d7..98a7caaeba8 100644 --- a/include/zephyr/drivers/modem/hl7800.h +++ b/include/zephyr/drivers/modem/hl7800.h @@ -250,6 +250,11 @@ struct mdm_hl7800_polte_location_data { typedef void (*mdm_hl7800_event_callback_t)(enum mdm_hl7800_event event, void *event_data); +struct mdm_hl7800_callback_agent { + sys_snode_t node; + mdm_hl7800_event_callback_t event_callback; +}; + /** * @brief Power off the HL7800 * @@ -346,10 +351,18 @@ bool mdm_hl7800_valid_rat(uint8_t value); /** * @brief Register a function that is called when a modem event occurs. + * Multiple users registering for callbacks is supported. * - * @param cb event callback + * @param agent event callback agent */ -void mdm_hl7800_register_event_callback(mdm_hl7800_event_callback_t cb); +void mdm_hl7800_register_event_callback(struct mdm_hl7800_callback_agent *agent); + +/** + * @brief Unregister a callback event function + * + * @param agent event callback agent + */ +void mdm_hl7800_unregister_event_callback(struct mdm_hl7800_callback_agent *agent); /** * @brief Force modem module to generate status events.