@@ -66,7 +66,6 @@ static struct l_genl_family *nl80211;
static uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static struct l_queue *dpp_list;
static uint32_t mlme_watch;
-static uint32_t unicast_watch;
static uint8_t dpp_prefix[] = { 0x04, 0x09, 0x50, 0x6f, 0x9a, 0x1a, 0x01 };
@@ -552,6 +551,8 @@ static void dpp_reset(struct dpp_sm *dpp)
dpp_property_changed_notify(dpp);
+ frame_watch_group_remove(dpp->wdev_id, FRAME_GROUP_DPP);
+
dpp->interface = DPP_INTERFACE_UNBOUND;
if (station) {
@@ -3475,10 +3476,11 @@ failed:
dpp_reset(dpp);
}
-static void dpp_handle_frame(struct dpp_sm *dpp,
- const struct mmpdu_header *frame,
- const void *body, size_t body_len)
+static void dpp_handle_frame(const struct mmpdu_header *frame,
+ const void *body, size_t body_len,
+ int rssi, void *user_data)
{
+ struct dpp_sm *dpp = user_data;
const uint8_t *ptr;
/*
@@ -3638,99 +3640,6 @@ retransmit:
dpp_frame_timeout, dpp, NULL);
}
-static void dpp_unicast_notify(struct l_genl_msg *msg, void *user_data)
-{
- struct dpp_sm *dpp;
- const uint64_t *wdev_id = NULL;
- struct l_genl_attr attr;
- uint16_t type, len, frame_len;
- const void *data;
- const struct mmpdu_header *mpdu = NULL;
- const uint8_t *body;
- size_t body_len;
-
- if (l_genl_msg_get_command(msg) != NL80211_CMD_FRAME)
- return;
-
- if (!l_genl_attr_init(&attr, msg))
- return;
-
- while (l_genl_attr_next(&attr, &type, &len, &data)) {
- switch (type) {
- case NL80211_ATTR_WDEV:
- if (len != 8)
- break;
-
- wdev_id = data;
- break;
-
- case NL80211_ATTR_FRAME:
- mpdu = mpdu_validate(data, len);
- if (!mpdu) {
- l_warn("Frame didn't validate as MMPDU");
- return;
- }
-
- frame_len = len;
- break;
- }
- }
-
- if (!wdev_id) {
- l_warn("Bad wdev attribute");
- return;
- }
-
- dpp = l_queue_find(dpp_list, match_wdev, wdev_id);
- if (!dpp)
- return;
-
- if (!mpdu) {
- l_warn("Missing frame data");
- return;
- }
-
- body = mmpdu_body(mpdu);
- body_len = (const uint8_t *) mpdu + frame_len - body;
-
- if (body_len < sizeof(dpp_prefix) ||
- memcmp(body, dpp_prefix, sizeof(dpp_prefix)) != 0)
- return;
-
- dpp_handle_frame(dpp, mpdu, body, body_len);
-}
-
-static void dpp_frame_watch_cb(struct l_genl_msg *msg, void *user_data)
-{
- if (l_genl_msg_get_error(msg) < 0)
- l_error("Could not register frame watch type %04x: %i",
- L_PTR_TO_UINT(user_data), l_genl_msg_get_error(msg));
-}
-
-/*
- * Special case the frame watch which includes the presence frames since they
- * require multicast support. This is only supported by ath9k, so adding
- * general support to frame-xchg isn't desireable.
- */
-static void dpp_frame_watch(struct dpp_sm *dpp, uint16_t frame_type,
- const uint8_t *prefix, size_t prefix_len)
-{
- struct l_genl_msg *msg;
-
- msg = l_genl_msg_new_sized(NL80211_CMD_REGISTER_FRAME, 32 + prefix_len);
-
- l_genl_msg_append_attr(msg, NL80211_ATTR_WDEV, 8, &dpp->wdev_id);
- l_genl_msg_append_attr(msg, NL80211_ATTR_FRAME_TYPE, 2, &frame_type);
- l_genl_msg_append_attr(msg, NL80211_ATTR_FRAME_MATCH,
- prefix_len, prefix);
- if (dpp->mcast_support)
- l_genl_msg_append_attr(msg, NL80211_ATTR_RECEIVE_MULTICAST,
- 0, NULL);
-
- l_genl_family_send(nl80211, msg, dpp_frame_watch_cb,
- L_UINT_TO_PTR(frame_type), NULL);
-}
-
static void dpp_start_enrollee(struct dpp_sm *dpp);
static bool dpp_start_pkex_enrollee(struct dpp_sm *dpp);
@@ -3820,8 +3729,6 @@ static void dpp_create(struct netdev *netdev)
{
struct l_dbus *dbus = dbus_get_bus();
struct dpp_sm *dpp = l_new(struct dpp_sm, 1);
- uint8_t dpp_conf_response_prefix[] = { 0x04, 0x0b };
- uint8_t dpp_conf_request_prefix[] = { 0x04, 0x0a };
uint64_t wdev_id = netdev_get_wdev_id(netdev);
dpp->netdev = netdev;
@@ -3857,17 +3764,6 @@ static void dpp_create(struct netdev *netdev)
*/
dpp->refcount = 2;
- dpp_frame_watch(dpp, 0x00d0, dpp_prefix, sizeof(dpp_prefix));
-
- frame_watch_add(netdev_get_wdev_id(netdev), 0, 0x00d0,
- dpp_conf_response_prefix,
- sizeof(dpp_conf_response_prefix), false,
- dpp_handle_config_response_frame, dpp, NULL);
- frame_watch_add(netdev_get_wdev_id(netdev), 0, 0x00d0,
- dpp_conf_request_prefix,
- sizeof(dpp_conf_request_prefix), false,
- dpp_handle_config_request_frame, dpp, NULL);
-
dpp->known_network_watch = known_networks_watch_add(
dpp_known_network_watch, dpp, NULL);
@@ -4012,6 +3908,26 @@ done:
return 0;
}
+static void dpp_add_frame_watches(struct dpp_sm *dpp, bool multicast_rx)
+{
+ uint8_t dpp_conf_response_prefix[] = { 0x04, 0x0b };
+ uint8_t dpp_conf_request_prefix[] = { 0x04, 0x0a };
+
+ frame_watch_add(dpp->wdev_id, FRAME_GROUP_DPP, 0x00d0,
+ dpp_prefix, sizeof(dpp_prefix), multicast_rx,
+ dpp_handle_frame, dpp, NULL);
+
+ frame_watch_add(dpp->wdev_id, FRAME_GROUP_DPP, 0x00d0,
+ dpp_conf_response_prefix,
+ sizeof(dpp_conf_response_prefix), false,
+ dpp_handle_config_response_frame, dpp, NULL);
+
+ frame_watch_add(dpp->wdev_id, FRAME_GROUP_DPP, 0x00d0,
+ dpp_conf_request_prefix,
+ sizeof(dpp_conf_request_prefix), false,
+ dpp_handle_config_request_frame, dpp, NULL);
+}
+
static void dpp_start_enrollee(struct dpp_sm *dpp)
{
uint32_t freq = band_channel_to_freq(6, BAND_FREQ_2_4_GHZ);
@@ -4051,6 +3967,8 @@ static struct l_dbus_message *dpp_dbus_start_enrollee(struct l_dbus *dbus,
dpp->role = DPP_CAPABILITY_ENROLLEE;
dpp->interface = DPP_INTERFACE_DPP;
+ dpp_add_frame_watches(dpp, false);
+
ret = dpp_try_disconnect_station(dpp, &wait_for_disconnect);
if (ret < 0) {
dpp_reset(dpp);
@@ -4188,6 +4106,8 @@ static struct l_dbus_message *dpp_start_configurator_common(
} else
dpp->current_freq = bss->frequency;
+ dpp_add_frame_watches(dpp, responder);
+
dpp->uri = dpp_generate_uri(dpp->own_asn1, dpp->own_asn1_len, 2,
netdev_get_address(dpp->netdev),
&bss->frequency, 1, NULL, NULL);
@@ -4517,6 +4437,8 @@ static struct l_dbus_message *dpp_dbus_pkex_start_enrollee(struct l_dbus *dbus,
dpp->state = DPP_STATE_PKEX_EXCHANGE;
dpp->interface = DPP_INTERFACE_PKEX;
+ dpp_add_frame_watches(dpp, false);
+
ret = dpp_try_disconnect_station(dpp, &wait_for_disconnect);
if (ret < 0) {
dpp_reset(dpp);
@@ -4613,6 +4535,7 @@ static struct l_dbus_message *dpp_start_pkex_configurator(struct dpp_sm *dpp,
dpp->config = dpp_configuration_new(network_get_settings(network),
network_get_ssid(network),
hs->akm_suite);
+ dpp_add_frame_watches(dpp, true);
dpp_reset_protocol_timer(dpp, DPP_PKEX_PROTO_TIMEOUT);
dpp_property_changed_notify(dpp);
@@ -4741,11 +4664,6 @@ static int dpp_init(void)
mlme_watch = l_genl_family_register(nl80211, "mlme", dpp_mlme_notify,
NULL, NULL);
- unicast_watch = l_genl_add_unicast_watch(iwd_get_genl(),
- NL80211_GENL_NAME,
- dpp_unicast_notify,
- NULL, NULL);
-
dpp_list = l_queue_new();
return 0;
@@ -4760,8 +4678,6 @@ static void dpp_exit(void)
netdev_watch_remove(netdev_watch);
- l_genl_remove_unicast_watch(iwd_get_genl(), unicast_watch);
-
l_genl_family_unregister(nl80211, mlme_watch);
mlme_watch = 0;