-
Notifications
You must be signed in to change notification settings - Fork 2.1k
net/gnrc_netif: add bus for interface events, gnrc_netif_up()/gnrc_netif_down() functions #17902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
4c012cb
ab47098
bb2697b
8de8d05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -311,6 +311,28 @@ int gnrc_netif_get_from_netdev(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt) | |||||||
res = netif->dev->driver->get(netif->dev, opt->opt, opt->data, | ||||||||
opt->data_len); | ||||||||
} | ||||||||
if (res == -ENOTSUP) { | ||||||||
/* handle default values */ | ||||||||
switch (opt->opt) { | ||||||||
case NETOPT_LINK: { | ||||||||
netopt_state_t state; | ||||||||
res = netif->dev->driver->get(netif->dev, NETOPT_STATE, &state, sizeof(state)); | ||||||||
if (res < 0) { | ||||||||
break; | ||||||||
} | ||||||||
res = sizeof(netopt_enable_t); | ||||||||
if ((state == NETOPT_STATE_SLEEP) || (state == NETOPT_STATE_OFF) || | ||||||||
(state == NETOPT_STATE_STANDBY)) { | ||||||||
*((netopt_enable_t *)opt->data) = NETOPT_DISABLE; | ||||||||
} else { | ||||||||
*((netopt_enable_t *)opt->data) = NETOPT_ENABLE; | ||||||||
} | ||||||||
break; | ||||||||
} | ||||||||
default: | ||||||||
break; | ||||||||
} | ||||||||
} | ||||||||
gnrc_netif_release(netif); | ||||||||
return res; | ||||||||
} | ||||||||
|
@@ -1437,6 +1459,61 @@ bool gnrc_netif_ipv6_wait_for_global_address(gnrc_netif_t *netif, | |||||||
#endif /* IS_USED(MODULE_GNRC_NETIF_BUS) */ | ||||||||
#endif /* IS_USED(MODULE_GNRC_NETIF_IPV6) */ | ||||||||
|
||||||||
static int _change_state_and_wait(gnrc_netif_t *netif, netopt_state_t state, unsigned timeout_ms) | ||||||||
{ | ||||||||
int res = 0; | ||||||||
|
||||||||
netopt_state_t state_prev; | ||||||||
while (gnrc_netapi_get(netif->pid, NETOPT_STATE, 0, &state_prev, sizeof(state_prev)) == -EBUSY) {} | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line and the one below are a bit too long (warning of > 100 characters) |
||||||||
|
||||||||
if (state == state_prev) { | ||||||||
return 0; | ||||||||
} | ||||||||
|
||||||||
#if IS_USED(MODULE_GNRC_NETIF_BUS) | ||||||||
gnrc_netif_event_t event; | ||||||||
|
||||||||
if ((state == NETOPT_STATE_SLEEP) || (state == NETOPT_STATE_OFF) || | ||||||||
(state == NETOPT_STATE_STANDBY)) { | ||||||||
event = GNRC_NETIF_EVENT_LINK_STATE_CHANGED_DOWN; | ||||||||
} else { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
event = GNRC_NETIF_EVENT_LINK_STATE_CHANGED_UP; | ||||||||
} | ||||||||
|
||||||||
msg_bus_entry_t sub; | ||||||||
msg_bus_t *bus = gnrc_netif_get_bus(netif, GNRC_NETIF_BUS_IFACE); | ||||||||
msg_bus_attach(bus, &sub); | ||||||||
msg_bus_subscribe(&sub, event); | ||||||||
#endif | ||||||||
|
||||||||
while (gnrc_netapi_set(netif->pid, NETOPT_STATE, 0, &state, sizeof(state)) == -EBUSY) {} | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Must it be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uh interesting.
|
||||||||
|
||||||||
if (timeout_ms == 0) { | ||||||||
return 0; | ||||||||
} | ||||||||
|
||||||||
#if IS_USED(MODULE_GNRC_NETIF_BUS) | ||||||||
msg_t m; | ||||||||
if (ztimer_msg_receive_timeout(ZTIMER_MSEC, &m, timeout_ms) < 0) { | ||||||||
DEBUG_PUTS("gnrc_netif: timeout waiting for state change"); | ||||||||
res = -ETIMEDOUT; | ||||||||
} | ||||||||
msg_bus_detach(bus, &sub); | ||||||||
#endif | ||||||||
|
||||||||
return res; | ||||||||
} | ||||||||
|
||||||||
int gnrc_netif_up(gnrc_netif_t *netif, unsigned timeout_ms) | ||||||||
benpicco marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
{ | ||||||||
return _change_state_and_wait(netif, NETOPT_STATE_IDLE, timeout_ms); | ||||||||
} | ||||||||
|
||||||||
int gnrc_netif_down(gnrc_netif_t *netif, unsigned timeout_ms) | ||||||||
{ | ||||||||
return _change_state_and_wait(netif, NETOPT_STATE_SLEEP, timeout_ms); | ||||||||
} | ||||||||
|
||||||||
static void _update_l2addr_from_dev(gnrc_netif_t *netif) | ||||||||
{ | ||||||||
netdev_t *dev = netif->dev; | ||||||||
|
@@ -2051,18 +2128,14 @@ static void _event_cb(netdev_t *dev, netdev_event_t event) | |||||||
gnrc_pktsnip_t *pkt = NULL; | ||||||||
switch (event) { | ||||||||
case NETDEV_EVENT_LINK_UP: | ||||||||
if (IS_USED(MODULE_GNRC_IPV6)) { | ||||||||
msg_t msg = { .type = GNRC_IPV6_NIB_IFACE_UP, .content = { .ptr = netif } }; | ||||||||
|
||||||||
msg_send(&msg, gnrc_ipv6_pid); | ||||||||
} | ||||||||
gnrc_netif_event_bus_post(netif, | ||||||||
GNRC_NETIF_EVENT_LINK_STATE_CHANGED_UP, | ||||||||
netif); | ||||||||
break; | ||||||||
case NETDEV_EVENT_LINK_DOWN: | ||||||||
if (IS_USED(MODULE_GNRC_IPV6)) { | ||||||||
msg_t msg = { .type = GNRC_IPV6_NIB_IFACE_DOWN, .content = { .ptr = netif } }; | ||||||||
|
||||||||
msg_send(&msg, gnrc_ipv6_pid); | ||||||||
} | ||||||||
gnrc_netif_event_bus_post(netif, | ||||||||
GNRC_NETIF_EVENT_LINK_STATE_CHANGED_DOWN, | ||||||||
netif); | ||||||||
break; | ||||||||
case NETDEV_EVENT_RX_COMPLETE: | ||||||||
pkt = netif->ops->recv(netif); | ||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -186,6 +186,22 @@ static void *_event_loop(void *args) | |
/* register interest in all IPv6 packets */ | ||
gnrc_netreg_register(GNRC_NETTYPE_IPV6, &me_reg); | ||
|
||
DEBUG_PUTS("ipv6: wait for interfaces to be ready"); | ||
while (gnrc_netif_iter(NULL) == NULL) { | ||
ztimer_sleep(ZTIMER_MSEC, 250); | ||
} | ||
Comment on lines
+189
to
+192
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks fragile. But I also do not know any way to reliably wait for interface registration to complete off the top of my head or even if such feature exists :/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The interfaces could send a message when they are initialized, then we can handle the registration here. |
||
|
||
/* subscribe to interface events */ | ||
gnrc_netif_t *netif = NULL; | ||
while ((netif = gnrc_netif_iter(netif))) { | ||
DEBUG("ipv6: subscribe to events on interface %u\n", netif->pid); | ||
|
||
msg_bus_t *bus = gnrc_netif_get_bus(netif, GNRC_NETIF_BUS_IFACE); | ||
msg_bus_attach(bus, &netif->ipv6.netif_sub); | ||
msg_bus_subscribe(&netif->ipv6.netif_sub, GNRC_NETIF_EVENT_LINK_STATE_CHANGED_UP); | ||
msg_bus_subscribe(&netif->ipv6.netif_sub, GNRC_NETIF_EVENT_LINK_STATE_CHANGED_DOWN); | ||
} | ||
|
||
/* preinitialize ACK */ | ||
reply.type = GNRC_NETAPI_MSG_TYPE_ACK; | ||
|
||
|
@@ -194,7 +210,7 @@ static void *_event_loop(void *args) | |
DEBUG("ipv6: waiting for incoming message.\n"); | ||
msg_receive(&msg); | ||
|
||
switch (msg.type) { | ||
switch (msg_bus_get_type(&msg)) { | ||
case GNRC_NETAPI_MSG_TYPE_RCV: | ||
DEBUG("ipv6: GNRC_NETAPI_MSG_TYPE_RCV received\n"); | ||
_receive(msg.content.ptr); | ||
|
@@ -244,10 +260,10 @@ static void *_event_loop(void *args) | |
DEBUG("ipv6: NIB timer event received\n"); | ||
gnrc_ipv6_nib_handle_timer_event(msg.content.ptr, msg.type); | ||
break; | ||
case GNRC_IPV6_NIB_IFACE_UP: | ||
case GNRC_NETIF_EVENT_LINK_STATE_CHANGED_UP: | ||
gnrc_ipv6_nib_iface_up(msg.content.ptr); | ||
break; | ||
case GNRC_IPV6_NIB_IFACE_DOWN: | ||
case GNRC_NETIF_EVENT_LINK_STATE_CHANGED_DOWN: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Care to fix the indent here, since you touch the code anyway? |
||
gnrc_ipv6_nib_iface_down(msg.content.ptr, false); | ||
break; | ||
default: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation seems to be swapped