From 3af51558f245ce99cfe26e33ba29898fddaa4892 Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Thu, 28 Feb 2019 15:41:51 -0800 Subject: [PATCH] netdev: pass event data to netdev events Several netdev events benefit from including event data in the callback. This is similar to how the connect callback works as well. The content of the event data is documented in netdev.h (netdev_event_func_t). By including event data for the two disconnect events, we can pass the reason code to better handle the failure in station.c. Now, inside station_disconnect_event, we still check if there is a pending connection, and if so we can call the connect callback directly with HANDSHAKE_FAILED. Doing it this way unifies the code path into a single switch statment to handle all failures. In addition, we pass the RSSI level index as event data to RSSI_LEVEL_NOTIFY. This removes the need for a getter to be exposed in netdev.h. --- src/netdev.c | 19 +++++++++---------- src/netdev.h | 15 ++++++++++++++- src/station.c | 43 +++++++++++++++++++++---------------------- src/wsc.c | 6 +++--- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/netdev.c b/src/netdev.c index b6ce57f0..3aa22196 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -474,6 +474,7 @@ static void netdev_rssi_poll_cb(struct l_genl_msg *msg, void *user_data) netdev_set_rssi_level_idx(netdev); if (netdev->cur_rssi_level_idx != prev_rssi_level_idx) netdev->event_filter(netdev, NETDEV_EVENT_RSSI_LEVEL_NOTIFY, + &netdev->cur_rssi_level_idx, netdev->user_data); done: @@ -612,6 +613,7 @@ static void netdev_connect_failed(struct netdev *netdev, connect_cb(netdev, result, &status_or_reason, connect_data); else if (event_filter) event_filter(netdev, NETDEV_EVENT_DISCONNECT_BY_SME, + &status_or_reason, connect_data); } @@ -709,7 +711,7 @@ static void netdev_lost_beacon(struct netdev *netdev) return; if (netdev->event_filter) - netdev->event_filter(netdev, NETDEV_EVENT_LOST_BEACON, + netdev->event_filter(netdev, NETDEV_EVENT_LOST_BEACON, NULL, netdev->user_data); } @@ -736,7 +738,7 @@ static void netdev_cqm_event_rssi_threshold(struct netdev *netdev, event = netdev->cur_rssi_low ? NETDEV_EVENT_RSSI_THRESHOLD_LOW : NETDEV_EVENT_RSSI_THRESHOLD_HIGH; - netdev->event_filter(netdev, event, netdev->user_data); + netdev->event_filter(netdev, event, NULL, netdev->user_data); } static void netdev_rssi_level_init(struct netdev *netdev) @@ -770,7 +772,7 @@ static void netdev_cqm_event_rssi_value(struct netdev *netdev, int rssi_val) NETDEV_EVENT_RSSI_THRESHOLD_HIGH; netdev->cur_rssi_low = new_rssi_low; - netdev->event_filter(netdev, event, netdev->user_data); + netdev->event_filter(netdev, event, NULL, netdev->user_data); } if (!netdev->rssi_levels_num) @@ -779,6 +781,7 @@ static void netdev_cqm_event_rssi_value(struct netdev *netdev, int rssi_val) netdev_set_rssi_level_idx(netdev); if (netdev->cur_rssi_level_idx != prev_rssi_level_idx) netdev->event_filter(netdev, NETDEV_EVENT_RSSI_LEVEL_NOTIFY, + &netdev->cur_rssi_level_idx, netdev->user_data); } @@ -922,10 +925,10 @@ static void netdev_disconnect_event(struct l_genl_msg *msg, if (disconnect_by_ap) event_filter(netdev, NETDEV_EVENT_DISCONNECT_BY_AP, - event_data); + &reason_code, event_data); else event_filter(netdev, NETDEV_EVENT_DISCONNECT_BY_SME, - event_data); + &reason_code, event_data); } static void netdev_cmd_disconnect_cb(struct l_genl_msg *msg, void *user_data) @@ -2404,6 +2407,7 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data) if (netdev->event_filter) netdev->event_filter(netdev, NETDEV_EVENT_ASSOCIATING, + NULL, netdev->user_data); /* the SAE SM can be freed */ @@ -4084,11 +4088,6 @@ done: return 0; } -int netdev_get_rssi_level(struct netdev *netdev) -{ - return netdev->cur_rssi_level_idx; -} - static int netdev_cqm_rssi_update(struct netdev *netdev) { struct l_genl_msg *msg = diff --git a/src/netdev.h b/src/netdev.h index 7f02f8d3..0e0292c8 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -82,8 +82,22 @@ typedef void (*netdev_connect_cb_t)(struct netdev *netdev, enum netdev_result result, void *event_data, void *user_data); +/* + * Notify function for netdev events. Depending on the event type, event_data + * will have different meanings: + * + * NETDEV_EVENT_AUTHENTICATING - unsused + * NETDEV_EVENT_ASSOCIATING - unused + * NETDEV_EVENT_LOST_BEACON - unused + * NETDEV_EVENT_DISCONNECT_BY_AP - MMPDU_REASON_CODE + * NETDEV_EVENT_DISCONNECT_BY_SME - MMPDU_REASON_CODE + * NETDEV_EVENT_RSSI_THRESHOLD_LOW - unused + * NETDEV_EVENT_RSSI_THRESHOLD_HIGH - unused + * NETDEV_EVENT_RSSI_LEVEL_NOTIFY - rssi level index (uint8_t) + */ typedef void (*netdev_event_func_t)(struct netdev *netdev, enum netdev_event event, + void *event_data, void *user_data); typedef void (*netdev_disconnect_cb_t)(struct netdev *netdev, bool result, void *user_data); @@ -168,7 +182,6 @@ int netdev_neighbor_report_req(struct netdev *netdev, int netdev_set_rssi_report_levels(struct netdev *netdev, const int8_t *levels, size_t levels_num); -int netdev_get_rssi_level(struct netdev *netdev); uint32_t netdev_frame_watch_add(struct netdev *netdev, uint16_t frame_type, const uint8_t *prefix, size_t prefix_len, diff --git a/src/station.c b/src/station.c index 1b267259..69c30b29 100644 --- a/src/station.c +++ b/src/station.c @@ -796,20 +796,19 @@ static void station_disassociated(struct station *station) station_enter_state(station, STATION_STATE_AUTOCONNECT); } -static void station_disconnect_event(struct station *station) +static void station_connect_cb(struct netdev *netdev, enum netdev_result result, + void *event_data, void *user_data); + +static void station_disconnect_event(struct station *station, void *event_data) { l_debug("%u", netdev_get_ifindex(station->netdev)); - if (station->connect_pending) { - struct network *network = station->connected_network; - - dbus_pending_reply(&station->connect_pending, - dbus_error_failed(station->connect_pending)); - - network_connect_failed(network); - } - - station_disassociated(station); + if (station->connect_pending) + station_connect_cb(station->netdev, + NETDEV_RESULT_HANDSHAKE_FAILED, + event_data, station); + else + station_disassociated(station); } static void station_roam_timeout_rearm(struct station *station, int seconds); @@ -886,7 +885,7 @@ static void station_fast_transition_cb(struct netdev *netdev, } static void station_netdev_event(struct netdev *netdev, enum netdev_event event, - void *user_data); + void *event_data, void *user_data); static void station_transition_reassociate(struct station *station, struct scan_bss *bss, @@ -1579,10 +1578,11 @@ static void station_ok_rssi(struct station *station) station->signal_low = false; } -static void station_rssi_level_changed(struct station *station); +static void station_rssi_level_changed(struct station *station, + uint8_t level_idx); static void station_netdev_event(struct netdev *netdev, enum netdev_event event, - void *user_data) + void *event_data, void *user_data) { struct station *station = user_data; @@ -1598,7 +1598,7 @@ static void station_netdev_event(struct netdev *netdev, enum netdev_event event, break; case NETDEV_EVENT_DISCONNECT_BY_AP: case NETDEV_EVENT_DISCONNECT_BY_SME: - station_disconnect_event(station); + station_disconnect_event(station, event_data); break; case NETDEV_EVENT_RSSI_THRESHOLD_LOW: station_low_rssi(station); @@ -1607,7 +1607,7 @@ static void station_netdev_event(struct netdev *netdev, enum netdev_event event, station_ok_rssi(station); break; case NETDEV_EVENT_RSSI_LEVEL_NOTIFY: - station_rssi_level_changed(station); + station_rssi_level_changed(station, l_get_u8(event_data)); break; }; } @@ -2165,22 +2165,22 @@ struct signal_agent { }; static void station_signal_agent_notify(struct signal_agent *agent, - const char *device_path, int level) + const char *device_path, uint8_t level) { struct l_dbus_message *msg; - uint8_t value = level; msg = l_dbus_message_new_method_call(dbus_get_bus(), agent->owner, agent->path, IWD_SIGNAL_AGENT_INTERFACE, "Changed"); - l_dbus_message_set_arguments(msg, "oy", device_path, value); + l_dbus_message_set_arguments(msg, "oy", device_path, level); l_dbus_message_set_no_reply(msg, true); l_dbus_send(dbus_get_bus(), msg); } -static void station_rssi_level_changed(struct station *station) +static void station_rssi_level_changed(struct station *station, + uint8_t level_idx) { struct netdev *netdev = station->netdev; @@ -2188,8 +2188,7 @@ static void station_rssi_level_changed(struct station *station) return; station_signal_agent_notify(station->signal_agent, - netdev_get_path(netdev), - netdev_get_rssi_level(netdev)); + netdev_get_path(netdev), level_idx); } static void station_signal_agent_release(struct signal_agent *agent, diff --git a/src/wsc.c b/src/wsc.c index 5fb00db6..64a5c2a9 100644 --- a/src/wsc.c +++ b/src/wsc.c @@ -359,7 +359,7 @@ static void wsc_eapol_event(uint32_t event, const void *event_data, } static void wsc_netdev_event(struct netdev *netdev, enum netdev_event event, - void *user_data) + void *event_data, void *user_data) { struct wsc *wsc = user_data; @@ -372,8 +372,8 @@ static void wsc_netdev_event(struct netdev *netdev, enum netdev_event event, break; case NETDEV_EVENT_DISCONNECT_BY_AP: l_debug("Disconnect by AP"); - wsc_connect_cb(wsc->netdev, - NETDEV_RESULT_HANDSHAKE_FAILED, NULL, wsc); + wsc_connect_cb(wsc->netdev, NETDEV_RESULT_HANDSHAKE_FAILED, + event_data, wsc); break; case NETDEV_EVENT_RSSI_THRESHOLD_LOW: case NETDEV_EVENT_RSSI_THRESHOLD_HIGH: