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.
This commit is contained in:
James Prestwood 2019-02-28 15:41:51 -08:00 committed by Denis Kenzior
parent a5424829b6
commit 3af51558f2
4 changed files with 47 additions and 36 deletions

View File

@ -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 =

View File

@ -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,

View File

@ -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,

View File

@ -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: