WPS: Add Enrollee-seen event message and wpa_gui-qt4 Peers entry
This can be used to show active Enrollees in AP mode to make it easier to provision a new device.
This commit is contained in:
parent
f7e5436502
commit
c2f5126941
5 changed files with 144 additions and 5 deletions
|
@ -154,6 +154,29 @@ static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_wps_enrollee_seen_cb(void *ctx, const u8 *addr,
|
||||||
|
const u8 *uuid_e,
|
||||||
|
const u8 *pri_dev_type,
|
||||||
|
u16 config_methods,
|
||||||
|
u16 dev_password_id, u8 request_type,
|
||||||
|
const char *dev_name)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd = ctx;
|
||||||
|
char uuid[40];
|
||||||
|
char devtype[WPS_DEV_TYPE_BUFSIZE];
|
||||||
|
if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
|
||||||
|
return;
|
||||||
|
if (dev_name == NULL)
|
||||||
|
dev_name = "";
|
||||||
|
wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ENROLLEE_SEEN MACSTR
|
||||||
|
" %s %s 0x%x %u %u [%s]",
|
||||||
|
MAC2STR(addr), uuid,
|
||||||
|
wps_dev_type_bin2str(pri_dev_type, devtype,
|
||||||
|
sizeof(devtype)),
|
||||||
|
config_methods, dev_password_id, request_type, dev_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int str_starts(const char *str, const char *start)
|
static int str_starts(const char *str, const char *start)
|
||||||
{
|
{
|
||||||
return os_strncmp(str, start, os_strlen(start)) == 0;
|
return os_strncmp(str, start, os_strlen(start)) == 0;
|
||||||
|
@ -596,6 +619,7 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
||||||
cfg.set_ie_cb = hostapd_wps_set_ie_cb;
|
cfg.set_ie_cb = hostapd_wps_set_ie_cb;
|
||||||
cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
|
cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
|
||||||
cfg.reg_success_cb = hostapd_wps_reg_success_cb;
|
cfg.reg_success_cb = hostapd_wps_reg_success_cb;
|
||||||
|
cfg.enrollee_seen_cb = hostapd_wps_enrollee_seen_cb;
|
||||||
cfg.cb_ctx = hapd;
|
cfg.cb_ctx = hapd;
|
||||||
cfg.skip_cred_build = conf->skip_cred_build;
|
cfg.skip_cred_build = conf->skip_cred_build;
|
||||||
cfg.extra_cred = conf->extra_cred;
|
cfg.extra_cred = conf->extra_cred;
|
||||||
|
|
|
@ -73,6 +73,8 @@ 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 "
|
||||||
|
|
||||||
|
#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
|
||||||
|
|
||||||
/* WPS ER events */
|
/* WPS ER events */
|
||||||
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
|
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
|
||||||
#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
|
#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
|
||||||
|
|
|
@ -277,6 +277,22 @@ struct wps_registrar_config {
|
||||||
void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
|
void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
|
||||||
u16 sel_reg_config_methods);
|
u16 sel_reg_config_methods);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enrollee_seen_cb - Callback for reporting Enrollee based on ProbeReq
|
||||||
|
* @ctx: Higher layer context data (cb_ctx)
|
||||||
|
* @addr: MAC address of the Enrollee
|
||||||
|
* @uuid_e: UUID of the Enrollee
|
||||||
|
* @pri_dev_type: Primary device type
|
||||||
|
* @config_methods: Config Methods
|
||||||
|
* @dev_password_id: Device Password ID
|
||||||
|
* @request_type: Request Type
|
||||||
|
* @dev_name: Device Name (if available)
|
||||||
|
*/
|
||||||
|
void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
|
||||||
|
const u8 *pri_dev_type, u16 config_methods,
|
||||||
|
u16 dev_password_id, u8 request_type,
|
||||||
|
const char *dev_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cb_ctx: Higher layer context data for Registrar callbacks
|
* cb_ctx: Higher layer context data for Registrar callbacks
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -107,6 +107,10 @@ struct wps_registrar {
|
||||||
const u8 *uuid_e);
|
const u8 *uuid_e);
|
||||||
void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
|
void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
|
||||||
u16 sel_reg_config_methods);
|
u16 sel_reg_config_methods);
|
||||||
|
void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
|
||||||
|
const u8 *pri_dev_type, u16 config_methods,
|
||||||
|
u16 dev_password_id, u8 request_type,
|
||||||
|
const char *dev_name);
|
||||||
void *cb_ctx;
|
void *cb_ctx;
|
||||||
|
|
||||||
struct dl_list pins;
|
struct dl_list pins;
|
||||||
|
@ -456,6 +460,7 @@ wps_registrar_init(struct wps_context *wps,
|
||||||
reg->pin_needed_cb = cfg->pin_needed_cb;
|
reg->pin_needed_cb = cfg->pin_needed_cb;
|
||||||
reg->reg_success_cb = cfg->reg_success_cb;
|
reg->reg_success_cb = cfg->reg_success_cb;
|
||||||
reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
|
reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
|
||||||
|
reg->enrollee_seen_cb = cfg->enrollee_seen_cb;
|
||||||
reg->cb_ctx = cfg->cb_ctx;
|
reg->cb_ctx = cfg->cb_ctx;
|
||||||
reg->skip_cred_build = cfg->skip_cred_build;
|
reg->skip_cred_build = cfg->skip_cred_build;
|
||||||
if (cfg->extra_cred) {
|
if (cfg->extra_cred) {
|
||||||
|
@ -770,6 +775,24 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reg->enrollee_seen_cb && attr.dev_password_id && attr.uuid_e &&
|
||||||
|
attr.primary_dev_type && attr.request_type) {
|
||||||
|
char *dev_name = NULL;
|
||||||
|
if (attr.dev_name) {
|
||||||
|
dev_name = os_zalloc(attr.dev_name_len + 1);
|
||||||
|
if (dev_name) {
|
||||||
|
os_memcpy(dev_name, attr.dev_name,
|
||||||
|
attr.dev_name_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e,
|
||||||
|
attr.primary_dev_type,
|
||||||
|
WPA_GET_BE16(attr.config_methods),
|
||||||
|
WPA_GET_BE16(attr.dev_password_id),
|
||||||
|
*attr.request_type, dev_name);
|
||||||
|
os_free(dev_name);
|
||||||
|
}
|
||||||
|
|
||||||
methods = WPA_GET_BE16(attr.config_methods);
|
methods = WPA_GET_BE16(attr.config_methods);
|
||||||
if (!(methods & WPS_CONFIG_PUSHBUTTON))
|
if (!(methods & WPS_CONFIG_PUSHBUTTON))
|
||||||
return; /* Not PBC */
|
return; /* Not PBC */
|
||||||
|
|
|
@ -45,7 +45,8 @@ enum peer_type {
|
||||||
PEER_TYPE_WPS_PIN_NEEDED,
|
PEER_TYPE_WPS_PIN_NEEDED,
|
||||||
PEER_TYPE_WPS_ER_AP,
|
PEER_TYPE_WPS_ER_AP,
|
||||||
PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
|
PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
|
||||||
PEER_TYPE_WPS_ER_ENROLLEE
|
PEER_TYPE_WPS_ER_ENROLLEE,
|
||||||
|
PEER_TYPE_WPS_ENROLLEE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,6 +123,9 @@ QString Peers::ItemType(int type)
|
||||||
case PEER_TYPE_WPS_ER_ENROLLEE:
|
case PEER_TYPE_WPS_ER_ENROLLEE:
|
||||||
title = tr("ER: WPS Enrollee");
|
title = tr("ER: WPS Enrollee");
|
||||||
break;
|
break;
|
||||||
|
case PEER_TYPE_WPS_ENROLLEE:
|
||||||
|
title = tr("WPS Enrollee");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +152,8 @@ void Peers::context_menu(const QPoint &pos)
|
||||||
if ((type == PEER_TYPE_ASSOCIATED_STATION ||
|
if ((type == PEER_TYPE_ASSOCIATED_STATION ||
|
||||||
type == PEER_TYPE_AP_WPS ||
|
type == PEER_TYPE_AP_WPS ||
|
||||||
type == PEER_TYPE_WPS_PIN_NEEDED ||
|
type == PEER_TYPE_WPS_PIN_NEEDED ||
|
||||||
type == PEER_TYPE_WPS_ER_ENROLLEE) &&
|
type == PEER_TYPE_WPS_ER_ENROLLEE ||
|
||||||
|
type == PEER_TYPE_WPS_ENROLLEE) &&
|
||||||
(config_methods == -1 || (config_methods & 0x010c))) {
|
(config_methods == -1 || (config_methods & 0x010c))) {
|
||||||
menu->addAction(tr("Enter WPS PIN"), this,
|
menu->addAction(tr("Enter WPS PIN"), this,
|
||||||
SLOT(enter_pin()));
|
SLOT(enter_pin()));
|
||||||
|
@ -160,7 +165,8 @@ void Peers::context_menu(const QPoint &pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type == PEER_TYPE_ASSOCIATED_STATION ||
|
if ((type == PEER_TYPE_ASSOCIATED_STATION ||
|
||||||
type == PEER_TYPE_WPS_ER_ENROLLEE) &&
|
type == PEER_TYPE_WPS_ER_ENROLLEE ||
|
||||||
|
type == PEER_TYPE_WPS_ENROLLEE) &&
|
||||||
config_methods >= 0 && (config_methods & 0x0080)) {
|
config_methods >= 0 && (config_methods & 0x0080)) {
|
||||||
menu->addAction(tr("Enroll (PBC)"), this,
|
menu->addAction(tr("Enroll (PBC)"), this,
|
||||||
SLOT(connect_pbc()));
|
SLOT(connect_pbc()));
|
||||||
|
@ -644,6 +650,71 @@ void Peers::event_notify(WpaMsg msg)
|
||||||
remove_enrollee_uuid(items[1]);
|
remove_enrollee_uuid(items[1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (text.startsWith(WPS_EVENT_ENROLLEE_SEEN)) {
|
||||||
|
/* TODO: need to time out this somehow or remove on successful
|
||||||
|
* WPS run, etc. */
|
||||||
|
/*
|
||||||
|
* WPS-ENROLLEE-SEEN 02:00:00:00:01:00
|
||||||
|
* 572cf82f-c957-5653-9b16-b5cfb298abf1 1-0050F204-1 0x80 4 1
|
||||||
|
* [Wireless Client]
|
||||||
|
* (MAC addr, UUID-E, pri dev type, config methods,
|
||||||
|
* dev passwd id, request type, [dev name])
|
||||||
|
*/
|
||||||
|
QStringList items = text.split(' ');
|
||||||
|
if (items.size() < 7)
|
||||||
|
return;
|
||||||
|
QString addr = items[1];
|
||||||
|
QString uuid = items[2];
|
||||||
|
QString pri_dev_type = items[3];
|
||||||
|
int config_methods = items[4].toInt(0, 0);
|
||||||
|
int dev_passwd_id = items[5].toInt();
|
||||||
|
QString name;
|
||||||
|
|
||||||
|
int pos = text.indexOf('[');
|
||||||
|
if (pos >= 0) {
|
||||||
|
int pos2 = text.lastIndexOf(']');
|
||||||
|
if (pos2 >= pos) {
|
||||||
|
QStringList items2 =
|
||||||
|
text.mid(pos + 1, pos2 - pos - 1).
|
||||||
|
split('|');
|
||||||
|
name = items2[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.isEmpty())
|
||||||
|
name = addr;
|
||||||
|
|
||||||
|
QStandardItem *item;
|
||||||
|
|
||||||
|
item = find_uuid(uuid);
|
||||||
|
if (item) {
|
||||||
|
QVariant var = item->data(peer_role_config_methods);
|
||||||
|
QVariant var2 = item->data(peer_role_dev_passwd_id);
|
||||||
|
if ((var.isValid() && config_methods != var.toInt()) ||
|
||||||
|
(var2.isValid() && dev_passwd_id != var2.toInt()))
|
||||||
|
remove_enrollee_uuid(uuid);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = new QStandardItem(*laptop_icon, name);
|
||||||
|
if (item) {
|
||||||
|
item->setData(uuid, peer_role_uuid);
|
||||||
|
item->setData(addr, peer_role_address);
|
||||||
|
item->setData(PEER_TYPE_WPS_ENROLLEE,
|
||||||
|
peer_role_type);
|
||||||
|
item->setToolTip(ItemType(PEER_TYPE_WPS_ENROLLEE));
|
||||||
|
item->setData(items.join(QString("\n")),
|
||||||
|
peer_role_details);
|
||||||
|
item->setData(pri_dev_type, peer_role_pri_dev_type);
|
||||||
|
item->setData(config_methods,
|
||||||
|
peer_role_config_methods);
|
||||||
|
item->setData(dev_passwd_id, peer_role_dev_passwd_id);
|
||||||
|
model.appendRow(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -673,8 +744,11 @@ void Peers::remove_enrollee_uuid(QString uuid)
|
||||||
peer_role_uuid, uuid);
|
peer_role_uuid, uuid);
|
||||||
for (int i = 0; i < lst.size(); i++) {
|
for (int i = 0; i < lst.size(); i++) {
|
||||||
QStandardItem *item = model.itemFromIndex(lst[i]);
|
QStandardItem *item = model.itemFromIndex(lst[i]);
|
||||||
if (item && item->data(peer_role_type).toInt() ==
|
if (item == NULL)
|
||||||
PEER_TYPE_WPS_ER_ENROLLEE)
|
continue;
|
||||||
|
int type = item->data(peer_role_type).toInt();
|
||||||
|
if (type == PEER_TYPE_WPS_ER_ENROLLEE ||
|
||||||
|
type == PEER_TYPE_WPS_ENROLLEE)
|
||||||
model.removeRow(lst[i].row());
|
model.removeRow(lst[i].row());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue