Browse Source

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

Jouni Malinen 15 years ago
parent
commit
b78bc3a37e
4 changed files with 188 additions and 2 deletions
  1. 6 0
      src/common/wpa_ctrl.h
  2. 48 1
      src/wps/wps.h
  3. 57 1
      src/wps/wps_er.c
  4. 77 0
      wpa_supplicant/wps_supplicant.c

+ 6 - 0
src/common/wpa_ctrl.h

@@ -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 "

+ 48 - 1
src/wps/wps.h

@@ -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;
 };
 };
 
 
 /**
 /**

+ 57 - 1
src/wps/wps_er.c

@@ -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;
 }
 }

+ 77 - 0
wpa_supplicant/wps_supplicant.c

@@ -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;
 	}
 	}
 }
 }