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>
This commit is contained in:
parent
87f841a140
commit
fbdcfd577a
10 changed files with 200 additions and 11 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -386,6 +386,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)
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue