diff --git a/src/netdev.c b/src/netdev.c index f098dabd..b6ce57f0 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -104,7 +104,7 @@ struct netdev { uint32_t set_interface_cmd_id; uint32_t rekey_offload_cmd_id; enum netdev_result result; - uint16_t last_status_code; + uint16_t last_code; /* reason or status, depending on result */ struct l_timeout *neighbor_report_timeout; struct l_timeout *sa_query_timeout; struct l_timeout *group_handshake_timeout; @@ -339,11 +339,6 @@ const char *netdev_get_path(struct netdev *netdev) return path; } -uint16_t netdev_get_last_status_code(struct netdev *netdev) -{ - return netdev->last_status_code; -} - static void netdev_set_powered_result(int error, uint16_t type, const void *data, uint32_t len, void *user_data) @@ -586,7 +581,7 @@ static void netdev_connect_free(struct netdev *netdev) netdev->event_filter = NULL; netdev->user_data = NULL; netdev->result = NETDEV_RESULT_OK; - netdev->last_status_code = 0; + netdev->last_code = 0; netdev->in_ft = false; netdev_rssi_polling_update(netdev); @@ -602,22 +597,19 @@ static void netdev_connect_free(struct netdev *netdev) static void netdev_connect_failed(struct netdev *netdev, enum netdev_result result, - uint16_t status_code) + uint16_t status_or_reason) { netdev_connect_cb_t connect_cb = netdev->connect_cb; netdev_event_func_t event_filter = netdev->event_filter; void *connect_data = netdev->user_data; - netdev->result = result; - netdev->last_status_code = status_code; - netdev->disconnect_cmd_id = 0; /* Done this way to allow re-entrant netdev_connect calls */ netdev_connect_free(netdev); if (connect_cb) - connect_cb(netdev, result, connect_data); + connect_cb(netdev, result, &status_or_reason, connect_data); else if (event_filter) event_filter(netdev, NETDEV_EVENT_DISCONNECT_BY_SME, connect_data); @@ -627,9 +619,7 @@ static void netdev_disconnect_cb(struct l_genl_msg *msg, void *user_data) { struct netdev *netdev = user_data; - /* FIXME: This should be a status code */ - netdev_connect_failed(netdev, netdev->result, - MMPDU_REASON_CODE_UNSPECIFIED); + netdev_connect_failed(netdev, netdev->result, netdev->last_code); } static void netdev_free(void *data) @@ -1056,7 +1046,8 @@ static void netdev_connect_ok(struct netdev *netdev) netdev->operational = true; if (netdev->connect_cb) { - netdev->connect_cb(netdev, NETDEV_RESULT_OK, netdev->user_data); + netdev->connect_cb(netdev, NETDEV_RESULT_OK, NULL, + netdev->user_data); netdev->connect_cb = NULL; } @@ -1488,7 +1479,7 @@ void netdev_handshake_failed(struct handshake_state *hs, uint16_t reason_code) netdev->sm = NULL; netdev->result = NETDEV_RESULT_HANDSHAKE_FAILED; - netdev->last_status_code = reason_code; + netdev->last_code = reason_code; switch (netdev->type) { case NL80211_IFTYPE_STATION: @@ -2081,7 +2072,7 @@ static void netdev_cmd_ft_reassociate_cb(struct l_genl_msg *msg, struct l_genl_msg *cmd_deauth; netdev->result = NETDEV_RESULT_ASSOCIATION_FAILED; - netdev->last_status_code = MMPDU_REASON_CODE_UNSPECIFIED; + netdev->last_code = MMPDU_STATUS_CODE_UNSPECIFIED; cmd_deauth = netdev_build_cmd_deauthenticate(netdev, MMPDU_REASON_CODE_UNSPECIFIED); netdev->disconnect_cmd_id = l_genl_family_send(nl80211, @@ -2274,7 +2265,7 @@ auth_error: ft_error: netdev->result = NETDEV_RESULT_AUTHENTICATION_FAILED; - netdev->last_status_code = MMPDU_REASON_CODE_UNSPECIFIED; + netdev->last_code = MMPDU_STATUS_CODE_UNSPECIFIED; cmd_deauth = netdev_build_cmd_deauthenticate(netdev, MMPDU_REASON_CODE_UNSPECIFIED); netdev->disconnect_cmd_id = l_genl_family_send(nl80211, cmd_deauth, @@ -2360,7 +2351,7 @@ static void netdev_authenticate_event(struct l_genl_msg *msg, auth_error: netdev_connect_failed(netdev, NETDEV_RESULT_AUTHENTICATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } static void netdev_associate_event(struct l_genl_msg *msg, @@ -2399,7 +2390,7 @@ static void netdev_associate_event(struct l_genl_msg *msg, assoc_failed: netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data) @@ -2435,7 +2426,7 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data) } netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } static struct l_genl_msg *netdev_build_cmd_authenticate(struct netdev *netdev, @@ -2504,7 +2495,7 @@ static void netdev_sae_complete(uint16_t status, void *user_data) auth_failed: netdev_connect_failed(netdev, NETDEV_RESULT_AUTHENTICATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } static void netdev_tx_sae_frame_cb(struct l_genl_msg *msg, @@ -2544,7 +2535,7 @@ static void netdev_owe_auth_cb(struct l_genl_msg *msg, void *user_data) netdev_connect_failed(netdev, NETDEV_RESULT_AUTHENTICATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); return; } } @@ -2563,7 +2554,7 @@ static void netdev_owe_tx_authenticate(void *user_data) l_genl_msg_unref(msg); netdev_connect_failed(netdev, NETDEV_RESULT_AUTHENTICATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } } @@ -2575,7 +2566,7 @@ static void netdev_owe_assoc_cb(struct l_genl_msg *msg, void *user_data) l_error("Error sending CMD_ASSOCIATE"); netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } } @@ -2593,7 +2584,7 @@ static void netdev_owe_tx_associate(struct iovec *ie_iov, size_t iov_len, netdev, NULL)) { l_genl_msg_unref(msg); netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } } @@ -3151,7 +3142,7 @@ static void netdev_cmd_authenticate_ft_cb(struct l_genl_msg *msg, if (l_genl_msg_get_error(msg) < 0) netdev_connect_failed(netdev, NETDEV_RESULT_AUTHENTICATION_FAILED, - MMPDU_REASON_CODE_UNSPECIFIED); + MMPDU_STATUS_CODE_UNSPECIFIED); } int netdev_fast_transition(struct netdev *netdev, struct scan_bss *target_bss, diff --git a/src/netdev.h b/src/netdev.h index 7b3bc282..7f02f8d3 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -66,8 +66,21 @@ enum netdev_iftype { typedef void (*netdev_command_cb_t)(struct netdev *netdev, int result, void *user_data); +/* + * Callback for a connection attempt. This callback is called on both success + * and failure. Depending on result, the event_data will have different + * meanings: + * + * NETDEV_RESULT_OK - unused + * NETDEV_RESULT_AUTHENTICATION_FAILED - MMPDU_STATUS_CODE + * NETDEV_RESULT_ASSOCIATION_FAILED - MMPDU_STATUS_CODE + * NETDEV_RESULT_HANDSHAKE_FAILED - MMPDU_REASON_CODE + * NETDEV_RESULT_KEY_SETTINGS_FAILED - unused + * NETDEV_RESULT_ABORTED - unused. + */ typedef void (*netdev_connect_cb_t)(struct netdev *netdev, enum netdev_result result, + void *event_data, void *user_data); typedef void (*netdev_event_func_t)(struct netdev *netdev, enum netdev_event event, @@ -110,7 +123,6 @@ const char *netdev_get_name(struct netdev *netdev); bool netdev_get_is_up(struct netdev *netdev); struct device *netdev_get_device(struct netdev *netdev); const char *netdev_get_path(struct netdev *netdev); -uint16_t netdev_get_last_status_code(struct netdev *netdev); struct handshake_state *netdev_handshake_state_new(struct netdev *netdev); struct handshake_state *netdev_get_handshake(struct netdev *netdev); diff --git a/src/station.c b/src/station.c index 95a313cb..1b267259 100644 --- a/src/station.c +++ b/src/station.c @@ -849,6 +849,7 @@ static void station_roam_failed(struct station *station) static void station_reassociate_cb(struct netdev *netdev, enum netdev_result result, + void *event_data, void *user_data) { struct station *station = user_data; @@ -867,6 +868,7 @@ static void station_reassociate_cb(struct netdev *netdev, static void station_fast_transition_cb(struct netdev *netdev, enum netdev_result result, + void *event_data, void *user_data) { struct station *station = user_data; @@ -1670,10 +1672,9 @@ static void station_connect_dbus_reply(struct station *station, } static void station_connect_cb(struct netdev *netdev, enum netdev_result result, - void *user_data) + void *event_data, void *user_data) { struct station *station = user_data; - uint16_t status_code = netdev_get_last_status_code(netdev); l_debug("%u, result: %d", netdev_get_ifindex(station->netdev), result); @@ -1682,7 +1683,8 @@ static void station_connect_cb(struct netdev *netdev, enum netdev_result result, blacklist_remove_bss(station->connected_bss->addr); break; case NETDEV_RESULT_HANDSHAKE_FAILED: - if (!station_can_retry(status_code)) + /* reason code in this case */ + if (!station_can_retry(l_get_u16(event_data))) break; /* fall through */ case NETDEV_RESULT_AUTHENTICATION_FAILED: diff --git a/src/wsc.c b/src/wsc.c index 3ed910c5..5fb00db6 100644 --- a/src/wsc.c +++ b/src/wsc.c @@ -204,7 +204,7 @@ static void wsc_disconnect_cb(struct netdev *netdev, bool success, } static void wsc_connect_cb(struct netdev *netdev, enum netdev_result result, - void *user_data) + void *event_data, void *user_data) { struct wsc *wsc = user_data; @@ -373,7 +373,7 @@ static void wsc_netdev_event(struct netdev *netdev, enum netdev_event event, case NETDEV_EVENT_DISCONNECT_BY_AP: l_debug("Disconnect by AP"); wsc_connect_cb(wsc->netdev, - NETDEV_RESULT_HANDSHAKE_FAILED, wsc); + NETDEV_RESULT_HANDSHAKE_FAILED, NULL, wsc); break; case NETDEV_EVENT_RSSI_THRESHOLD_LOW: case NETDEV_EVENT_RSSI_THRESHOLD_HIGH: