WPS ER: Add ctrl_iface notifications for AP/Enrollee add/remove

This commit is contained in:
Jouni Malinen 2009-11-15 12:07:27 +02:00
parent 462adee5fe
commit b78bc3a37e
4 changed files with 188 additions and 2 deletions

View file

@ -69,6 +69,12 @@ extern "C" {
/** WPS enrollment attempt timed out and was terminated */ /** WPS enrollment attempt timed out and was terminated */
#define WPS_EVENT_TIMEOUT "WPS-TIMEOUT " #define WPS_EVENT_TIMEOUT "WPS-TIMEOUT "
/* WPS ER events */
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
#define WPS_EVENT_ER_ENROLLEE_ADD "WPS-ER-ENROLLEE-ADD "
#define WPS_EVENT_ER_ENROLLEE_REMOVE "WPS-ER-ENROLLEE-REMOVE "
/* hostapd control interface - fixed message prefixes */ /* hostapd control interface - fixed message prefixes */
#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED " #define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS " #define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "

View file

@ -351,7 +351,27 @@ enum wps_event {
/** /**
* WPS_EV_PBC_TIMEOUT - PBC walktime expired before protocol run start * WPS_EV_PBC_TIMEOUT - PBC walktime expired before protocol run start
*/ */
WPS_EV_PBC_TIMEOUT WPS_EV_PBC_TIMEOUT,
/**
* WPS_EV_ER_AP_ADD - ER: AP added
*/
WPS_EV_ER_AP_ADD,
/**
* WPS_EV_ER_AP_REMOVE - ER: AP removed
*/
WPS_EV_ER_AP_REMOVE,
/**
* WPS_EV_ER_ENROLLEE_ADD - ER: Enrollee added
*/
WPS_EV_ER_ENROLLEE_ADD,
/**
* WPS_EV_ER_ENROLLEE_REMOVE - ER: Enrollee removed
*/
WPS_EV_ER_ENROLLEE_REMOVE
}; };
/** /**
@ -390,6 +410,33 @@ union wps_event_data {
int enrollee; int enrollee;
int part; int part;
} pwd_auth_fail; } pwd_auth_fail;
struct wps_event_er_ap {
const u8 *uuid;
const char *friendly_name;
const char *manufacturer;
const char *manufacturer_url;
const char *model_description;
const char *model_name;
const char *model_number;
const char *model_url;
const char *serial_number;
const char *upc;
} ap;
struct wps_event_er_enrollee {
const u8 *uuid;
const u8 *mac_addr;
int m1_received;
u16 config_methods;
u16 dev_passwd_id;
const u8 *pri_dev_type;
const char *dev_name;
const char *manufacturer;
const char *model_name;
const char *model_number;
const char *serial_number;
} enrollee;
}; };
/** /**

View file

@ -100,6 +100,31 @@ struct wps_er {
}; };
static void wps_er_sta_event(struct wps_context *wps, struct wps_er_sta *sta,
enum wps_event event)
{
union wps_event_data data;
struct wps_event_er_enrollee *ev = &data.enrollee;
if (wps->event_cb == NULL)
return;
os_memset(&data, 0, sizeof(data));
ev->uuid = sta->uuid;
ev->mac_addr = sta->addr;
ev->m1_received = sta->m1_received;
ev->config_methods = sta->config_methods;
ev->dev_passwd_id = sta->dev_passwd_id;
ev->pri_dev_type = sta->pri_dev_type;
ev->dev_name = sta->dev_name;
ev->manufacturer = sta->manufacturer;
ev->model_name = sta->model_name;
ev->model_number = sta->model_number;
ev->serial_number = sta->serial_number;
wps->event_cb(wps->cb_ctx, event, &data);
}
static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr) static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr)
{ {
struct wps_er_sta *sta = ap->sta; struct wps_er_sta *sta = ap->sta;
@ -114,6 +139,7 @@ static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr)
static void wps_er_sta_free(struct wps_er_sta *sta) static void wps_er_sta_free(struct wps_er_sta *sta)
{ {
wps_er_sta_event(sta->ap->er->wps, sta, WPS_EV_ER_ENROLLEE_REMOVE);
if (sta->wps) if (sta->wps)
wps_deinit(sta->wps); wps_deinit(sta->wps);
os_free(sta->manufacturer); os_free(sta->manufacturer);
@ -165,6 +191,30 @@ static struct wps_er_ap * wps_er_ap_get_id(struct wps_er *er, unsigned int id)
} }
static void wps_er_ap_event(struct wps_context *wps, struct wps_er_ap *ap,
enum wps_event event)
{
union wps_event_data data;
struct wps_event_er_ap *evap = &data.ap;
if (wps->event_cb == NULL)
return;
os_memset(&data, 0, sizeof(data));
evap->uuid = ap->uuid;
evap->friendly_name = ap->friendly_name;
evap->manufacturer = ap->manufacturer;
evap->manufacturer_url = ap->manufacturer_url;
evap->model_description = ap->model_description;
evap->model_name = ap->model_name;
evap->model_number = ap->model_number;
evap->model_url = ap->model_url;
evap->serial_number = ap->serial_number;
evap->upc = ap->upc;
wps->event_cb(wps->cb_ctx, event, &data);
}
static void wps_er_ap_free(struct wps_er *er, struct wps_er_ap *ap) static void wps_er_ap_free(struct wps_er *er, struct wps_er_ap *ap)
{ {
/* TODO: if ap->subscribed, unsubscribe from events if the AP is still /* TODO: if ap->subscribed, unsubscribe from events if the AP is still
@ -172,6 +222,7 @@ static void wps_er_ap_free(struct wps_er *er, struct wps_er_ap *ap)
wpa_printf(MSG_DEBUG, "WPS ER: Removing AP entry for %s (%s)", wpa_printf(MSG_DEBUG, "WPS ER: Removing AP entry for %s (%s)",
inet_ntoa(ap->addr), ap->location); inet_ntoa(ap->addr), ap->location);
eloop_cancel_timeout(wps_er_ap_timeout, er, ap); eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_REMOVE);
os_free(ap->location); os_free(ap->location);
http_client_free(ap->http); http_client_free(ap->http);
@ -213,6 +264,7 @@ static void wps_er_http_subscribe_cb(void *ctx, struct http_client *c,
switch (event) { switch (event) {
case HTTP_CLIENT_OK: case HTTP_CLIENT_OK:
wpa_printf(MSG_DEBUG, "WPS ER: Subscribed to events"); wpa_printf(MSG_DEBUG, "WPS ER: Subscribed to events");
wps_er_ap_event(ap->er->wps, ap, WPS_EV_ER_AP_ADD);
break; break;
case HTTP_CLIENT_FAILED: case HTTP_CLIENT_FAILED:
case HTTP_CLIENT_INVALID_REPLY: case HTTP_CLIENT_INVALID_REPLY:
@ -615,6 +667,7 @@ static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
int probe_req) int probe_req)
{ {
struct wps_er_sta *sta = wps_er_sta_get(ap, addr); struct wps_er_sta *sta = wps_er_sta_get(ap, addr);
int new_sta = 0;
if (sta == NULL) { if (sta == NULL) {
sta = os_zalloc(sizeof(*sta)); sta = os_zalloc(sizeof(*sta));
@ -624,6 +677,7 @@ static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
sta->ap = ap; sta->ap = ap;
sta->next = ap->sta; sta->next = ap->sta;
ap->sta = sta; ap->sta = sta;
new_sta = 1;
} }
if (!probe_req) if (!probe_req)
@ -691,7 +745,9 @@ static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL); eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL); eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL);
/* TODO: wpa_msg indication if new STA */ if (!probe_req || new_sta)
wps_er_sta_event(ap->er->wps, sta,
WPS_EV_ER_ENROLLEE_ADD);
return sta; return sta;
} }

View file

@ -410,6 +410,69 @@ static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
} }
static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s,
struct wps_event_er_ap *ap)
{
char uuid_str[100];
uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s|%s|%s|%s|%s|%s|%s",
uuid_str,
ap->friendly_name ? ap->friendly_name : "",
ap->manufacturer ? ap->manufacturer : "",
ap->model_description ? ap->model_description : "",
ap->model_name ? ap->model_name : "",
ap->manufacturer_url ? ap->manufacturer_url : "",
ap->model_url ? ap->model_url : "");
}
static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s,
struct wps_event_er_ap *ap)
{
char uuid_str[100];
uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str);
}
static void wpa_supplicant_wps_event_er_enrollee_add(
struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
{
char uuid_str[100];
char dev_type[20];
uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
if (enrollee->pri_dev_type)
os_snprintf(dev_type, sizeof(dev_type), "%u-%08X-%u",
WPA_GET_BE16(enrollee->pri_dev_type),
WPA_GET_BE32(enrollee->pri_dev_type + 2),
WPA_GET_BE16(enrollee->pri_dev_type + 6));
else
dev_type[0] = '\0';
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR
" M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s "
"|%s|%s|%s|%s|%s|",
uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received,
enrollee->config_methods, enrollee->dev_passwd_id, dev_type,
enrollee->dev_name ? enrollee->dev_name : "",
enrollee->manufacturer ? enrollee->manufacturer : "",
enrollee->model_name ? enrollee->model_name : "",
enrollee->model_number ? enrollee->model_number : "",
enrollee->serial_number ? enrollee->serial_number : "");
}
static void wpa_supplicant_wps_event_er_enrollee_remove(
struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
{
char uuid_str[100];
uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR,
uuid_str, MAC2STR(enrollee->mac_addr));
}
static void wpa_supplicant_wps_event(void *ctx, enum wps_event event, static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
union wps_event_data *data) union wps_event_data *data)
{ {
@ -430,6 +493,20 @@ static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
break; break;
case WPS_EV_PBC_TIMEOUT: case WPS_EV_PBC_TIMEOUT:
break; break;
case WPS_EV_ER_AP_ADD:
wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap);
break;
case WPS_EV_ER_AP_REMOVE:
wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap);
break;
case WPS_EV_ER_ENROLLEE_ADD:
wpa_supplicant_wps_event_er_enrollee_add(wpa_s,
&data->enrollee);
break;
case WPS_EV_ER_ENROLLEE_REMOVE:
wpa_supplicant_wps_event_er_enrollee_remove(wpa_s,
&data->enrollee);
break;
} }
} }