hostapd-2.0/src/drivers/driver_nl80211.c
static int wpa_driver_nl80211_sched_scan(void *priv,
					 struct wpa_driver_scan_params *params,
					 u32 interval)
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	int ret = -1;
	struct nl_msg *msg;
	struct nl_msg *match_set_ssid = NULL, *match_sets = NULL;
	struct nl_msg *match_set_rssi = NULL;
	size_t i;

#ifdef ANDROID
	if (!drv->capa.sched_scan_supported)
		return android_pno_start(bss, params);
#endif /* ANDROID */

	msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params);
	if (!msg)
		goto nla_put_failure;

	NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);

	if ((drv->num_filter_ssids &&
	    (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
	    params->filter_rssi) {
		match_sets = nlmsg_alloc();
		if (match_sets == NULL)
			goto nla_put_failure;

		for (i = 0; i < drv->num_filter_ssids; i++) {
			wpa_hexdump_ascii(MSG_MSGDUMP,
					  "nl80211: Sched scan filter SSID",
					  drv->filter_ssids[i].ssid,
					  drv->filter_ssids[i].ssid_len);

			match_set_ssid = nlmsg_alloc();
			if (match_set_ssid == NULL)
				goto nla_put_failure;
			NLA_PUT(match_set_ssid,
				NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
				drv->filter_ssids[i].ssid_len,
				drv->filter_ssids[i].ssid);

			if (nla_put_nested(match_sets, i + 1, match_set_ssid) <
			    0)
				goto nla_put_failure;
		}

		if (params->filter_rssi) {
			match_set_rssi = nlmsg_alloc();
			if (match_set_rssi == NULL)
				goto nla_put_failure;
			NLA_PUT_U32(match_set_rssi,
				    NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
				    params->filter_rssi);
			wpa_printf(MSG_MSGDUMP,
				   "nl80211: Sched scan RSSI filter %d dBm",
				   params->filter_rssi);
			if (nla_put_nested(match_sets, 0, match_set_rssi) < 0)
				goto nla_put_failure;
		}

		if (nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH,
				   match_sets) < 0)
			goto nla_put_failure;
	}

	ret = send_and_recv_msgs(drv, msg, NULL, NULL);

	/* TODO: if we get an error here, we should fall back to normal scan */

	msg = NULL;
	if (ret) {
		wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
			   "ret=%d (%s)", ret, strerror(-ret));
		goto nla_put_failure;
	}

	wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
		   "scan interval %d msec", ret, interval);

nla_put_failure:
	nlmsg_free(match_set_ssid);
	nlmsg_free(match_sets);
	nlmsg_free(match_set_rssi);
	nlmsg_free(msg);
	return ret;
}
/**
 * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
 * @params: Scan parameters
 * @interval: Interval between scan cycles in milliseconds
 * Returns: 0 on success, -1 on failure or if not supported
 */
Initiate a scheduled scan
@priv: Pointer to private driver data from wpa_driver_nl80211_init()
@params: Scan parameters
@interval: Interval between scan cycles in milliseconds
Returns: 0 on success, -1 on failure or if not supported
Initiate a scheduled scan @priv : Pointer to private driver data from wpa_driver_nl80211_init () @params : Scan parameters @interval : Interval between scan cycles in milliseconds Returns : 0 on success - 1 on failure or if not supported
static int wpa_driver_nl80211_sched_scan(void *priv,
					 struct wpa_driver_scan_params *params,
					 u32 interval)
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	int ret = -1;
	struct nl_msg *msg;
	struct nl_msg *match_set_ssid = NULL, *match_sets = NULL;
	struct nl_msg *match_set_rssi = NULL;
	size_t i;
#ifdef ANDROID
	if (!drv->capa.sched_scan_supported)
		return android_pno_start(bss, params);
#endif 
	msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params);
	if (!msg)
		goto nla_put_failure;
	NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
	if ((drv->num_filter_ssids &&
	    (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
	    params->filter_rssi) {
		match_sets = nlmsg_alloc();
		if (match_sets == NULL)
			goto nla_put_failure;
		for (i = 0; i < drv->num_filter_ssids; i++) {
			wpa_hexdump_ascii(MSG_MSGDUMP,
					  "nl80211: Sched scan filter SSID",
					  drv->filter_ssids[i].ssid,
					  drv->filter_ssids[i].ssid_len);
			match_set_ssid = nlmsg_alloc();
			if (match_set_ssid == NULL)
				goto nla_put_failure;
			NLA_PUT(match_set_ssid,
				NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
				drv->filter_ssids[i].ssid_len,
				drv->filter_ssids[i].ssid);
			if (nla_put_nested(match_sets, i + 1, match_set_ssid) <
			    0)
				goto nla_put_failure;
		}
		if (params->filter_rssi) {
			match_set_rssi = nlmsg_alloc();
			if (match_set_rssi == NULL)
				goto nla_put_failure;
			NLA_PUT_U32(match_set_rssi,
				    NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
				    params->filter_rssi);
			wpa_printf(MSG_MSGDUMP,
				   "nl80211: Sched scan RSSI filter %d dBm",
				   params->filter_rssi);
			if (nla_put_nested(match_sets, 0, match_set_rssi) < 0)
				goto nla_put_failure;
		}
		if (nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH,
				   match_sets) < 0)
			goto nla_put_failure;
	}
	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
	msg = NULL;
	if (ret) {
		wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
			   "ret=%d (%s)", ret, strerror(-ret));
		goto nla_put_failure;
	}
	wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
		   "scan interval %d msec", ret, interval);
nla_put_failure:
	nlmsg_free(match_set_ssid);
	nlmsg_free(match_sets);
	nlmsg_free(match_set_rssi);
	nlmsg_free(msg);
	return ret;
}
static int wpa_driver_nl80211_sched_scan ( void * priv , struct wpa_driver_scan_params * params , u32 interval ) { struct i802_bss * bss = priv ; struct wpa_driver_nl80211_data * drv = bss -> drv ; int ret = -1 ; struct nl_msg * msg ; struct nl_msg * match_set_ssid = NULL , * match_sets = NULL ; struct nl_msg * match_set_rssi = NULL ; size_t i ; #ifdef ANDROID if ( ! drv -> capa . sched_scan_supported ) return android_pno_start ( bss , params ) ; #endif msg = nl80211_scan_common ( drv , NL80211_CMD_START_SCHED_SCAN , params ) ; if ( ! msg ) goto nla_put_failure ; NLA_PUT_U32 ( msg , NL80211_ATTR_SCHED_SCAN_INTERVAL , interval ) ; if ( ( drv -> num_filter_ssids && ( int ) drv -> num_filter_ssids <= drv -> capa . max_match_sets ) || params -> filter_rssi ) { match_sets = nlmsg_alloc ( ) ; if ( match_sets == NULL ) goto nla_put_failure ; for ( i = 0 ; i < drv -> num_filter_ssids ; i ++ ) { wpa_hexdump_ascii ( MSG_MSGDUMP , " " , drv -> filter_ssids [ i ] . ssid , drv -> filter_ssids [ i ] . ssid_len ) ; match_set_ssid = nlmsg_alloc ( ) ; if ( match_set_ssid == NULL ) goto nla_put_failure ; NLA_PUT ( match_set_ssid , NL80211_ATTR_SCHED_SCAN_MATCH_SSID , drv -> filter_ssids [ i ] . ssid_len , drv -> filter_ssids [ i ] . ssid ) ; if ( nla_put_nested ( match_sets , i + 1 , match_set_ssid ) < 0 ) goto nla_put_failure ; } if ( params -> filter_rssi ) { match_set_rssi = nlmsg_alloc ( ) ; if ( match_set_rssi == NULL ) goto nla_put_failure ; NLA_PUT_U32 ( match_set_rssi , NL80211_SCHED_SCAN_MATCH_ATTR_RSSI , params -> filter_rssi ) ; wpa_printf ( MSG_MSGDUMP , " " , params -> filter_rssi ) ; if ( nla_put_nested ( match_sets , 0 , match_set_rssi ) < 0 ) goto nla_put_failure ; } if ( nla_put_nested ( msg , NL80211_ATTR_SCHED_SCAN_MATCH , match_sets ) < 0 ) goto nla_put_failure ; } ret = send_and_recv_msgs ( drv , msg , NULL , NULL ) ; msg = NULL ; if ( ret ) { wpa_printf ( MSG_DEBUG , " " " " , ret , strerror ( - ret ) ) ; goto nla_put_failure ; } wpa_printf ( MSG_DEBUG , " " " " , ret , interval ) ; nla_put_failure : nlmsg_free ( match_set_ssid ) ; nlmsg_free ( match_sets ) ; nlmsg_free ( match_set_rssi ) ; nlmsg_free ( msg ) ; return ret ; }
wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
 @priv: Pointer to private driver data from wpa_driver_nl80211_init()
 @params: Scan parameters
 @interval: Interval between scan cycles in milliseconds
 Returns: 0 on success, -1 on failure or if not supported
wpa_driver_nl80211_sched_scan - Initiate a scheduled scan @priv : Pointer to private driver data from wpa_driver_nl80211_init () @params : Scan parameters @interval : Interval between scan cycles in milliseconds Returns : 0 on success - 1 on failure or if not supported
/* ANDROID */ /* TODO: if we get an error here, we should fall back to normal scan */