/* This function is a wrapper for gettimeofday(). It uses local storage to * guarantee that the returned time will always be monotonic. If the time goes * backwards, it returns the same as previous one and readjust its internal * drift. If the time goes forward further than TIME_MAX_FORWARD_US * microseconds since last call, it will bound it to that value. It is designed * to be used as a drop-in replacement of gettimeofday(&now, NULL). It will * normally return 0, unless <now> is NULL, in which case it will return -1 and * set errno to EFAULT. */ static int monotonic_gettimeofday(timeval_t *now) { static timeval_t mono_date; static timeval_t drift; /* warning: signed seconds! */ timeval_t sys_date, adjusted, deadline; if (!now) { errno = EFAULT; return -1; } timer_reset_lazy(*now); gettimeofday(&sys_date, NULL); /* on first call, we set mono_date to system date */ if (mono_date.tv_sec == 0) { mono_date = sys_date; timer_reset(drift); *now = mono_date; return 0; } /* compute new adjusted time by adding the drift offset */ adjusted = timer_add(sys_date, drift); /* check for jumps in the past, and bound to last date */ if (timer_cmp(adjusted, mono_date) < 0) goto fixup; /* check for jumps too far in the future, and bound them to * TIME_MAX_FORWARD_US microseconds. */ deadline = timer_add_long(mono_date, TIME_MAX_FORWARD_US); if (timer_cmp (adjusted, deadline) >= 0) { mono_date = deadline; goto fixup; } /* adjusted date is correct */ mono_date = adjusted; *now = mono_date; return 0; fixup: /* Now we have to recompute the drift between sys_date and * mono_date. Since it can be negative and we don't want to * play with negative carries in all computations, we take * care of always having the microseconds positive. */ drift = timer_sub(mono_date, sys_date); *now = mono_date; return 0; }
/* Timer functions */ static timeval_t vrrp_compute_timer(const int fd) { vrrp_t *vrrp; element e; list l = &vrrp_data->vrrp_index_fd[fd%1024 + 1]; timeval_t timer; /* Multiple instances on the same interface */ timer_reset(timer); for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vrrp = ELEMENT_DATA(e); if (timer_cmp(vrrp->sands, timer) < 0 || timer_isnull(timer)) timer = timer_dup(vrrp->sands); } return timer; }
/* Timer functions */ static TIMEVAL vrrp_compute_timer(const int fd) { vrrp_rt *vrrp; element e; list l = &vrrp_data->vrrp_index_fd[fd%1024 + 1]; TIMEVAL timer; /* Multiple instances on the same interface */ TIMER_RESET(timer); for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vrrp = ELEMENT_DATA(e); if (timer_cmp(vrrp->sands, timer) < 0 || TIMER_ISNULL(timer)) timer = timer_dup(vrrp->sands); } return timer; }
/* WPS main processing thread * */ static void wps_main(os_thread_arg_t data) { #ifdef CONFIG_P2P struct timeval tv, now; WPS_DATA *wps_s = (WPS_DATA *) &wps_global; WFD_DATA *pwfd_data = &wps_global.wfd_data; bss_config_t bss_config; #endif int ret; #ifdef CONFIG_WPA2_ENTP struct wpa2_command *wpa2_cmd = NULL; WPS_DATA *wps_s = (WPS_DATA *) &wps_global; #else struct wps_command *wps_cmd = NULL; #endif #ifdef CONFIG_P2P memset(&bss_config, 0, sizeof(bss_config_t)); /* * Download Wfd configuration if supplied with -p command line. */ if (local_wcc->role == WFD_ROLE) { if (wfd_wlan_update_bss_mode(BSS_MODE_WIFIDIRECT_GO) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to initialize " "BSS Mode!\n"); goto fail; } /* Set WFD uAP configuration */ wifidirectapcmd_sys_config(); if (wfd_wlan_update_bss_mode(BSS_MODE_WIFIDIRECT_CLIENT) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to initialize " "BSS Mode!\n"); goto fail; } /* Set WFD configuration */ wifidirectcmd_config(); if (wfd_set_mode(WFD_MODE_START) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize WFD!\n"); goto fail; } if (auto_go) { if (wfd_wlan_update_bss_mode(BSS_MODE_WIFIDIRECT_GO) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize BSS Mode!\n"); goto fail; } if (wfd_set_mode(WFD_MODE_START_GROUP_OWNER) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize WFD!\n"); goto fail; } if (!wps_s->current_ssid.ssid_len) { apcmd_get_bss_config(&bss_config); load_cred_info(wps_s, gpwps_info, &bss_config); /* * For Wi-Fi Direct, we need to * convert the passphrase to PSK. * * Hence update the default * passphrase */ wlan_generate_psk(gpwps_info); } if (wps.cb(P2P_AUTO_GO_STARTED, &WFD_devicename, strlen(WFD_devicename)) == -WM_FAIL) P2P_LOG("WFD Callback failed for " "event: %d\r\n", P2P_AUTO_GO_STARTED); if (wlan_add_network(&p2p_uap_network) != WLAN_ERROR_NONE) { wps_printf(MSG_ERROR, "failed to add " "wfd network\r\n"); goto fail; } if (wlan_start_network(p2p_uap_network.name) != WLAN_ERROR_NONE) { wps_printf(MSG_ERROR, "failed to start " "wfd network\r\n"); goto fail; } } else { mlanconfig_bgscan(1); if (wfd_set_mode(WFD_MODE_START_FIND_PHASE) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize WFD!\n"); goto fail; } wps_set_wfd_cfg(); if (wps.cb(P2P_DEVICE_STARTED, &WFD_devicename, strlen(WFD_devicename)) == -WM_FAIL) P2P_LOG("WFD Callback failed for " "event: %d\r\n", P2P_DEVICE_STARTED); wfd_start_peer_ageout_timer(pwfd_data); p2p_scan_on = 1; } } #endif #ifndef CONFIG_P2P if (wps.cb(WPS_STARTED, NULL, 0) == -WM_FAIL) WPS_LOG("WPS Callback failed for event: %d\r\n", WPS_STARTED); #endif #ifndef CONFIG_WPA2_ENTP wps_register_rx_callback(WPSEAPoLRxDataHandler); #endif while (1) { #ifdef CONFIG_WPA2_ENTP ret = os_queue_recv(&wps.cmd_queue, &wpa2_cmd, RX_WAIT); if (ret != WM_SUCCESS || wpa2_cmd == NULL) continue; #else #ifdef CONFIG_P2P if (!auto_go && p2p_scan_on) { if (wps_loop.timeout) { now.tv_sec = os_ticks_to_msec(os_ticks_get()) / 1000; now.tv_usec = (os_ticks_to_msec (os_ticks_get()) % 1000) * 1000; if (timer_cmp(&now, &wps_loop.timeout->time)) timersub(&wps_loop.timeout->time, &now, &tv); else tv.tv_sec = tv.tv_usec = 0; } /* check if some registered timeouts have occurred */ if (wps_loop.timeout) { struct wps_timeout_s *tmp; now.tv_sec = os_ticks_to_msec(os_ticks_get()) / 1000; now.tv_usec = (os_ticks_to_msec (os_ticks_get()) % 1000) * 1000; if (!timer_cmp(&now, &wps_loop.timeout->time)) { tmp = wps_loop.timeout; wps_loop.timeout = wps_loop.timeout->next; tmp->handler(tmp->callback_data); wps_mem_free(tmp); } } } if (go_request) { p2p_scan_on = 0; g_method = CMD_WPS_PBC; wps_init(); go_request = 0; } ret = os_queue_recv(&wps.cmd_queue, &wps_cmd, os_msec_to_ticks(1000)); #else ret = os_queue_recv(&wps.cmd_queue, &wps_cmd, RX_WAIT); #endif if (ret != WM_SUCCESS || wps_cmd == NULL) continue; #endif #ifdef CONFIG_WPA2_ENTP memcpy(&wps_s->wpa2_network, &wpa2_cmd->wpa2_network, sizeof(struct wlan_network)); wps_mem_free(wpa2_cmd); g_method = CMD_WPS_PBC; ret = wps_private_info_allocate(&gpwps_info); ret = wps_init(); continue; #else g_method = wps_cmd->command; g_channel = wps_cmd->res.channel; #ifdef CONFIG_P2P g_bssid = (u8 *) wps_cmd->res.bssid; g_ssid = (u8 *) wps_cmd->res.ssid; #else memcpy(g_ssid, (u8 *) wps_cmd->res.ssid, MAX_SSID_LEN + 1); memcpy(g_bssid, (u8 *) wps_cmd->res.bssid, ETH_ALEN); #endif wps_mem_free(wps_cmd); switch (g_method) { case CMD_WPS_PIN: g_gen_pin = wps_cmd->wps_pin; wps_init(); break; case CMD_WPS_PBC: wps_init(); break; } #endif } #ifdef CONFIG_P2P fail: if (wps.cb(P2P_FAILED, NULL, 0) == -WM_FAIL) P2P_LOG("WPS Callback failed for event: %d\r\n", P2P_FAILED); wps_stop(); #endif }