示例#1
0
文件: timer.c 项目: DStape/keepalived
/* 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;
}
示例#2
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;
}
示例#3
0
/* 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;
}
示例#4
0
/* 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
}