modem: hl7800: Enable multi-user callbacks

Change callback registration so it can support multiple users.

Signed-off-by: Ryan Erickson <ryan.erickson@lairdconnect.com>
This commit is contained in:
Ryan Erickson 2022-06-01 09:23:25 -05:00 committed by Carles Cufí
commit d4a16768bf
2 changed files with 42 additions and 9 deletions

View file

@ -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_RX_lock_sem, 1, 1);
static K_SEM_DEFINE(hl7800_TX_lock_sem, 1, 1); static K_SEM_DEFINE(hl7800_TX_lock_sem, 1, 1);
static K_MUTEX_DEFINE(cb_lock);
/* RX thread structures */ /* RX thread structures */
K_THREAD_STACK_DEFINE(hl7800_rx_stack, CONFIG_MODEM_HL7800_RX_STACK_SIZE); 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 hl7800_lpm low_power_mode;
enum mdm_hl7800_network_state network_state; enum mdm_hl7800_network_state network_state;
enum net_operator_status operator_status; enum net_operator_status operator_status;
void (*event_callback)(enum mdm_hl7800_event event, void *event_data);
struct tm local_time; struct tm local_time;
int32_t local_time_offset; int32_t local_time_offset;
bool local_time_valid; bool local_time_valid;
@ -578,6 +578,9 @@ struct cmd_handler {
bool (*func)(struct net_buf **buf, uint16_t len); 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 struct hl7800_iface_ctx ictx;
static size_t hl7800_read_rx(struct net_buf **buf); 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) static void event_handler(enum mdm_hl7800_event event, void *event_data)
{ {
if (ictx.event_callback != NULL) { sys_snode_t *node;
ictx.event_callback(event, event_data); 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) void mdm_hl7800_get_signal_quality(int *rsrp, int *sinr)
@ -5476,12 +5487,21 @@ int32_t mdm_hl7800_power_off(void)
return rc; 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; void mdm_hl7800_unregister_event_callback(struct mdm_hl7800_callback_agent *agent)
irq_unlock(key); {
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 ***/ /*** OFFLOAD FUNCTIONS ***/

View file

@ -250,6 +250,11 @@ struct mdm_hl7800_polte_location_data {
typedef void (*mdm_hl7800_event_callback_t)(enum mdm_hl7800_event event, typedef void (*mdm_hl7800_event_callback_t)(enum mdm_hl7800_event event,
void *event_data); void *event_data);
struct mdm_hl7800_callback_agent {
sys_snode_t node;
mdm_hl7800_event_callback_t event_callback;
};
/** /**
* @brief Power off the HL7800 * @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. * @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. * @brief Force modem module to generate status events.