P2PS: ASP provisioning commands to control interface

This adds new wpa_supplicant control interface commands
P2P_ASP_PROVISION and P2P_ASP_PROVISION_RESP.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Krishna Vamsi 2014-12-10 15:04:32 +05:30 committed by Jouni Malinen
parent 6d9085145c
commit f309c18e50
2 changed files with 173 additions and 0 deletions

View file

@ -4549,6 +4549,153 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
} }
static struct p2ps_provision * p2p_parse_asp_provision_cmd(const char *cmd)
{
struct p2ps_provision *p2ps_prov;
char *pos;
size_t info_len = 0;
char *info = NULL;
u8 role = P2PS_SETUP_NONE;
long long unsigned val;
pos = os_strstr(cmd, "info=");
if (pos) {
pos += 5;
info_len = os_strlen(pos);
if (info_len) {
info = os_malloc(info_len + 1);
if (info) {
info_len = utf8_unescape(pos, info_len,
info, info_len + 1);
} else
info_len = 0;
}
}
p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + info_len + 1);
if (p2ps_prov == NULL) {
os_free(info);
return NULL;
}
if (info) {
os_memcpy(p2ps_prov->info, info, info_len);
p2ps_prov->info[info_len] = '\0';
os_free(info);
}
pos = os_strstr(cmd, "status=");
if (pos)
p2ps_prov->status = atoi(pos + 7);
else
p2ps_prov->status = -1;
pos = os_strstr(cmd, "adv_id=");
if (!pos || sscanf(pos + 7, "%llx", &val) != 1 || val > 0xffffffffULL)
goto invalid_args;
p2ps_prov->adv_id = val;
pos = os_strstr(cmd, "method=");
if (pos)
p2ps_prov->method = strtol(pos + 7, NULL, 16);
else
p2ps_prov->method = 0;
pos = os_strstr(cmd, "session=");
if (!pos || sscanf(pos + 8, "%llx", &val) != 1 || val > 0xffffffffULL)
goto invalid_args;
p2ps_prov->session_id = val;
pos = os_strstr(cmd, "adv_mac=");
if (!pos || hwaddr_aton(pos + 8, p2ps_prov->adv_mac))
goto invalid_args;
pos = os_strstr(cmd, "session_mac=");
if (!pos || hwaddr_aton(pos + 12, p2ps_prov->session_mac))
goto invalid_args;
/* force conncap with tstCap (no sanity checks) */
pos = os_strstr(cmd, "tstCap=");
if (pos) {
role = strtol(pos + 7, NULL, 16);
} else {
pos = os_strstr(cmd, "role=");
if (pos) {
role = strtol(pos + 5, NULL, 16);
if (role != P2PS_SETUP_CLIENT &&
role != P2PS_SETUP_GROUP_OWNER)
role = P2PS_SETUP_NONE;
}
}
p2ps_prov->role = role;
return p2ps_prov;
invalid_args:
os_free(p2ps_prov);
return NULL;
}
static int p2p_ctrl_asp_provision_resp(struct wpa_supplicant *wpa_s, char *cmd)
{
u8 addr[ETH_ALEN];
struct p2ps_provision *p2ps_prov;
char *pos;
/* <addr> id=<adv_id> [role=<conncap>] [info=<infodata>] */
wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd);
if (hwaddr_aton(cmd, addr))
return -1;
pos = cmd + 17;
if (*pos != ' ')
return -1;
p2ps_prov = p2p_parse_asp_provision_cmd(pos);
if (!p2ps_prov)
return -1;
if (p2ps_prov->status < 0) {
os_free(p2ps_prov);
return -1;
}
return wpas_p2p_prov_disc(wpa_s, addr, NULL, WPAS_P2P_PD_FOR_ASP,
p2ps_prov);
}
static int p2p_ctrl_asp_provision(struct wpa_supplicant *wpa_s, char *cmd)
{
u8 addr[ETH_ALEN];
struct p2ps_provision *p2ps_prov;
char *pos;
/* <addr> id=<adv_id> adv_mac=<adv_mac> conncap=<conncap>
* session=<ses_id> mac=<ses_mac> [info=<infodata>]
*/
wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd);
if (hwaddr_aton(cmd, addr))
return -1;
pos = cmd + 17;
if (*pos != ' ')
return -1;
p2ps_prov = p2p_parse_asp_provision_cmd(pos);
if (!p2ps_prov)
return -1;
return wpas_p2p_prov_disc(wpa_s, addr, NULL, WPAS_P2P_PD_FOR_ASP,
p2ps_prov);
}
static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
char *buf, size_t buflen) char *buf, size_t buflen)
{ {
@ -7856,6 +8003,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = -1; reply_len = -1;
} else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) { } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
wpas_p2p_stop_find(wpa_s); wpas_p2p_stop_find(wpa_s);
} else if (os_strncmp(buf, "P2P_ASP_PROVISION ", 18) == 0) {
if (p2p_ctrl_asp_provision(wpa_s, buf + 18))
reply_len = -1;
} else if (os_strncmp(buf, "P2P_ASP_PROVISION_RESP ", 23) == 0) {
if (p2p_ctrl_asp_provision_resp(wpa_s, buf + 23))
reply_len = -1;
} else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) { } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply, reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
reply_size); reply_size);

View file

@ -1825,6 +1825,20 @@ static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
} }
static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
}
static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
}
static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
char *argv[]) char *argv[])
{ {
@ -2878,6 +2892,12 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
"[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
{ "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
"= stop P2P Devices search" }, "= stop P2P Devices search" },
{ "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
cli_cmd_flag_none,
"<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
{ "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
cli_cmd_flag_none,
"<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
{ "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
cli_cmd_flag_none, cli_cmd_flag_none,
"<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },