net: config: Wait network interface to come up
Before we try to set IP addresses to the network interface, make sure that the interface is up. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
6378ac4e38
commit
e3dc05f14d
@ -34,6 +34,10 @@ extern int net_init_clock_via_sntp(void);
|
||||
static K_SEM_DEFINE(waiter, 0, 1);
|
||||
static struct k_sem counter;
|
||||
|
||||
#if defined(CONFIG_NET_NATIVE)
|
||||
static struct net_mgmt_event_callback mgmt_iface_cb;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
|
||||
static struct net_mgmt_event_callback mgmt4_cb;
|
||||
|
||||
@ -282,12 +286,50 @@ static void setup_ipv6(struct net_if *iface, u32_t flags)
|
||||
#define setup_ipv6(...)
|
||||
#endif /* CONFIG_NET_IPV6 */
|
||||
|
||||
#if defined(CONFIG_NET_NATIVE)
|
||||
static void iface_up_handler(struct net_mgmt_event_callback *cb,
|
||||
u32_t mgmt_event, struct net_if *iface)
|
||||
{
|
||||
if (mgmt_event == NET_EVENT_IF_UP) {
|
||||
NET_INFO("Interface %p coming up", iface);
|
||||
|
||||
k_sem_reset(&counter);
|
||||
k_sem_give(&waiter);
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_interface(struct net_if *iface)
|
||||
{
|
||||
if (net_if_is_up(iface)) {
|
||||
k_sem_reset(&counter);
|
||||
k_sem_give(&waiter);
|
||||
return true;
|
||||
}
|
||||
|
||||
NET_INFO("Waiting interface %p to be up...", iface);
|
||||
|
||||
net_mgmt_init_event_callback(&mgmt_iface_cb, iface_up_handler,
|
||||
NET_EVENT_IF_UP);
|
||||
net_mgmt_add_event_callback(&mgmt_iface_cb);
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
static void check_interface(struct net_if *iface)
|
||||
{
|
||||
k_sem_reset(&counter);
|
||||
k_sem_give(&waiter);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
int net_config_init(const char *app_info, u32_t flags, s32_t timeout)
|
||||
{
|
||||
#define LOOP_DIVIDER 10
|
||||
struct net_if *iface = net_if_get_default();
|
||||
int loop = timeout / LOOP_DIVIDER;
|
||||
int count = 0;
|
||||
int count, need = 0;
|
||||
|
||||
if (app_info) {
|
||||
NET_INFO("%s", log_strdup(app_info));
|
||||
@ -298,22 +340,6 @@ int net_config_init(const char *app_info, u32_t flags, s32_t timeout)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (flags & NET_CONFIG_NEED_IPV6) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (flags & NET_CONFIG_NEED_IPV4) {
|
||||
count++;
|
||||
}
|
||||
|
||||
k_sem_init(&counter, count, UINT_MAX);
|
||||
|
||||
setup_ipv4(iface);
|
||||
|
||||
setup_dhcpv4(iface);
|
||||
|
||||
setup_ipv6(iface, flags);
|
||||
|
||||
if (timeout < 0) {
|
||||
count = -1;
|
||||
} else if (timeout == 0) {
|
||||
@ -322,6 +348,48 @@ int net_config_init(const char *app_info, u32_t flags, s32_t timeout)
|
||||
count = timeout / 1000 + 1;
|
||||
}
|
||||
|
||||
/* First make sure that network interface is up */
|
||||
if (check_interface(iface) == false) {
|
||||
k_sem_init(&counter, 1, UINT_MAX);
|
||||
|
||||
while (count--) {
|
||||
if (!k_sem_count_get(&counter)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (k_sem_take(&waiter, loop)) {
|
||||
if (!k_sem_count_get(&counter)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the above while() loop timeouted, reset the count so that
|
||||
* the while() loop below will not wait more.
|
||||
*/
|
||||
if (timeout > 0 && count < 0) {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_NATIVE)
|
||||
net_mgmt_del_event_callback(&mgmt_iface_cb);
|
||||
#endif
|
||||
}
|
||||
|
||||
setup_ipv4(iface);
|
||||
setup_dhcpv4(iface);
|
||||
setup_ipv6(iface, flags);
|
||||
|
||||
if (flags & NET_CONFIG_NEED_IPV6) {
|
||||
need++;
|
||||
}
|
||||
|
||||
if (flags & NET_CONFIG_NEED_IPV4) {
|
||||
need++;
|
||||
}
|
||||
|
||||
k_sem_init(&counter, need, UINT_MAX);
|
||||
|
||||
/* Loop here until we are ready to continue. As we might need
|
||||
* to wait multiple events, sleep smaller amounts of data.
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user