net: openthread: Add state change callback list
Add a new callback list structure for state change information. These APIs are meant to eventually replace the single callback API provided by openthread_set_state_changed_cb(). This will allow multiple users to gain information about OpenThread stage changes. Note CONFIG_OPENTHREAD_MAX_STATECHANGE_HANDLERS with OpenThread's otSetStateChangedCallback() API can also be used to enable registration of multiple callbacks of this type but this cannot be modified if a certified OpenThread binary is used in the build. Signed-off-by: Nick Ward <nick.ward@ftpsolutions.com.au>
This commit is contained in:
parent
11c7371f99
commit
583545b662
2 changed files with 105 additions and 4 deletions
|
@ -68,11 +68,65 @@ struct openthread_context {
|
||||||
|
|
||||||
/** Work object for OpenThread internal usage */
|
/** Work object for OpenThread internal usage */
|
||||||
struct k_work api_work;
|
struct k_work api_work;
|
||||||
|
|
||||||
|
/** A list for state change callbacks */
|
||||||
|
sys_slist_t state_change_cbs;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* INTERNAL_HIDDEN @endcond
|
* INTERNAL_HIDDEN @endcond
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** OpenThread state change callback */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief OpenThread state change callback structure
|
||||||
|
*
|
||||||
|
* Used to register a callback in the callback list. As many
|
||||||
|
* callbacks as needed can be added as long as each of them
|
||||||
|
* are unique pointers of struct openthread_state_changed_cb.
|
||||||
|
* Beware such structure should not be allocated on stack.
|
||||||
|
*/
|
||||||
|
struct openthread_state_changed_cb {
|
||||||
|
/**
|
||||||
|
* @brief Callback for notifying configuration or state changes.
|
||||||
|
*
|
||||||
|
* @param flags as per OpenThread otStateChangedCallback() aFlags parameter.
|
||||||
|
* See https://openthread.io/reference/group/api-instance#otstatechangedcallback
|
||||||
|
* @param ot_context the OpenThread context the callback is registered with.
|
||||||
|
* @param user_data Data to pass to the callback.
|
||||||
|
*/
|
||||||
|
void (*state_changed_cb)(otChangedFlags flags, struct openthread_context *ot_context,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/** User data if required */
|
||||||
|
void *user_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internally used field for list handling
|
||||||
|
* - user must not directly modify
|
||||||
|
*/
|
||||||
|
sys_snode_t node;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers callbacks which will be called when certain configuration
|
||||||
|
* or state changes occur within OpenThread.
|
||||||
|
*
|
||||||
|
* @param ot_context the OpenThread context to register the callback with.
|
||||||
|
* @param cb callback struct to register.
|
||||||
|
*/
|
||||||
|
int openthread_state_changed_cb_register(struct openthread_context *ot_context,
|
||||||
|
struct openthread_state_changed_cb *cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unregisters OpenThread configuration or state changed callbacks.
|
||||||
|
*
|
||||||
|
* @param ot_context the OpenThread context to unregister the callback from.
|
||||||
|
* @param cb callback struct to unregister.
|
||||||
|
*/
|
||||||
|
int openthread_state_changed_cb_unregister(struct openthread_context *ot_context,
|
||||||
|
struct openthread_state_changed_cb *cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets function which will be called when certain configuration or state
|
* @brief Sets function which will be called when certain configuration or state
|
||||||
* changes within OpenThread.
|
* changes within OpenThread.
|
||||||
|
|
|
@ -15,6 +15,8 @@ LOG_MODULE_REGISTER(net_l2_openthread, CONFIG_OPENTHREAD_L2_LOG_LEVEL);
|
||||||
#include <net_private.h>
|
#include <net_private.h>
|
||||||
|
|
||||||
#include <zephyr/init.h>
|
#include <zephyr/init.h>
|
||||||
|
#include <zephyr/sys/check.h>
|
||||||
|
#include <zephyr/sys/slist.h>
|
||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
#include <zephyr/sys/__assert.h>
|
#include <zephyr/sys/__assert.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
@ -174,6 +176,7 @@ void otSysEventSignalPending(void)
|
||||||
|
|
||||||
static void ot_state_changed_handler(uint32_t flags, void *context)
|
static void ot_state_changed_handler(uint32_t flags, void *context)
|
||||||
{
|
{
|
||||||
|
struct openthread_state_changed_cb *entry, *next;
|
||||||
struct openthread_context *ot_context = context;
|
struct openthread_context *ot_context = context;
|
||||||
|
|
||||||
NET_INFO("State changed! Flags: 0x%08" PRIx32 " Current role: %s",
|
NET_INFO("State changed! Flags: 0x%08" PRIx32 " Current role: %s",
|
||||||
|
@ -220,6 +223,12 @@ static void ot_state_changed_handler(uint32_t flags, void *context)
|
||||||
if (state_changed_cb) {
|
if (state_changed_cb) {
|
||||||
state_changed_cb(flags, context);
|
state_changed_cb(flags, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&ot_context->state_change_cbs, entry, next, node) {
|
||||||
|
if (entry->state_changed_cb != NULL) {
|
||||||
|
entry->state_changed_cb(flags, ot_context, entry->user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ot_receive_handler(otMessage *aMessage, void *context)
|
static void ot_receive_handler(otMessage *aMessage, void *context)
|
||||||
|
@ -491,11 +500,11 @@ int openthread_stop(struct openthread_context *ot_context)
|
||||||
static int openthread_init(struct net_if *iface)
|
static int openthread_init(struct net_if *iface)
|
||||||
{
|
{
|
||||||
struct openthread_context *ot_context = net_if_l2_data(iface);
|
struct openthread_context *ot_context = net_if_l2_data(iface);
|
||||||
|
|
||||||
struct k_work_queue_config q_cfg = {
|
struct k_work_queue_config q_cfg = {
|
||||||
.name = "openthread",
|
.name = "openthread",
|
||||||
.no_yield = true,
|
.no_yield = true,
|
||||||
};
|
};
|
||||||
|
otError err;
|
||||||
|
|
||||||
NET_DBG("openthread_init");
|
NET_DBG("openthread_init");
|
||||||
|
|
||||||
|
@ -524,9 +533,13 @@ static int openthread_init(struct net_if *iface)
|
||||||
otIp6SetReceiveFilterEnabled(ot_context->instance, true);
|
otIp6SetReceiveFilterEnabled(ot_context->instance, true);
|
||||||
otIp6SetReceiveCallback(ot_context->instance,
|
otIp6SetReceiveCallback(ot_context->instance,
|
||||||
ot_receive_handler, ot_context);
|
ot_receive_handler, ot_context);
|
||||||
otSetStateChangedCallback(ot_context->instance,
|
sys_slist_init(&ot_context->state_change_cbs);
|
||||||
&ot_state_changed_handler,
|
err = otSetStateChangedCallback(ot_context->instance,
|
||||||
ot_context);
|
&ot_state_changed_handler,
|
||||||
|
ot_context);
|
||||||
|
if (err != OT_ERROR_NONE) {
|
||||||
|
NET_ERR("Could not set state changed callback: %d", err);
|
||||||
|
}
|
||||||
|
|
||||||
net_mgmt_init_event_callback(
|
net_mgmt_init_event_callback(
|
||||||
&ip6_addr_cb, ipv6_addr_event_handler,
|
&ip6_addr_cb, ipv6_addr_event_handler,
|
||||||
|
@ -612,6 +625,40 @@ struct otInstance *openthread_get_default_instance(void)
|
||||||
return ot_context ? ot_context->instance : NULL;
|
return ot_context ? ot_context->instance : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int openthread_state_changed_cb_register(struct openthread_context *ot_context,
|
||||||
|
struct openthread_state_changed_cb *cb)
|
||||||
|
{
|
||||||
|
CHECKIF(cb == NULL || cb->state_changed_cb == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
openthread_api_mutex_lock(ot_context);
|
||||||
|
sys_slist_append(&ot_context->state_change_cbs, &cb->node);
|
||||||
|
openthread_api_mutex_unlock(ot_context);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int openthread_state_changed_cb_unregister(struct openthread_context *ot_context,
|
||||||
|
struct openthread_state_changed_cb *cb)
|
||||||
|
{
|
||||||
|
bool removed;
|
||||||
|
|
||||||
|
CHECKIF(cb == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
openthread_api_mutex_lock(ot_context);
|
||||||
|
removed = sys_slist_find_and_remove(&ot_context->state_change_cbs, &cb->node);
|
||||||
|
openthread_api_mutex_unlock(ot_context);
|
||||||
|
|
||||||
|
if (!removed) {
|
||||||
|
return -EALREADY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void openthread_set_state_changed_cb(otStateChangedCallback cb)
|
void openthread_set_state_changed_cb(otStateChangedCallback cb)
|
||||||
{
|
{
|
||||||
state_changed_cb = cb;
|
state_changed_cb = cb;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue