P2P: Allow Device ID to be specified for p2p_find command
dev_id=<P2P Device Addr> can now be specified as an argument to p2p_find to request P2P find for a specific P2P device. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
68921e24b2
commit
6d92fa6e92
9 changed files with 55 additions and 23 deletions
|
@ -2832,7 +2832,7 @@ static int wpa_driver_test_p2p_find(void *priv, unsigned int timeout, int type)
|
||||||
wpa_printf(MSG_DEBUG, "%s(timeout=%u)", __func__, timeout);
|
wpa_printf(MSG_DEBUG, "%s(timeout=%u)", __func__, timeout);
|
||||||
if (!drv->p2p)
|
if (!drv->p2p)
|
||||||
return -1;
|
return -1;
|
||||||
return p2p_find(drv->p2p, timeout, type, 0, NULL);
|
return p2p_find(drv->p2p, timeout, type, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2918,7 +2918,7 @@ static int wpa_driver_test_p2p_set_params(void *priv,
|
||||||
|
|
||||||
static int test_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
static int test_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
||||||
unsigned int num_req_dev_types,
|
unsigned int num_req_dev_types,
|
||||||
const u8 *req_dev_types)
|
const u8 *req_dev_types, const u8 *dev_id)
|
||||||
{
|
{
|
||||||
struct wpa_driver_test_data *drv = ctx;
|
struct wpa_driver_test_data *drv = ctx;
|
||||||
struct wpa_driver_scan_params params;
|
struct wpa_driver_scan_params params;
|
||||||
|
@ -2956,7 +2956,7 @@ static int test_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
||||||
wpabuf_put_buf(ies, wps_ie);
|
wpabuf_put_buf(ies, wps_ie);
|
||||||
wpabuf_free(wps_ie);
|
wpabuf_free(wps_ie);
|
||||||
|
|
||||||
p2p_scan_ie(drv->p2p, ies);
|
p2p_scan_ie(drv->p2p, ies, dev_id);
|
||||||
|
|
||||||
params.extra_ies = wpabuf_head(ies);
|
params.extra_ies = wpabuf_head(ies);
|
||||||
params.extra_ies_len = wpabuf_len(ies);
|
params.extra_ies_len = wpabuf_len(ies);
|
||||||
|
|
|
@ -795,8 +795,8 @@ static void p2p_search(struct p2p_data *p2p)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
|
if (p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
|
||||||
p2p->num_req_dev_types, p2p->req_dev_types) < 0)
|
p2p->num_req_dev_types, p2p->req_dev_types,
|
||||||
{
|
p2p->find_dev_id) < 0) {
|
||||||
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
|
||||||
"P2P: Scan request failed");
|
"P2P: Scan request failed");
|
||||||
p2p_continue_find(p2p);
|
p2p_continue_find(p2p);
|
||||||
|
@ -895,7 +895,8 @@ static void p2p_free_req_dev_types(struct p2p_data *p2p)
|
||||||
|
|
||||||
int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
||||||
enum p2p_discovery_type type,
|
enum p2p_discovery_type type,
|
||||||
unsigned int num_req_dev_types, const u8 *req_dev_types)
|
unsigned int num_req_dev_types, const u8 *req_dev_types,
|
||||||
|
const u8 *dev_id)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -917,6 +918,12 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
||||||
p2p->num_req_dev_types = num_req_dev_types;
|
p2p->num_req_dev_types = num_req_dev_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev_id) {
|
||||||
|
os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN);
|
||||||
|
p2p->find_dev_id = p2p->find_dev_id_buf;
|
||||||
|
} else
|
||||||
|
p2p->find_dev_id = NULL;
|
||||||
|
|
||||||
p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
|
p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
|
||||||
p2p_clear_timeout(p2p);
|
p2p_clear_timeout(p2p);
|
||||||
p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
|
p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
|
||||||
|
@ -933,12 +940,12 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
||||||
case P2P_FIND_PROGRESSIVE:
|
case P2P_FIND_PROGRESSIVE:
|
||||||
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
|
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
|
||||||
p2p->num_req_dev_types,
|
p2p->num_req_dev_types,
|
||||||
p2p->req_dev_types);
|
p2p->req_dev_types, dev_id);
|
||||||
break;
|
break;
|
||||||
case P2P_FIND_ONLY_SOCIAL:
|
case P2P_FIND_ONLY_SOCIAL:
|
||||||
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
|
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
|
||||||
p2p->num_req_dev_types,
|
p2p->num_req_dev_types,
|
||||||
p2p->req_dev_types);
|
p2p->req_dev_types, dev_id);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -975,7 +982,8 @@ int p2p_other_scan_completed(struct p2p_data *p2p)
|
||||||
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find "
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find "
|
||||||
"now that previous scan was completed");
|
"now that previous scan was completed");
|
||||||
if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type,
|
if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type,
|
||||||
p2p->num_req_dev_types, p2p->req_dev_types) < 0)
|
p2p->num_req_dev_types, p2p->req_dev_types,
|
||||||
|
p2p->find_dev_id) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2533,10 +2541,12 @@ void p2p_scan_res_handled(struct p2p_data *p2p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies)
|
void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id)
|
||||||
{
|
{
|
||||||
u8 *len = p2p_buf_add_ie_hdr(ies);
|
u8 *len = p2p_buf_add_ie_hdr(ies);
|
||||||
p2p_buf_add_capability(ies, p2p->dev_capab, 0);
|
p2p_buf_add_capability(ies, p2p->dev_capab, 0);
|
||||||
|
if (dev_id)
|
||||||
|
p2p_buf_add_device_id(ies, dev_id);
|
||||||
if (p2p->cfg->reg_class && p2p->cfg->channel)
|
if (p2p->cfg->reg_class && p2p->cfg->channel)
|
||||||
p2p_buf_add_listen_channel(ies, p2p->cfg->country,
|
p2p_buf_add_listen_channel(ies, p2p->cfg->country,
|
||||||
p2p->cfg->reg_class,
|
p2p->cfg->reg_class,
|
||||||
|
|
|
@ -359,6 +359,7 @@ struct p2p_config {
|
||||||
* @freq: Specific frequency (MHz) to scan or 0 for no restriction
|
* @freq: Specific frequency (MHz) to scan or 0 for no restriction
|
||||||
* @num_req_dev_types: Number of requested device types
|
* @num_req_dev_types: Number of requested device types
|
||||||
* @req_dev_types: Array containing requested device types
|
* @req_dev_types: Array containing requested device types
|
||||||
|
* @dev_id: Device ID to search for or %NULL to find all devices
|
||||||
* Returns: 0 on success, -1 on failure
|
* Returns: 0 on success, -1 on failure
|
||||||
*
|
*
|
||||||
* This callback function is used to request a P2P scan or search
|
* This callback function is used to request a P2P scan or search
|
||||||
|
@ -382,7 +383,7 @@ struct p2p_config {
|
||||||
*/
|
*/
|
||||||
int (*p2p_scan)(void *ctx, enum p2p_scan_type type, int freq,
|
int (*p2p_scan)(void *ctx, enum p2p_scan_type type, int freq,
|
||||||
unsigned int num_req_dev_types,
|
unsigned int num_req_dev_types,
|
||||||
const u8 *req_dev_types);
|
const u8 *req_dev_types, const u8 *dev_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* send_probe_resp - Transmit a Probe Response frame
|
* send_probe_resp - Transmit a Probe Response frame
|
||||||
|
@ -809,11 +810,13 @@ enum p2p_discovery_type {
|
||||||
* @req_dev_types: Requested device types array, must be an array
|
* @req_dev_types: Requested device types array, must be an array
|
||||||
* containing num_req_dev_types * WPS_DEV_TYPE_LEN bytes; %NULL if no
|
* containing num_req_dev_types * WPS_DEV_TYPE_LEN bytes; %NULL if no
|
||||||
* requested device types.
|
* requested device types.
|
||||||
|
* @dev_id: Device ID to search for or %NULL to find all devices
|
||||||
* Returns: 0 on success, -1 on failure
|
* Returns: 0 on success, -1 on failure
|
||||||
*/
|
*/
|
||||||
int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
||||||
enum p2p_discovery_type type,
|
enum p2p_discovery_type type,
|
||||||
unsigned int num_req_dev_types, const u8 *req_dev_types);
|
unsigned int num_req_dev_types, const u8 *req_dev_types,
|
||||||
|
const u8 *dev_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* p2p_stop_find - Stop P2P Find (Device Discovery)
|
* p2p_stop_find - Stop P2P Find (Device Discovery)
|
||||||
|
@ -1376,8 +1379,9 @@ int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf,
|
||||||
* p2p_scan_ie - Build P2P IE for Probe Request
|
* p2p_scan_ie - Build P2P IE for Probe Request
|
||||||
* @p2p: P2P module context from p2p_init()
|
* @p2p: P2P module context from p2p_init()
|
||||||
* @ies: Buffer for writing P2P IE
|
* @ies: Buffer for writing P2P IE
|
||||||
|
* @dev_id: Device ID to search for or %NULL for any
|
||||||
*/
|
*/
|
||||||
void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies);
|
void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* p2p_scan_ie_buf_len - Get maximum buffer length needed for p2p_scan_ie
|
* p2p_scan_ie_buf_len - Get maximum buffer length needed for p2p_scan_ie
|
||||||
|
|
|
@ -381,6 +381,8 @@ struct p2p_data {
|
||||||
/* Requested device types for find/search */
|
/* Requested device types for find/search */
|
||||||
unsigned int num_req_dev_types;
|
unsigned int num_req_dev_types;
|
||||||
u8 *req_dev_types;
|
u8 *req_dev_types;
|
||||||
|
u8 *find_dev_id;
|
||||||
|
u8 find_dev_id_buf[ETH_ALEN];
|
||||||
|
|
||||||
struct p2p_group **groups;
|
struct p2p_group **groups;
|
||||||
size_t num_groups;
|
size_t num_groups;
|
||||||
|
|
|
@ -2451,13 +2451,23 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
{
|
{
|
||||||
unsigned int timeout = atoi(cmd);
|
unsigned int timeout = atoi(cmd);
|
||||||
enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
|
enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
|
||||||
|
u8 dev_id[ETH_ALEN], *_dev_id = NULL;
|
||||||
|
char *pos;
|
||||||
|
|
||||||
if (os_strstr(cmd, "type=social"))
|
if (os_strstr(cmd, "type=social"))
|
||||||
type = P2P_FIND_ONLY_SOCIAL;
|
type = P2P_FIND_ONLY_SOCIAL;
|
||||||
else if (os_strstr(cmd, "type=progressive"))
|
else if (os_strstr(cmd, "type=progressive"))
|
||||||
type = P2P_FIND_PROGRESSIVE;
|
type = P2P_FIND_PROGRESSIVE;
|
||||||
|
|
||||||
return wpas_p2p_find(wpa_s, timeout, type, 0, NULL);
|
pos = os_strstr(cmd, "dev_id=");
|
||||||
|
if (pos) {
|
||||||
|
pos += 7;
|
||||||
|
if (hwaddr_aton(pos, dev_id))
|
||||||
|
return -1;
|
||||||
|
_dev_id = dev_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,8 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
|
||||||
wpa_dbus_dict_entry_clear(&entry);
|
wpa_dbus_dict_entry_clear(&entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types);
|
wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types,
|
||||||
|
NULL);
|
||||||
os_free(req_dev_types);
|
os_free(req_dev_types);
|
||||||
return reply;
|
return reply;
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
||||||
unsigned int num_req_dev_types,
|
unsigned int num_req_dev_types,
|
||||||
const u8 *req_dev_types)
|
const u8 *req_dev_types, const u8 *dev_id)
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
struct wpa_driver_scan_params params;
|
struct wpa_driver_scan_params params;
|
||||||
|
@ -130,7 +130,7 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
||||||
wpabuf_put_buf(ies, wps_ie);
|
wpabuf_put_buf(ies, wps_ie);
|
||||||
wpabuf_free(wps_ie);
|
wpabuf_free(wps_ie);
|
||||||
|
|
||||||
p2p_scan_ie(wpa_s->global->p2p, ies);
|
p2p_scan_ie(wpa_s->global->p2p, ies, dev_id);
|
||||||
|
|
||||||
params.p2p_probe = 1;
|
params.p2p_probe = 1;
|
||||||
params.extra_ies = wpabuf_head(ies);
|
params.extra_ies = wpabuf_head(ies);
|
||||||
|
@ -2667,7 +2667,7 @@ static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
|
||||||
wpabuf_put_buf(ies, wps_ie);
|
wpabuf_put_buf(ies, wps_ie);
|
||||||
wpabuf_free(wps_ie);
|
wpabuf_free(wps_ie);
|
||||||
|
|
||||||
p2p_scan_ie(wpa_s->global->p2p, ies);
|
p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
|
||||||
|
|
||||||
params.p2p_probe = 1;
|
params.p2p_probe = 1;
|
||||||
params.extra_ies = wpabuf_head(ies);
|
params.extra_ies = wpabuf_head(ies);
|
||||||
|
@ -3459,7 +3459,8 @@ static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
|
||||||
|
|
||||||
int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
|
int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
|
||||||
enum p2p_discovery_type type,
|
enum p2p_discovery_type type,
|
||||||
unsigned int num_req_dev_types, const u8 *req_dev_types)
|
unsigned int num_req_dev_types, const u8 *req_dev_types,
|
||||||
|
const u8 *dev_id)
|
||||||
{
|
{
|
||||||
wpas_p2p_clear_pending_action_tx(wpa_s);
|
wpas_p2p_clear_pending_action_tx(wpa_s);
|
||||||
wpa_s->p2p_long_listen = 0;
|
wpa_s->p2p_long_listen = 0;
|
||||||
|
@ -3471,7 +3472,7 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return p2p_find(wpa_s->global->p2p, timeout, type,
|
return p2p_find(wpa_s->global->p2p, timeout, type,
|
||||||
num_req_dev_types, req_dev_types);
|
num_req_dev_types, req_dev_types, dev_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3599,7 +3600,7 @@ void wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies)
|
||||||
if (wpa_s->global->p2p == NULL)
|
if (wpa_s->global->p2p == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p2p_scan_ie(wpa_s->global->p2p, ies);
|
p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,8 @@ int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
|
||||||
enum p2p_discovery_type;
|
enum p2p_discovery_type;
|
||||||
int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
|
int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
|
||||||
enum p2p_discovery_type type,
|
enum p2p_discovery_type type,
|
||||||
unsigned int num_req_dev_types, const u8 *req_dev_types);
|
unsigned int num_req_dev_types, const u8 *req_dev_types,
|
||||||
|
const u8 *dev_id);
|
||||||
void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s);
|
void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s);
|
||||||
int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
|
int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
|
||||||
int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
|
|
|
@ -1930,7 +1930,10 @@ static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
return wpa_ctrl_command(ctrl, "P2P_FIND");
|
return wpa_ctrl_command(ctrl, "P2P_FIND");
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 2)
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2]);
|
||||||
|
else if (argc > 1)
|
||||||
res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
|
res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
|
||||||
argv[0], argv[1]);
|
argv[0], argv[1]);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue