net: conn_mgr: refactor event logic
In preparation for altering the conditions under which conn_mgr fires NET_EVENT_L4_CONNECTED and NET_EVENT_L4_DISCONNECTED, refactor the event logic without changing its behavior. These changes do not alter the behavior of conn_mgr. They merely change how that behavior is expressed so that it is easier to understand, and so that upcoming changes are easier to implement. Signed-off-by: Georges Oates_Larsen <georges.larsen@nordicsemi.no>
This commit is contained in:
parent
7afca97f9e
commit
6cda221c53
|
@ -23,6 +23,9 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL);
|
|||
#define THREAD_PRIORITY K_PRIO_PREEMPT(7)
|
||||
#endif
|
||||
|
||||
/* Internal state array tracking readiness, flags, and other state information for all available
|
||||
* ifaces. Note that indexing starts at 0, whereas Zephyr iface indices start at 1.
|
||||
*/
|
||||
uint16_t iface_states[CONN_MGR_IFACE_MAX];
|
||||
|
||||
/* Used to signal when modifications have been made that need to be responded to */
|
||||
|
@ -31,72 +34,94 @@ K_SEM_DEFINE(conn_mgr_event_signal, 1, 1);
|
|||
/* Used to protect conn_mgr state */
|
||||
K_MUTEX_DEFINE(conn_mgr_lock);
|
||||
|
||||
static enum conn_mgr_state conn_mgr_iface_status(int index)
|
||||
{
|
||||
if (iface_states[index] & CONN_MGR_IF_UP) {
|
||||
return CONN_MGR_STATE_CONNECTED;
|
||||
}
|
||||
|
||||
return CONN_MGR_STATE_DISCONNECTED;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_IPV6)
|
||||
static enum conn_mgr_state conn_mgr_ipv6_status(int index)
|
||||
static bool conn_mgr_is_if_ipv6_ready(int index)
|
||||
{
|
||||
if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) ==
|
||||
CONN_MGR_IPV6_STATUS_MASK) {
|
||||
if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == CONN_MGR_IPV6_STATUS_MASK) {
|
||||
NET_DBG("IPv6 connected on iface index %u", index + 1);
|
||||
return CONN_MGR_STATE_CONNECTED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return CONN_MGR_STATE_DISCONNECTED;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#define conn_mgr_ipv6_status(...) CONN_MGR_STATE_CONNECTED
|
||||
#define conn_mgr_is_if_ipv6_ready(...) false
|
||||
#endif /* CONFIG_NET_IPV6 */
|
||||
|
||||
#if defined(CONFIG_NET_IPV4)
|
||||
static enum conn_mgr_state conn_mgr_ipv4_status(int index)
|
||||
static bool conn_mgr_is_if_ipv4_ready(int index)
|
||||
{
|
||||
if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) ==
|
||||
CONN_MGR_IPV4_STATUS_MASK) {
|
||||
if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == CONN_MGR_IPV4_STATUS_MASK) {
|
||||
NET_DBG("IPv4 connected on iface index %u", index + 1);
|
||||
return CONN_MGR_STATE_CONNECTED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return CONN_MGR_STATE_DISCONNECTED;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#define conn_mgr_ipv4_status(...) CONN_MGR_STATE_CONNECTED
|
||||
#define conn_mgr_is_if_ipv4_ready(...) false
|
||||
#endif /* CONFIG_NET_IPV4 */
|
||||
|
||||
static void conn_mgr_notify_status(int index)
|
||||
/**
|
||||
* @brief Retrieves pointer to an iface by the index that corresponds to it in iface_states
|
||||
*
|
||||
* @param index - The index in iface_states to find the corresponding iface for.
|
||||
* @return net_if* - The corresponding iface.
|
||||
*/
|
||||
static struct net_if *conn_mgr_get_if_by_index(int index)
|
||||
{
|
||||
struct net_if *iface = net_if_get_by_index(index + 1);
|
||||
return net_if_get_by_index(index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Notifies listeners of the current readiness state of the iface at the given index
|
||||
*
|
||||
* @param index - Index of the iface (in iface_states)
|
||||
*/
|
||||
static void conn_mgr_notify_if_readiness(int index)
|
||||
{
|
||||
struct net_if *iface = conn_mgr_get_if_by_index(index);
|
||||
bool readiness = iface_states[index] & CONN_MGR_IF_READY;
|
||||
|
||||
if (iface == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (iface_states[index] & CONN_MGR_IF_READY) {
|
||||
NET_DBG("Iface %d (%p) connected",
|
||||
net_if_get_by_iface(iface), iface);
|
||||
net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, iface);
|
||||
} else {
|
||||
NET_DBG("Iface %d (%p) disconnected",
|
||||
net_if_get_by_iface(iface), iface);
|
||||
net_mgmt_event_notify(NET_EVENT_L4_DISCONNECTED, iface);
|
||||
NET_DBG("Iface %d (%p) %s", net_if_get_by_iface(iface),
|
||||
iface, readiness ? "ready" : "unready");
|
||||
|
||||
net_mgmt_event_notify(
|
||||
readiness ? NET_EVENT_L4_CONNECTED : NET_EVENT_L4_DISCONNECTED,
|
||||
iface
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks an iface as ready or unready and updates all associated state tracking.
|
||||
*
|
||||
* @param idx - index (in iface_states) of the iface to mark ready or unready
|
||||
* @param readiness - true if the iface should be considered ready, otherwise false
|
||||
*/
|
||||
static void conn_mgr_set_ready(int idx, bool readiness)
|
||||
{
|
||||
/* Clear and then update the L4-readiness bit */
|
||||
iface_states[idx] &= ~CONN_MGR_IF_READY;
|
||||
if (readiness) {
|
||||
iface_states[idx] |= CONN_MGR_IF_READY;
|
||||
}
|
||||
}
|
||||
|
||||
static void conn_mgr_act_on_changes(void)
|
||||
{
|
||||
int idx;
|
||||
bool is_ip_ready;
|
||||
bool is_l4_ready;
|
||||
bool is_oper_up;
|
||||
bool was_l4_ready;
|
||||
|
||||
k_mutex_lock(&conn_mgr_lock, K_FOREVER);
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) {
|
||||
enum conn_mgr_state state;
|
||||
|
||||
if (iface_states[idx] == 0) {
|
||||
/* This interface is not used */
|
||||
|
@ -104,44 +129,36 @@ static void conn_mgr_act_on_changes(void)
|
|||
}
|
||||
|
||||
if (!(iface_states[idx] & CONN_MGR_IF_CHANGED)) {
|
||||
/* No changes on this iface */
|
||||
continue;
|
||||
}
|
||||
|
||||
state = CONN_MGR_STATE_CONNECTED;
|
||||
|
||||
state &= conn_mgr_iface_status(idx);
|
||||
if (state) {
|
||||
enum conn_mgr_state ip_state = CONN_MGR_STATE_DISCONNECTED;
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_IPV6)) {
|
||||
ip_state |= conn_mgr_ipv6_status(idx);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_IPV4)) {
|
||||
ip_state |= conn_mgr_ipv4_status(idx);
|
||||
}
|
||||
|
||||
state &= ip_state;
|
||||
}
|
||||
|
||||
/* Clear the state-change flag */
|
||||
iface_states[idx] &= ~CONN_MGR_IF_CHANGED;
|
||||
|
||||
if (state == CONN_MGR_STATE_CONNECTED &&
|
||||
!(iface_states[idx] & CONN_MGR_IF_READY)) {
|
||||
iface_states[idx] |= CONN_MGR_IF_READY;
|
||||
/* Detect whether the iface is currently or was L4 ready */
|
||||
is_ip_ready = conn_mgr_is_if_ipv6_ready(idx) || conn_mgr_is_if_ipv4_ready(idx);
|
||||
is_oper_up = iface_states[idx] & CONN_MGR_IF_UP;
|
||||
was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY;
|
||||
is_l4_ready = is_oper_up && is_ip_ready;
|
||||
|
||||
conn_mgr_notify_status(idx);
|
||||
} else if (state != CONN_MGR_STATE_CONNECTED &&
|
||||
(iface_states[idx] & CONN_MGR_IF_READY)) {
|
||||
iface_states[idx] &= ~CONN_MGR_IF_READY;
|
||||
/* Respond to changes to iface readiness */
|
||||
if (was_l4_ready != is_l4_ready) {
|
||||
/* Track the iface readiness change */
|
||||
conn_mgr_set_ready(idx, is_l4_ready);
|
||||
|
||||
conn_mgr_notify_status(idx);
|
||||
/* Notify listeners of the readiness change */
|
||||
conn_mgr_notify_if_readiness(idx);
|
||||
}
|
||||
}
|
||||
|
||||
k_mutex_unlock(&conn_mgr_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the internal state flags for the given iface using its current status
|
||||
*
|
||||
* @param iface - iface to initialize from.
|
||||
*/
|
||||
static void conn_mgr_initial_state(struct net_if *iface)
|
||||
{
|
||||
int idx = net_if_get_by_iface(iface) - 1;
|
||||
|
@ -217,7 +234,7 @@ void conn_mgr_resend_status(void)
|
|||
k_mutex_lock(&conn_mgr_lock, K_FOREVER);
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) {
|
||||
conn_mgr_notify_status(idx);
|
||||
conn_mgr_notify_if_readiness(idx);
|
||||
}
|
||||
|
||||
k_mutex_unlock(&conn_mgr_lock);
|
||||
|
|
|
@ -51,11 +51,6 @@
|
|||
extern struct k_sem conn_mgr_event_signal;
|
||||
extern struct k_mutex conn_mgr_lock;
|
||||
|
||||
enum conn_mgr_state {
|
||||
CONN_MGR_STATE_DISCONNECTED = 0,
|
||||
CONN_MGR_STATE_CONNECTED = 1,
|
||||
};
|
||||
|
||||
void conn_mgr_init_events_handler(void);
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue