WPS ER: Fetch AP's M1 to learn device type and WPS state

This commit is contained in:
Jouni Malinen 2009-11-21 13:13:02 +02:00
parent 52a45d20dd
commit c3016248f4

View file

@ -66,6 +66,8 @@ struct wps_er_ap {
struct wps_data *wps;
u8 uuid[WPS_UUID_LEN];
u8 pri_dev_type[8];
u8 wps_state;
char *friendly_name;
char *manufacturer;
char *manufacturer_url;
@ -85,6 +87,8 @@ struct wps_er_ap {
unsigned int id;
struct wps_credential *ap_settings;
void (*m1_handler)(struct wps_er_ap *ap, struct wpabuf *m1);
};
struct wps_er {
@ -104,6 +108,9 @@ struct wps_er {
static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg);
static int wps_er_send_get_device_info(struct wps_er_ap *ap,
void (*m1_handler)(struct wps_er_ap *ap,
struct wpabuf *m1));
static void wps_er_sta_event(struct wps_context *wps, struct wps_er_sta *sta,
@ -377,6 +384,29 @@ static void wps_er_subscribe(struct wps_er_ap *ap)
}
static void wps_er_ap_get_m1(struct wps_er_ap *ap, struct wpabuf *m1)
{
struct wps_parse_attr attr;
if (wps_parse_msg(m1, &attr) < 0) {
wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse M1");
return;
}
if (attr.primary_dev_type)
os_memcpy(ap->pri_dev_type, attr.primary_dev_type, 8);
if (attr.wps_state)
ap->wps_state = *attr.wps_state;
wps_er_subscribe(ap);
}
static void wps_er_get_device_info(struct wps_er_ap *ap)
{
wps_er_send_get_device_info(ap, wps_er_ap_get_m1);
}
static void wps_er_parse_device_description(struct wps_er_ap *ap,
struct wpabuf *reply)
{
@ -443,7 +473,7 @@ static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c,
{
struct wps_er_ap *ap = ctx;
struct wpabuf *reply;
int subscribe = 0;
int ok = 0;
switch (event) {
case HTTP_CLIENT_OK:
@ -451,7 +481,7 @@ static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c,
if (reply == NULL)
break;
wps_er_parse_device_description(ap, reply);
subscribe = 1;
ok = 1;
break;
case HTTP_CLIENT_FAILED:
case HTTP_CLIENT_INVALID_REPLY:
@ -461,8 +491,8 @@ static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c,
}
http_client_free(ap->http);
ap->http = NULL;
if (subscribe)
wps_er_subscribe(ap);
if (ok)
wps_er_get_device_info(ap);
}
@ -1560,11 +1590,33 @@ static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg)
}
static void wps_er_ap_learn_m1(struct wps_er_ap *ap, struct wpabuf *m1)
{
struct wps_config cfg;
if (ap->wps) {
wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in "
"progress with this AP");
return;
}
os_memset(&cfg, 0, sizeof(cfg));
cfg.wps = ap->er->wps;
cfg.registrar = 1;
ap->wps = wps_init(&cfg);
if (ap->wps == NULL)
return;
ap->wps->ap_settings_cb = wps_er_ap_settings_cb;
ap->wps->ap_settings_cb_ctx = ap;
wps_er_ap_process(ap, m1);
}
static void wps_er_ap_learn(struct wps_er_ap *ap, const char *dev_info)
{
struct wpabuf *info;
enum http_reply_code ret;
struct wps_config cfg;
wpa_printf(MSG_DEBUG, "WPS ER: Received GetDeviceInfo response (M1) "
"from the AP");
@ -1575,25 +1627,7 @@ static void wps_er_ap_learn(struct wps_er_ap *ap, const char *dev_info)
return;
}
if (ap->wps) {
wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in "
"progress with this AP");
wpabuf_free(info);
return;
}
os_memset(&cfg, 0, sizeof(cfg));
cfg.wps = ap->er->wps;
cfg.registrar = 1;
ap->wps = wps_init(&cfg);
if (ap->wps == NULL) {
wpabuf_free(info);
return;
}
ap->wps->ap_settings_cb = wps_er_ap_settings_cb;
ap->wps->ap_settings_cb_ctx = ap;
wps_er_ap_process(ap, info);
ap->m1_handler(ap, info);
wpabuf_free(info);
}
@ -1632,27 +1666,18 @@ static void wps_er_http_get_dev_info_cb(void *ctx, struct http_client *c,
}
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
size_t pin_len)
static int wps_er_send_get_device_info(struct wps_er_ap *ap,
void (*m1_handler)(struct wps_er_ap *ap,
struct wpabuf *m1))
{
struct wps_er_ap *ap;
struct wpabuf *buf;
char *len_ptr, *body_ptr;
struct sockaddr_in dst;
char *url, *path;
if (er == NULL)
return -1;
ap = wps_er_ap_get(er, NULL, uuid);
if (ap == NULL) {
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
"request");
return -1;
}
if (ap->wps || ap->http) {
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
"with the AP - cannot start learn");
if (ap->http) {
wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
"with the AP - cannot get device info");
return -1;
}
@ -1682,6 +1707,35 @@ int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
return -1;
}
ap->m1_handler = m1_handler;
return 0;
}
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
size_t pin_len)
{
struct wps_er_ap *ap;
if (er == NULL)
return -1;
ap = wps_er_ap_get(er, NULL, uuid);
if (ap == NULL) {
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
"request");
return -1;
}
if (ap->wps) {
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
"with the AP - cannot start learn");
return -1;
}
if (wps_er_send_get_device_info(ap, wps_er_ap_learn_m1) < 0)
return -1;
/* TODO: add PIN without SetSelectedRegistrar trigger to all APs */
wps_registrar_add_pin(er->wps->registrar, uuid, pin, pin_len, 0);