diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index 89aee7df1..bd65dd874 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -1321,7 +1321,8 @@ static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx) for (i = 0; i < drv->num_scanres; i++) { struct wpa_scan_res *bss = drv->scanres[i]; if (p2p_scan_res_handler(drv->p2p, bss->bssid, - bss->freq, bss->level, + bss->freq, bss->age, + bss->level, (const u8 *) (bss + 1), bss->ie_len) > 0) return; diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 22760d91e..47f8593cc 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -583,6 +583,7 @@ static void p2p_copy_wps_info(struct p2p_device *dev, int probe_req, * P2P Device Address or P2P Interface Address) * @level: Signal level (signal strength of the received frame from the peer) * @freq: Frequency on which the Beacon or Probe Response frame was received + * @age_ms: Age of the information in milliseconds * @ies: IEs from the Beacon or Probe Response frame * @ies_len: Length of ies buffer in octets * @scan_res: Whether this was based on scan results @@ -593,13 +594,15 @@ static void p2p_copy_wps_info(struct p2p_device *dev, int probe_req, * like Provision Discovery Request that contains P2P Capability and P2P Device * Info attributes. */ -int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level, - const u8 *ies, size_t ies_len, int scan_res) +int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, + unsigned int age_ms, int level, const u8 *ies, + size_t ies_len, int scan_res) { struct p2p_device *dev; struct p2p_message msg; const u8 *p2p_dev_addr; int i; + struct os_time time_now, time_tmp_age, entry_ts; os_memset(&msg, 0, sizeof(msg)); if (p2p_parse_ies(ies, ies_len, &msg)) { @@ -634,7 +637,22 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level, p2p_parse_free(&msg); return -1; } - os_get_time(&dev->last_seen); + + os_get_time(&time_now); + time_tmp_age.sec = age_ms / 1000; + time_tmp_age.usec = (age_ms % 1000) * 1000; + os_time_sub(&time_now, &time_tmp_age, &entry_ts); + + /* + * Update the device entry only if the new peer + * entry is newer than the one previously stored. + */ + if (dev->last_seen.usec > 0 && + os_time_before(&entry_ts, &dev->last_seen)) + return -1; + + os_memcpy(&dev->last_seen, &entry_ts, sizeof(struct os_time)); + dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) @@ -2723,9 +2741,10 @@ static void p2p_prov_disc_cb(struct p2p_data *p2p, int success) int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, - int level, const u8 *ies, size_t ies_len) + unsigned int age, int level, const u8 *ies, + size_t ies_len) { - p2p_add_device(p2p, bssid, freq, level, ies, ies_len, 1); + p2p_add_device(p2p, bssid, freq, age, level, ies, ies_len, 1); return 0; } diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 8b2aab2d1..2d8b2c257 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1183,6 +1183,7 @@ void p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, * @p2p: P2P module context from p2p_init() * @bssid: BSSID of the scan result * @freq: Frequency of the channel on which the device was found in MHz + * @age: Age of the scan result in milliseconds * @level: Signal level (signal strength of the received Beacon/Probe Response * frame) * @ies: Pointer to IEs from the scan result @@ -1204,7 +1205,8 @@ void p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, * start of a pending operation, e.g., to start a pending GO negotiation. */ int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, - int level, const u8 *ies, size_t ies_len); + unsigned int age, int level, const u8 *ies, + size_t ies_len); /** * p2p_scan_res_handled - Indicate end of scan results diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index c38eb3bde..27fef0182 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -692,8 +692,9 @@ struct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, struct p2p_message *msg); void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, struct p2p_device *dev, struct p2p_message *msg); -int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level, - const u8 *ies, size_t ies_len, int scan_res); +int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, + unsigned int age_ms, int level, const u8 *ies, + size_t ies_len, int scan_res); struct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr); struct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, const u8 *addr); diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index e06ba12ca..983dd6b36 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -176,8 +176,8 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, "P2P: Invitation Request from unknown peer " MACSTR, MAC2STR(sa)); - if (p2p_add_device(p2p, sa, rx_freq, 0, data + 1, len - 1, 0)) - { + if (p2p_add_device(p2p, sa, rx_freq, 0, 0, data + 1, len - 1, + 0)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Invitation Request add device failed " MACSTR, MAC2STR(sa)); diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index e40f2b716..d28efd1e8 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -151,8 +151,9 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision Discovery Request from " "unknown peer " MACSTR, MAC2STR(sa)); - if (p2p_add_device(p2p, sa, rx_freq, 0, data + 1, len - 1, 0)) - { + + if (p2p_add_device(p2p, sa, rx_freq, 0, 0, data + 1, len - 1, + 0)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision Discovery Request add device " "failed " MACSTR, MAC2STR(sa)); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index eefeac60c..202857b91 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -105,7 +105,7 @@ static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s, for (i = 0; i < scan_res->num; i++) { struct wpa_scan_res *bss = scan_res->res[i]; if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid, - bss->freq, bss->level, + bss->freq, bss->age, bss->level, (const u8 *) (bss + 1), bss->ie_len) > 0) break;