Beispiel #1
0
static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src,
                             struct os_reltime *fetch_time)
{
    struct ieee80211_ht_capabilities *capab;
    struct ieee80211_ht_operation *oper;
    struct ieee802_11_elems elems;

    dst->flags = src->flags;
    os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
    dst->freq = src->freq;
    dst->beacon_int = src->beacon_int;
    dst->caps = src->caps;
    dst->qual = src->qual;
    dst->noise = src->noise;
    dst->level = src->level;
    dst->tsf = src->tsf;
    dst->est_throughput = src->est_throughput;
    dst->snr = src->snr;

    memset(&elems, 0, sizeof(elems));
    ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0);
    capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities;
    oper = (struct ieee80211_ht_operation *) elems.ht_operation;
    if (capab)
        dst->ht_capab = le_to_host16(capab->ht_capabilities_info);
    if (oper)
        dst->ht_param = oper->ht_param;

    calculate_update_time(fetch_time, src->age, &dst->last_update);
}
static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src,
                             struct os_reltime *fetch_time)
{
    dst->flags = src->flags;
    os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
    dst->freq = src->freq;
    dst->beacon_int = src->beacon_int;
    dst->caps = src->caps;
    dst->qual = src->qual;
    dst->noise = src->noise;
    dst->level = src->level;
    dst->tsf = src->tsf;

    calculate_update_time(fetch_time, src->age, &dst->last_update);
}
Beispiel #3
0
/**
 * wpa_bss_update_scan_res - Update a BSS table entry based on a scan result
 * @wpa_s: Pointer to wpa_supplicant data
 * @res: Scan result
 * @fetch_time: Time when the result was fetched from the driver
 *
 * This function updates a BSS table entry (or adds one) based on a scan result.
 * This is called separately for each scan result between the calls to
 * wpa_bss_update_start() and wpa_bss_update_end().
 */
void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
			     struct wpa_scan_res *res,
			     struct os_reltime *fetch_time)
{
	const u8 *ssid, *p2p, *mesh;
	struct wpa_bss *bss;

	if (wpa_s->conf->ignore_old_scan_res) {
		struct os_reltime update;
		calculate_update_time(fetch_time, res->age, &update);
		if (os_reltime_before(&update, &wpa_s->scan_trigger_time)) {
			struct os_reltime age;
			os_reltime_sub(&wpa_s->scan_trigger_time, &update,
				       &age);
			wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Ignore driver BSS "
				"table entry that is %u.%06u seconds older "
				"than our scan trigger",
				(unsigned int) age.sec,
				(unsigned int) age.usec);
			return;
		}
	}

	ssid = wpa_scan_get_ie(res, WLAN_EID_SSID);
	if (ssid == NULL) {
		wpa_dbg(wpa_s, MSG_DEBUG, "BSS: No SSID IE included for "
			MACSTR, MAC2STR(res->bssid));
		return;
	}
	if (ssid[1] > SSID_MAX_LEN) {
		wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Too long SSID IE included for "
			MACSTR, MAC2STR(res->bssid));
		return;
	}

	p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE);
#ifdef CONFIG_P2P
	if (p2p == NULL &&
	    wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
		/*
		 * If it's a P2P specific interface, then don't update
		 * the scan result without a P2P IE.
		 */
		wpa_printf(MSG_DEBUG, "BSS: No P2P IE - skipping BSS " MACSTR
			   " update for P2P interface", MAC2STR(res->bssid));
		return;
	}
#endif /* CONFIG_P2P */
	if (p2p && ssid[1] == P2P_WILDCARD_SSID_LEN &&
	    os_memcmp(ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 0)
		return; /* Skip P2P listen discovery results here */

	/* TODO: add option for ignoring BSSes we are not interested in
	 * (to save memory) */

	mesh = wpa_scan_get_ie(res, WLAN_EID_MESH_ID);
	if (mesh && mesh[1] <= SSID_MAX_LEN)
		ssid = mesh;

	bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);
	if (bss == NULL)
		bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res, fetch_time);
	else {
		bss = wpa_bss_update(wpa_s, bss, res, fetch_time);
		if (wpa_s->last_scan_res) {
			unsigned int i;
			for (i = 0; i < wpa_s->last_scan_res_used; i++) {
				if (bss == wpa_s->last_scan_res[i]) {
					/* Already in the list */
					return;
				}
			}
		}
	}

	if (bss == NULL)
		return;
	if (wpa_s->last_scan_res_used >= wpa_s->last_scan_res_size) {
		struct wpa_bss **n;
		unsigned int siz;
		if (wpa_s->last_scan_res_size == 0)
			siz = 32;
		else
			siz = wpa_s->last_scan_res_size * 2;
		n = os_realloc_array(wpa_s->last_scan_res, siz,
				     sizeof(struct wpa_bss *));
		if (n == NULL)
			return;
		wpa_s->last_scan_res = n;
		wpa_s->last_scan_res_size = siz;
	}

	if (wpa_s->last_scan_res)
		wpa_s->last_scan_res[wpa_s->last_scan_res_used++] = bss;
}