diff --git a/src/netdev.c b/src/netdev.c index d80ce10f..09fac959 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -2559,6 +2559,10 @@ static bool netdev_retry_owe(struct netdev *netdev) if (!owe_next_group(netdev->owe_sm)) return false; + if (netdev->event_filter) + netdev->event_filter(netdev, NETDEV_EVENT_ECC_GROUP_RETRY, + NULL, netdev->user_data); + connect_cmd = netdev_build_cmd_connect(netdev, netdev->handshake, NULL); netdev->connect_cmd_id = l_genl_family_send(nl80211, connect_cmd, @@ -2966,6 +2970,17 @@ static void netdev_authenticate_event(struct l_genl_msg *msg, ret = auth_proto_rx_authenticate(netdev->ap, frame, frame_len); + /* + * Allows station to persist settings so it does not retry + * the higher order ECC group again + */ + if (status_code == + MMPDU_STATUS_CODE_UNSUPP_FINITE_CYCLIC_GROUP && + netdev->event_filter) + netdev->event_filter(netdev, + NETDEV_EVENT_ECC_GROUP_RETRY, + NULL, netdev->user_data); + /* We have sent another CMD_AUTHENTICATE / CMD_ASSOCIATE */ if (ret == 0 || ret == -EAGAIN) return; diff --git a/src/netdev.h b/src/netdev.h index d87f09f4..671d0d40 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -51,6 +51,7 @@ enum netdev_event { NETDEV_EVENT_RSSI_LEVEL_NOTIFY, NETDEV_EVENT_PACKET_LOSS_NOTIFY, NETDEV_EVENT_BEACON_LOSS_NOTIFY, + NETDEV_EVENT_ECC_GROUP_RETRY, }; enum netdev_watch_event { diff --git a/src/station.c b/src/station.c index b564f4aa..477f444a 100644 --- a/src/station.c +++ b/src/station.c @@ -3456,6 +3456,18 @@ static void station_event_roaming(struct station *station) station_enter_state(station, STATION_STATE_FW_ROAMING); } +static void station_ecc_group_retry(struct station *station) +{ + struct network *network = station_get_connected_network(station); + + if (L_WARN_ON(!network)) + return; + + station_debug_event(station, "ecc-group-rejected"); + + network_set_force_default_ecc_group(network); +} + static void station_netdev_event(struct netdev *netdev, enum netdev_event event, void *event_data, void *user_data) { @@ -3497,6 +3509,9 @@ static void station_netdev_event(struct netdev *netdev, enum netdev_event event, case NETDEV_EVENT_BEACON_LOSS_NOTIFY: station_beacon_lost(station); break; + case NETDEV_EVENT_ECC_GROUP_RETRY: + station_ecc_group_retry(station); + break; } }