diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen index 2ca40ae9b..940f469d1 100644 --- a/doc/dbus.doxygen +++ b/doc/dbus.doxygen @@ -734,6 +734,11 @@ fi.w1.wpa_supplicant1.CreateInterface.

List of D-Bus objects paths representing BSSs known to the interface, i.e., scan results.

+
  • +

    Stations - ao - (read)

    +

    List of D-Bus objects paths representing connected stations in AP mode.

    +
  • +
  • Networks - ao - (read)

    List of D-Bus objects paths representing configured networks.

    @@ -1126,6 +1131,32 @@ fi.w1.wpa_supplicant1.CreateInterface.
  • +
  • +

    StationAdded ( o : Station, a{sv} : properties )

    +

    A new station has been added to the interface.

    +

    This signal complements StaAuthorized, passing the Station object and its properties.

    +

    Arguments

    +
    +
    o : Station
    +
    A D-Bus path to an object representing the new Station.
    +
    +
    +
    a{sv} : properties
    +
    A dictionary containing properties of added Station.
    +
    +
  • + +
  • +

    StationRemoved ( o : Station )

    +

    The station has been removed from the interface.

    +

    This signal complements StaDeauthorized, passing the Station object.

    +

    Arguments

    +
    +
    o : Station
    +
    A D-Bus path to an object representing the Station.
    +
    +
  • +
  • PropertiesChanged ( a{sv} : properties )

    Some properties have changed.

    diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 97655d569..96ab444d3 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -13,6 +13,7 @@ #include "common.h" #include "common/ieee802_11_defs.h" #include "wps/wps.h" +#include "ap/sta_info.h" #include "../config.h" #include "../wpa_supplicant_i.h" #include "../bss.h" @@ -1078,6 +1079,79 @@ void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s, } +/** + * wpas_dbus_signal_station - Send an event signal related to a station object + * @wpa_s: %wpa_supplicant network interface data + * @station_obj_path: Station object path + * @sig_name: signal name - StationAdded or StationRemoved + * @properties: Whether to add second argument with object properties + * + * Notify listeners about event related with station. + */ +static void wpas_dbus_signal_station(struct wpa_supplicant *wpa_s, + const char *station_obj_path, + const char *sig_name, + dbus_bool_t properties) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (!iface || !wpa_s->dbus_new_path) + return; + + wpa_printf(MSG_DEBUG, "dbus: STA signal %s", sig_name); + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name); + if (!msg) + return; + + dbus_message_iter_init_append(msg, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, + &station_obj_path) || + (properties && + !wpa_dbus_get_object_properties(iface, station_obj_path, + WPAS_DBUS_NEW_IFACE_STA, + &iter))) + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + else + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_station_added - Send a Station added signal + * @wpa_s: %wpa_supplicant network interface data + * @station_obj_path: new Station object path + * + * Notify listeners about adding new Station + */ +static void wpas_dbus_signal_station_added(struct wpa_supplicant *wpa_s, + const char *station_obj_path) +{ + wpas_dbus_signal_station(wpa_s, station_obj_path, "StationAdded", TRUE); +} + + +/** + * wpas_dbus_signal_station_removed - Send a Station removed signal + * @wpa_s: %wpa_supplicant network interface data + * @station_obj_path: Station object path + * + * Notify listeners about removing Station + */ +static void wpas_dbus_signal_station_removed(struct wpa_supplicant *wpa_s, + const char *station_obj_path) +{ + wpas_dbus_signal_station(wpa_s, station_obj_path, "StationRemoved", + FALSE); +} + + #ifdef CONFIG_P2P /** @@ -2147,6 +2221,9 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, case WPAS_DBUS_PROP_BSSS: prop = "BSSs"; break; + case WPAS_DBUS_PROP_STATIONS: + prop = "Stations"; + break; case WPAS_DBUS_PROP_CURRENT_AUTH_MODE: prop = "CurrentAuthMode"; break; @@ -2239,6 +2316,41 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s, } +/** + * wpas_dbus_sta_signal_prop_changed - Signals change of STA property + * @wpa_s: %wpa_supplicant network interface data + * @property: indicates which property has changed + * @address: unique BSS identifier + * + * Sends PropertyChanged signals with path, interface, and arguments depending + * on which property has changed. + */ +void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s, + enum wpas_dbus_bss_prop property, + u8 address[ETH_ALEN]) +{ + char path[WPAS_DBUS_OBJECT_PATH_MAX]; + char *prop; + + switch (property) { + case WPAS_DBUS_STA_PROP_ADDRESS: + prop = "Address"; + break; + default: + wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d", + __func__, property); + return; + } + + os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(address)); + + wpa_dbus_mark_property_changed(wpa_s->global->dbus, path, + WPAS_DBUS_NEW_IFACE_STA, prop); +} + + /** * wpas_dbus_signal_debug_level_changed - Signals change of debug param * @global: wpa_global structure @@ -2853,6 +2965,157 @@ err: } +static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = { + { "Address", WPAS_DBUS_NEW_IFACE_STA, "ay", + wpas_dbus_getter_sta_address, + NULL, NULL + }, + { "AID", WPAS_DBUS_NEW_IFACE_STA, "q", + wpas_dbus_getter_sta_aid, + NULL, NULL + }, + { "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q", + wpas_dbus_getter_sta_caps, + NULL, NULL + }, + { "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_rx_packets, + NULL, NULL + }, + { "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_tx_packets, + NULL, NULL + }, + { "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_rx_bytes, + NULL, NULL + }, + { "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t", + wpas_dbus_getter_sta_tx_bytes, + NULL, NULL + }, + { NULL, NULL, NULL, NULL, NULL, NULL } +}; + + +static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = { + /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */ + { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA, + { + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { NULL, NULL, { END_ARGS } } +}; + + +/** + * wpas_dbus_unregister_sta - Unregister a connected station from dbus + * @wpa_s: wpa_supplicant interface structure + * @sta: station MAC address + * Returns: 0 on success, -1 on failure + * + * Unregisters STA representing object from dbus. + */ +int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta) +{ + struct wpas_dbus_priv *ctrl_iface; + char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + + /* Do nothing if the control interface is not turned on */ + if (!wpa_s || !wpa_s->global) + return 0; + ctrl_iface = wpa_s->global->dbus; + if (!ctrl_iface) + return 0; + + os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(sta)); + + wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'", + station_obj_path); + if (wpa_dbus_unregister_object_per_iface(ctrl_iface, + station_obj_path)) { + wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s", + station_obj_path); + return -1; + } + + wpas_dbus_signal_station_removed(wpa_s, station_obj_path); + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS); + + return 0; +} + + +/** + * wpas_dbus_register_sta - Register a connected station with dbus + * @wpa_s: wpa_supplicant interface structure + * @sta: station MAC address + * Returns: 0 on success, -1 on failure + * + * Registers STA representing object with dbus. + */ +int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta) +{ + struct wpas_dbus_priv *ctrl_iface; + struct wpa_dbus_object_desc *obj_desc; + char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + struct sta_handler_args *arg; + + /* Do nothing if the control interface is not turned on */ + if (!wpa_s || !wpa_s->global) + return 0; + ctrl_iface = wpa_s->global->dbus; + if (!ctrl_iface) + return 0; + + os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(sta)); + + obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); + if (!obj_desc) { + wpa_printf(MSG_ERROR, + "Not enough memory to create object description"); + goto err; + } + + arg = os_zalloc(sizeof(struct sta_handler_args)); + if (!arg) { + wpa_printf(MSG_ERROR, + "Not enough memory to create arguments for handler"); + goto err; + } + arg->wpa_s = wpa_s; + arg->sta = sta; + + wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL, + wpas_dbus_sta_properties, wpas_dbus_sta_signals); + + wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'", + station_obj_path); + if (wpa_dbus_register_object_per_iface(ctrl_iface, station_obj_path, + wpa_s->ifname, obj_desc)) { + wpa_printf(MSG_ERROR, + "Cannot register STA dbus object %s", + station_obj_path); + goto err; + } + + wpas_dbus_signal_station_added(wpa_s, station_obj_path); + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS); + + return 0; + +err: + free_dbus_object_desc(obj_desc); + return -1; +} + + static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE, (WPADBusMethodHandler) wpas_dbus_handler_scan, @@ -3490,6 +3753,11 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { NULL }, #endif /* CONFIG_MESH */ + { "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", + wpas_dbus_getter_stas, + NULL, + NULL + }, { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -3759,6 +4027,19 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { END_ARGS } }, + { "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + END_ARGS + } + }, { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE, { { "path", "o", ARG_OUT }, diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index 40ae133b2..be2ce0d33 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -28,6 +28,7 @@ enum wpas_dbus_prop { WPAS_DBUS_PROP_CURRENT_NETWORK, WPAS_DBUS_PROP_CURRENT_AUTH_MODE, WPAS_DBUS_PROP_BSSS, + WPAS_DBUS_PROP_STATIONS, WPAS_DBUS_PROP_DISCONNECT_REASON, WPAS_DBUS_PROP_ASSOC_STATUS_CODE, }; @@ -45,6 +46,10 @@ enum wpas_dbus_bss_prop { WPAS_DBUS_BSS_PROP_AGE, }; +enum wpas_dbus_sta_prop { + WPAS_DBUS_STA_PROP_ADDRESS, +}; + #define WPAS_DBUS_OBJECT_PATH_MAX 150 #define WPAS_DBUS_NEW_SERVICE "fi.w1.wpa_supplicant1" @@ -61,6 +66,9 @@ enum wpas_dbus_bss_prop { #define WPAS_DBUS_NEW_BSSIDS_PART "BSSs" #define WPAS_DBUS_NEW_IFACE_BSS WPAS_DBUS_NEW_INTERFACE ".BSS" +#define WPAS_DBUS_NEW_STAS_PART "Stations" +#define WPAS_DBUS_NEW_IFACE_STA WPAS_DBUS_NEW_INTERFACE ".Station" + #define WPAS_DBUS_NEW_IFACE_P2PDEVICE \ WPAS_DBUS_NEW_IFACE_INTERFACE ".P2PDevice" @@ -163,6 +171,8 @@ int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, u8 bssid[ETH_ALEN], unsigned int id); int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, u8 bssid[ETH_ALEN], unsigned int id); +int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta); +int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta); void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s, const char *name); void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s, @@ -345,6 +355,18 @@ static inline int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, return 0; } +static inline int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, + const u8 *sta) +{ + return 0; +} + +static inline int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, + const u8 *sta) +{ + return 0; +} + static inline void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s, const char *name) { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 94773b329..2a6ad5818 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -15,6 +15,9 @@ #include "eap_peer/eap_methods.h" #include "eapol_supp/eapol_supp_sm.h" #include "rsn_supp/wpa.h" +#include "ap/hostapd.h" +#include "ap/sta_info.h" +#include "ap/ap_drv_ops.h" #include "../config.h" #include "../wpa_supplicant_i.h" #include "../driver_i.h" @@ -22,6 +25,7 @@ #include "../bss.h" #include "../scan.h" #include "../autoscan.h" +#include "../ap.h" #include "dbus_new_helpers.h" #include "dbus_new.h" #include "dbus_new_handlers.h" @@ -3805,6 +3809,289 @@ dbus_bool_t wpas_dbus_setter_iface_global( } +/** + * wpas_dbus_getter_stas - Get connected stations for an interface + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: a list of stations + * + * Getter for "Stations" property. + */ +dbus_bool_t wpas_dbus_getter_stas( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + struct hostapd_data *hapd; + struct sta_info *sta = NULL; + char **paths = NULL; + unsigned int i = 0, num = 0; + dbus_bool_t success = FALSE; + + if (!wpa_s->dbus_new_path) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: no D-Bus interface", __func__); + return FALSE; + } + + if (wpa_s->ap_iface) { + hapd = wpa_s->ap_iface->bss[0]; + sta = hapd->sta_list; + num = hapd->num_sta; + } + + paths = os_calloc(num, sizeof(char *)); + if (!paths) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; + } + + /* Loop through scan results and append each result's object path */ + for (; sta; sta = sta->next) { + paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); + if (!paths[i]) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); + goto out; + } + /* Construct the object path for this BSS. */ + os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(sta->addr)); + } + + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + paths, num, + error); + +out: + while (i) + os_free(paths[--i]); + os_free(paths); + return success; +} + + +/** + * wpas_dbus_getter_sta_address - Return the address of a connected station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "Address" property. + */ +dbus_bool_t wpas_dbus_getter_sta_address( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct sta_handler_args *args = user_data; + struct sta_info *sta; + + sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta); + if (!sta) + return FALSE; + + return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, + sta->addr, ETH_ALEN, + error); +} + + +/** + * wpas_dbus_getter_sta_aid - Return the AID of a connected station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "AID" property. + */ +dbus_bool_t wpas_dbus_getter_sta_aid( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct sta_handler_args *args = user_data; + struct sta_info *sta; + + sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta); + if (!sta) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16, + &sta->aid, + error); +} + + +/** + * wpas_dbus_getter_sta_caps - Return the capabilities of a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "Capabilities" property. + */ +dbus_bool_t wpas_dbus_getter_sta_caps( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct sta_handler_args *args = user_data; + struct sta_info *sta; + + sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta); + if (!sta) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16, + &sta->capability, + error); +} + + +/** + * wpas_dbus_getter_rx_packets - Return the received packets for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "RxPackets" property. + */ +dbus_bool_t wpas_dbus_getter_sta_rx_packets( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.rx_packets, + error); +} + + +/** + * wpas_dbus_getter_tx_packets - Return the transmitted packets for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "TxPackets" property. + */ +dbus_bool_t wpas_dbus_getter_sta_tx_packets( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.tx_packets, + error); +} + + +/** + * wpas_dbus_getter_tx_bytes - Return the transmitted bytes for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "TxBytes" property. + */ +dbus_bool_t wpas_dbus_getter_sta_tx_bytes( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.tx_bytes, + error); +} + + +/** + * wpas_dbus_getter_rx_bytes - Return the received bytes for a station + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "RxBytes" property. + */ +dbus_bool_t wpas_dbus_getter_sta_rx_bytes( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct sta_handler_args *args = user_data; + struct sta_info *sta; + struct hostap_sta_driver_data data; + struct hostapd_data *hapd; + + if (!args->wpa_s->ap_iface) + return FALSE; + + hapd = args->wpa_s->ap_iface->bss[0]; + sta = ap_get_sta(hapd, args->sta); + if (!sta) + return FALSE; + + if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) + return FALSE; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64, + &data.rx_bytes, + error); +} + + static struct wpa_bss * get_bss_helper(struct bss_handler_args *args, DBusError *error, const char *func_name) { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index 6f952cc39..1907a8a51 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -22,6 +22,11 @@ struct bss_handler_args { unsigned int id; }; +struct sta_handler_args { + struct wpa_supplicant *wpa_s; + const u8 *sta; +}; + dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter, const int type, const void *val, @@ -166,6 +171,14 @@ DECLARE_ACCESSOR(wpas_dbus_getter_networks); DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_engine_path); DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_module_path); DECLARE_ACCESSOR(wpas_dbus_getter_blobs); +DECLARE_ACCESSOR(wpas_dbus_getter_stas); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_address); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_aid); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_caps); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_packets); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_packets); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_bytes); +DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_bytes); DECLARE_ACCESSOR(wpas_dbus_getter_bss_bssid); DECLARE_ACCESSOR(wpas_dbus_getter_bss_ssid); DECLARE_ACCESSOR(wpas_dbus_getter_bss_privacy); diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index 83df04f39..75f762daf 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -720,6 +720,9 @@ static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s, wpas_dbus_signal_p2p_peer_joined(wpa_s, p2p_dev_addr); #endif /* CONFIG_P2P */ + /* Register the station */ + wpas_dbus_register_sta(wpa_s, sta); + /* Notify listeners a new station has been authorized */ wpas_dbus_signal_sta_authorized(wpa_s, sta); } @@ -740,6 +743,9 @@ static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s, /* Notify listeners a station has been deauthorized */ wpas_dbus_signal_sta_deauthorized(wpa_s, sta); + + /* Unregister the station */ + wpas_dbus_unregister_sta(wpa_s, sta); }