aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2011-12-22 20:47:41 (GMT)
committerJouni Malinen <j@w1.fi>2011-12-22 20:47:41 (GMT)
commitfbdcfd577a3f6245c9c34e09842e766777a84ea7 (patch)
tree8a3728f8b1a499a600981142ed4b3232d1c83778
parent87f841a1407dc8f988d6c43a9c4307e34e86986f (diff)
downloadhostap-fbdcfd577a3f6245c9c34e09842e766777a84ea7.zip
hostap-fbdcfd577a3f6245c9c34e09842e766777a84ea7.tar.gz
hostap-fbdcfd577a3f6245c9c34e09842e766777a84ea7.tar.bz2
P2P: Maintain a list of P2P Clients for persistent group on GO
Add a new persistent group network block field, p2p_client_list, to maintain a list of P2P Clients that have connected to a persistent group. This allows GO of a persistent group to figure out more easily whether re-invocation of a persistent group can be used with a specific peer device. Signed-hostap: Jouni Malinen <j@w1.fi>
-rw-r--r--src/ap/hostapd.h2
-rw-r--r--src/ap/sta_info.c2
-rw-r--r--wpa_supplicant/ap.c4
-rw-r--r--wpa_supplicant/config.c88
-rw-r--r--wpa_supplicant/config_file.c15
-rw-r--r--wpa_supplicant/config_ssid.h14
-rw-r--r--wpa_supplicant/notify.c10
-rw-r--r--wpa_supplicant/notify.h3
-rw-r--r--wpa_supplicant/p2p_supplicant.c71
-rw-r--r--wpa_supplicant/p2p_supplicant.h2
10 files changed, 200 insertions, 11 deletions
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 5b72768..c6f6205 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -149,7 +149,7 @@ struct hostapd_data {
void *wps_event_cb_ctx;
void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr,
- int authorized);
+ int authorized, const u8 *p2p_dev_addr);
void *sta_authorized_cb_ctx;
void (*setup_complete_cb)(void *ctx);
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index d9c348e..27ab258 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -824,7 +824,7 @@ void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
if (hapd->sta_authorized_cb)
hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx,
- sta->addr, authorized);
+ sta->addr, authorized, dev_addr);
}
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 2d147d1..1386d0c 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -328,9 +328,9 @@ static void ap_wps_event_cb(void *ctx, enum wps_event event,
static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
- int authorized)
+ int authorized, const u8 *p2p_dev_addr)
{
- wpas_notify_sta_authorized(ctx, mac_addr, authorized);
+ wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
}
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index b446a3f..0fd1f3e 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1351,6 +1351,90 @@ static char * wpa_config_write_wep_key3(const struct parse_data *data,
#endif /* NO_CONFIG_WRITE */
+#ifdef CONFIG_P2P
+
+static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ const char *pos;
+ u8 *buf, *n, addr[ETH_ALEN];
+ size_t count;
+
+ buf = NULL;
+ count = 0;
+
+ pos = value;
+ while (pos && *pos) {
+ while (*pos == ' ')
+ pos++;
+
+ if (hwaddr_aton(pos, addr)) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid "
+ "p2p_client_list address '%s'.",
+ line, value);
+ /* continue anyway */
+ } else {
+ n = os_realloc(buf, (count + 1) * ETH_ALEN);
+ if (n == NULL) {
+ os_free(buf);
+ return -1;
+ }
+ buf = n;
+ os_memcpy(buf + count * ETH_ALEN, addr, ETH_ALEN);
+ count++;
+ wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
+ addr, ETH_ALEN);
+ }
+
+ pos = os_strchr(pos, ' ');
+ }
+
+ os_free(ssid->p2p_client_list);
+ ssid->p2p_client_list = buf;
+ ssid->num_p2p_clients = count;
+
+ return 0;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ char *value, *end, *pos;
+ int res;
+ size_t i;
+
+ if (ssid->p2p_client_list == NULL || ssid->num_p2p_clients == 0)
+ return NULL;
+
+ value = os_malloc(20 * ssid->num_p2p_clients);
+ if (value == NULL)
+ return NULL;
+ pos = value;
+ end = value + 20 * ssid->num_p2p_clients;
+
+ for (i = 0; i < ssid->num_p2p_clients; i++) {
+ res = os_snprintf(pos, end - pos, MACSTR " ",
+ MAC2STR(ssid->p2p_client_list +
+ i * ETH_ALEN));
+ if (res < 0 || res >= end - pos) {
+ os_free(value);
+ return NULL;
+ }
+ pos += res;
+ }
+
+ if (pos > value)
+ pos[-1] = '\0';
+
+ return value;
+}
+#endif /* NO_CONFIG_WRITE */
+
+#endif /* CONFIG_P2P */
+
/* Helper macros for network block parser */
#ifdef OFFSET
@@ -1511,6 +1595,9 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(frequency, 0, 10000) },
{ INT(wpa_ptk_rekey) },
{ STR(bgscan) },
+#ifdef CONFIG_P2P
+ { FUNC(p2p_client_list) },
+#endif /* CONFIG_P2P */
};
#undef OFFSET
@@ -1677,6 +1764,7 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
os_free(ssid->scan_freq);
os_free(ssid->freq_list);
os_free(ssid->bgscan);
+ os_free(ssid->p2p_client_list);
os_free(ssid);
}
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 8ea03ab..f3a7291 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -493,6 +493,18 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid)
}
+#ifdef CONFIG_P2P
+static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid)
+{
+ char *value = wpa_config_get(ssid, "p2p_client_list");
+ if (value == NULL)
+ return;
+ fprintf(f, "\tp2p_client_list=%s\n", value);
+ os_free(value);
+}
+#endif /* CONFIG_P2P */
+
+
static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
{
int i;
@@ -567,6 +579,9 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
INT(ieee80211w);
#endif /* CONFIG_IEEE80211W */
STR(id_str);
+#ifdef CONFIG_P2P
+ write_p2p_client_list(f, ssid);
+#endif /* CONFIG_P2P */
#undef STR
#undef INT
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 8419f43..8a47c0b 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -387,6 +387,20 @@ struct wpa_ssid {
int *freq_list;
/**
+ * p2p_client_list - List of P2P Clients in a persistent group (GO)
+ *
+ * This is a list of P2P Clients (P2P Device Address) that have joined
+ * the persistent group. This is maintained on the GO for persistent
+ * group entries (disabled == 2).
+ */
+ u8 *p2p_client_list;
+
+ /**
+ * num_p2p_clients - Number of entries in p2p_client_list
+ */
+ size_t num_p2p_clients;
+
+ /**
* p2p_group - Network generated as a P2P group (used internally)
*/
int p2p_group;
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 71778ae..6e9b5a9 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -525,9 +525,12 @@ void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *sta)
+ const u8 *sta,
+ const u8 *p2p_dev_addr)
{
#ifdef CONFIG_P2P
+ wpas_p2p_notify_ap_sta_authorized(wpa_s, p2p_dev_addr);
+
/*
* Register a group member object corresponding to this peer and
* emit a PeerJoined signal. This will check if it really is a
@@ -564,10 +567,11 @@ static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s,
void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *mac_addr, int authorized)
+ const u8 *mac_addr, int authorized,
+ const u8 *p2p_dev_addr)
{
if (authorized)
- wpas_notify_ap_sta_authorized(wpa_s, mac_addr);
+ wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr);
else
wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr);
}
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 7d4a11e..236a31e 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -86,7 +86,8 @@ void wpas_notify_suspend(struct wpa_global *global);
void wpas_notify_resume(struct wpa_global *global);
void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *mac_addr, int authorized);
+ const u8 *mac_addr, int authorized,
+ const u8 *p2p_dev_addr);
void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
const u8 *dev_addr, int new_device);
void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 367fce1..5cb9db6 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -465,6 +465,52 @@ static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
}
+static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
+ const u8 *addr)
+{
+ struct wpa_ssid *ssid, *s;
+ u8 *n;
+ size_t i;
+
+ ssid = wpa_s->current_ssid;
+ if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
+ !ssid->p2p_persistent_group)
+ return;
+
+ for (s = wpa_s->parent->conf->ssid; s; s = s->next) {
+ if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
+ continue;
+
+ if (s->ssid_len == ssid->ssid_len &&
+ os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
+ break;
+ }
+
+ if (s == NULL)
+ return;
+
+ for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
+ if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr,
+ ETH_ALEN) == 0)
+ return; /* already in list */
+ }
+
+ n = os_realloc(s->p2p_client_list,
+ (s->num_p2p_clients + 1) * ETH_ALEN);
+ if (n == NULL)
+ return;
+ os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN);
+ s->p2p_client_list = n;
+ s->num_p2p_clients++;
+
+#ifndef CONFIG_NO_CONFIG_WRITE
+ if (wpa_s->parent->conf->update_config &&
+ wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
+ wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
+#endif /* CONFIG_NO_CONFIG_WRITE */
+}
+
+
static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
int success)
{
@@ -4266,12 +4312,31 @@ struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
const u8 *addr)
{
struct wpa_ssid *s;
+ size_t i;
for (s = wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled == 2 &&
- os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
- return s;
+ if (s->disabled != 2)
+ continue;
+ if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
+ return s; /* peer is GO in the persistent group */
+ if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
+ continue;
+ for (i = 0; i < s->num_p2p_clients; i++) {
+ if (os_memcmp(s->p2p_client_list + i * ETH_ALEN,
+ addr, ETH_ALEN) == 0)
+ return s; /* peer is P2P client in persistent
+ * group */
+ }
}
return NULL;
}
+
+
+void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
+ const u8 *addr)
+{
+ if (addr == NULL)
+ return;
+ wpas_p2p_add_persistent_group_client(wpa_s, addr);
+}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 0a450b6..3150f04 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -133,5 +133,7 @@ void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
const u8 *addr);
+void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
+ const u8 *addr);
#endif /* P2P_SUPPLICANT_H */