From 1f68696578ea4d2530fcba7ed4efb64eb9124aa3 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Wed, 16 Sep 2020 11:17:49 +0200 Subject: [PATCH] ap: Pass "ops" struct to ap_start() Pass the event callback function pointer in a "struct ap_ops" instead of as individual ap_start() argument to make adding new callbacks easier. --- src/ap.c | 65 +++++++++++++++++++++++++++++++------------------------- src/ap.h | 9 +++++--- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/ap.c b/src/ap.c index b87f49a3..5ee07ad2 100644 --- a/src/ap.c +++ b/src/ap.c @@ -53,7 +53,7 @@ struct ap_state { struct netdev *netdev; struct l_genl_family *nl80211; - ap_event_func_t event_func; + const struct ap_ops *ops; ap_stopped_func_t stopped_func; void *user_data; struct ap_config *config; @@ -211,7 +211,7 @@ static void ap_del_station(struct sta_state *sta, uint16_t reason, sta->associated = false; if (sta->rsna) { - if (ap->event_func) { + if (ap->ops->handle_event) { memset(&event_data, 0, sizeof(event_data)); event_data.mac = sta->addr; event_data.reason = reason; @@ -229,8 +229,8 @@ static void ap_del_station(struct sta_state *sta, uint16_t reason, ap_stop_handshake(sta); if (send_event) - ap->event_func(AP_EVENT_STATION_REMOVED, &event_data, - ap->user_data); + ap->ops->handle_event(AP_EVENT_STATION_REMOVED, &event_data, + ap->user_data); } static bool ap_sta_match_addr(const void *a, const void *b) @@ -270,12 +270,12 @@ static void ap_new_rsna(struct sta_state *sta) sta->rsna = true; - if (ap->event_func) { + if (ap->ops->handle_event) { struct ap_event_station_added_data event_data = {}; event_data.mac = sta->addr; event_data.rsn_ie = sta->assoc_rsne; - ap->event_func(AP_EVENT_STATION_ADDED, &event_data, - ap->user_data); + ap->ops->handle_event(AP_EVENT_STATION_ADDED, &event_data, + ap->user_data); } } @@ -309,11 +309,11 @@ static void ap_drop_rsna(struct sta_state *sta) ap_stop_handshake(sta); - if (ap->event_func) { + if (ap->ops->handle_event) { struct ap_event_station_removed_data event_data = {}; event_data.mac = sta->addr; - ap->event_func(AP_EVENT_STATION_REMOVED, &event_data, - ap->user_data); + ap->ops->handle_event(AP_EVENT_STATION_REMOVED, &event_data, + ap->user_data); } } @@ -544,7 +544,7 @@ static void ap_wsc_exit_pbc(struct ap_state *ap) ap->wsc_dpid = 0; ap_update_beacon(ap); - ap->event_func(AP_EVENT_PBC_MODE_EXIT, NULL, ap->user_data); + ap->ops->handle_event(AP_EVENT_PBC_MODE_EXIT, NULL, ap->user_data); } static uint32_t ap_send_mgmt_frame(struct ap_state *ap, @@ -751,8 +751,9 @@ static void ap_wsc_handshake_event(struct handshake_state *hs, &expiry_data); event_data.mac = sta->addr; - sta->ap->event_func(AP_EVENT_REGISTRATION_SUCCESS, &event_data, - sta->ap->user_data); + sta->ap->ops->handle_event(AP_EVENT_REGISTRATION_SUCCESS, + &event_data, + sta->ap->user_data); break; default: break; @@ -1330,8 +1331,8 @@ static void ap_assoc_reassoc(struct sta_state *sta, bool reassoc, sta->wsc_v2 = wsc_req.version2; event_data.mac = sta->addr; - ap->event_func(AP_EVENT_REGISTRATION_START, &event_data, - ap->user_data); + ap->ops->handle_event(AP_EVENT_REGISTRATION_START, &event_data, + ap->user_data); /* * Since we're starting the PBC Registration Protocol @@ -1914,7 +1915,8 @@ static void ap_start_cb(struct l_genl_msg *msg, void *user_data) if (l_genl_msg_get_error(msg) < 0) { l_error("START_AP failed: %i", l_genl_msg_get_error(msg)); - ap->event_func(AP_EVENT_START_FAILED, NULL, ap->user_data); + ap->ops->handle_event(AP_EVENT_START_FAILED, NULL, + ap->user_data); ap_reset(ap); l_genl_family_free(ap->nl80211); l_free(ap); @@ -1922,7 +1924,7 @@ static void ap_start_cb(struct l_genl_msg *msg, void *user_data) } ap->started = true; - ap->event_func(AP_EVENT_STARTED, NULL, ap->user_data); + ap->ops->handle_event(AP_EVENT_STARTED, NULL, ap->user_data); } static struct l_genl_msg *ap_build_cmd_start_ap(struct ap_state *ap) @@ -2009,11 +2011,12 @@ static void ap_mlme_notify(struct l_genl_msg *msg, void *user_data) l_genl_family_cancel(ap->nl80211, ap->start_stop_cmd_id); ap->start_stop_cmd_id = 0; - ap->event_func(AP_EVENT_START_FAILED, NULL, - ap->user_data); + ap->ops->handle_event(AP_EVENT_START_FAILED, NULL, + ap->user_data); } else if (ap->started) { ap->started = false; - ap->event_func(AP_EVENT_STOPPING, NULL, ap->user_data); + ap->ops->handle_event(AP_EVENT_STOPPING, NULL, + ap->user_data); } ap_reset(ap); @@ -2026,17 +2029,17 @@ static void ap_mlme_notify(struct l_genl_msg *msg, void *user_data) /* * Start a simple independent WPA2 AP on given netdev. * - * @event_func is required and must react to AP_EVENT_START_FAILED - * and AP_EVENT_STOPPING by forgetting the ap_state struct, which - * is going to be freed automatically. - * In the @config struct only .ssid and .psk need to be non-NUL, + * @ops.handle_event is required and must react to AP_EVENT_START_FAILED + * and AP_EVENT_STOPPING by forgetting the ap_state struct, which is + * going to be freed automatically. + * In the @config struct only .ssid and .psk need to be non-NULL, * other fields are optional. If @ap_start succeeds, the returned * ap_state takes ownership of @config and the caller shouldn't * free it or any of the memory pointed to by its members (they * also can't be static). */ struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config, - ap_event_func_t event_func, void *user_data) + const struct ap_ops *ops, void *user_data) { struct ap_state *ap; struct wiphy *wiphy = netdev_get_wiphy(netdev); @@ -2047,7 +2050,7 @@ struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config, ap->nl80211 = l_genl_family_new(iwd_get_genl(), NL80211_GENL_NAME); ap->config = config; ap->netdev = netdev; - ap->event_func = event_func; + ap->ops = ops; ap->user_data = user_data; if (!config->channel) @@ -2178,7 +2181,7 @@ static struct l_genl_msg *ap_build_cmd_stop_ap(struct ap_state *ap) /* * Schedule the running @ap to be stopped and freed. The original - * event_func and user_data are forgotten and a new callback can be + * ops and user_data are forgotten and a new callback can be * provided if the caller needs to know when the interface becomes * free, for example for a new ap_start call. * @@ -2195,7 +2198,7 @@ void ap_shutdown(struct ap_state *ap, ap_stopped_func_t stopped_func, if (ap->started) { ap->started = false; - ap->event_func(AP_EVENT_STOPPING, NULL, ap->user_data); + ap->ops->handle_event(AP_EVENT_STOPPING, NULL, ap->user_data); } ap_reset(ap); @@ -2365,6 +2368,10 @@ static void ap_if_event_func(enum ap_event_type type, const void *event_data, } } +static const struct ap_ops ap_dbus_ops = { + .handle_event = ap_if_event_func, +}; + static struct l_dbus_message *ap_dbus_start(struct l_dbus *dbus, struct l_dbus_message *message, void *user_data) { @@ -2385,7 +2392,7 @@ static struct l_dbus_message *ap_dbus_start(struct l_dbus *dbus, config->ssid = l_strdup(ssid); config->psk = l_strdup(wpa2_psk); - ap_if->ap = ap_start(ap_if->netdev, config, ap_if_event_func, ap_if); + ap_if->ap = ap_start(ap_if->netdev, config, &ap_dbus_ops, ap_if); if (!ap_if->ap) { ap_config_free(config); return dbus_error_invalid_args(message); diff --git a/src/ap.h b/src/ap.h index cb5238d1..bbfecd6d 100644 --- a/src/ap.h +++ b/src/ap.h @@ -52,8 +52,6 @@ struct ap_event_registration_success_data { const uint8_t *mac; }; -typedef void (*ap_event_func_t)(enum ap_event_type type, const void *event_data, - void *user_data); typedef void (*ap_stopped_func_t)(void *user_data); struct ap_config { @@ -67,10 +65,15 @@ struct ap_config { bool no_cck_rates : 1; }; +struct ap_ops { + void (*handle_event)(enum ap_event_type type, const void *event_data, + void *user_data); +}; + void ap_config_free(struct ap_config *config); struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config, - ap_event_func_t event_func, void *user_data); + const struct ap_ops *ops, void *user_data); void ap_shutdown(struct ap_state *ap, ap_stopped_func_t stopped_func, void *user_data); void ap_free(struct ap_state *ap);