diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index 04bdf5a66..9f5f17ea0 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -117,13 +117,17 @@ registered in the bus with fi.w1.wpa_supplicant1 name.
-
-
InterfaceAdded ( o : interface )
+ InterfaceAdded ( o : interface, a{sv} : properties )
A new interface was added to %wpa_supplicant.
Arguments
- o : interface
- A D-Bus path to an object representing the added interface
+
+ - a{sv} : properties
+ - A dictionary containing properties of added interface.
+
-
@@ -402,13 +406,17 @@ fi.w1.wpa_supplicant1.CreateInterface.
-
-
BSSAdded ( o : BSS )
+ BSSAdded ( o : BSS, a{sv} : properties )
Interface became aware of a new BSS.
Arguments
- o : BSS
- A D-Bus path to an object representing the new BSS.
+
+ - a{sv} : properties
+ - A dictionary containing properties of added BSS.
+
-
@@ -442,13 +450,17 @@ fi.w1.wpa_supplicant1.CreateInterface.
-
-
NetworkAdded ( o : network )
+ NetworkAdded ( o : network, a{sv} : properties )
A new network has been added to the interface.
Arguments
- o : network
- A D-Bus path to an object representing the added network.
+
+ - a{sv} : properties
+ - A dictionary containing properties of added network.
+
-
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index f8d5767a2..568bb62cf 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -51,14 +51,16 @@ static int wpas_dbus_set_path(struct wpa_supplicant *wpa_s,
* wpas_dbus_signal_interface - Send a interface related event signal
* @wpa_s: %wpa_supplicant network interface data
* @sig_name: signal name - InterfaceAdded or InterfaceRemoved
+ * @properties: determines if add second argument with object properties
*
* Notify listeners about event related with interface
*/
static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
- const char *sig_name)
+ const char *sig_name, int properties)
{
struct wpas_dbus_priv *iface;
DBusMessage *_signal;
+ DBusMessageIter iter, iter_dict;
const char *path;
iface = wpa_s->global->dbus;
@@ -82,13 +84,32 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
return;
}
- if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID)) {
- dbus_connection_send(iface->con, _signal, NULL);
- } else {
- wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
- "not enough memory to construct signal.");
+ dbus_message_iter_init_append(_signal, &iter);
+
+ if(!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &path))
+ goto err;
+
+ if (properties) {
+ if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
+ goto err;
+
+ wpa_dbus_get_object_properties(iface, path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ &iter_dict);
+
+ if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+ goto err;
}
+
+ dbus_connection_send(iface->con, _signal, NULL);
+
+ dbus_message_unref(_signal);
+ return;
+
+err:
+ wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
+ "not enough memory to construct signal.");
dbus_message_unref(_signal);
}
@@ -101,7 +122,7 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
*/
static void wpas_dbus_signal_interface_created(struct wpa_supplicant *wpa_s)
{
- wpas_dbus_signal_interface(wpa_s, "InterfaceCreated");
+ wpas_dbus_signal_interface(wpa_s, "InterfaceCreated", TRUE);
}
@@ -113,7 +134,7 @@ static void wpas_dbus_signal_interface_created(struct wpa_supplicant *wpa_s)
*/
static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
{
- wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved");
+ wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
}
@@ -171,15 +192,17 @@ static void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
* @wpa_s: %wpa_supplicant network interface data
* @bss_obj_path: BSS object path
* @sig_name: signal name - BSSAdded or BSSRemoved
+ * @properties: determines if add second argument with object properties
*
* Notify listeners about event related with BSS
*/
static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
const char *bss_obj_path,
- const char *sig_name)
+ const char *sig_name, int properties)
{
struct wpas_dbus_priv *iface;
DBusMessage *_signal;
+ DBusMessageIter iter, iter_dict;
const char *path;
iface = wpa_s->global->dbus;
@@ -203,13 +226,32 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
return;
}
- if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
- &bss_obj_path, DBUS_TYPE_INVALID)) {
- dbus_connection_send(iface->con, _signal, NULL);
- } else {
- wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
- "not enough memory to construct signal.");
+ dbus_message_iter_init_append(_signal, &iter);
+
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &bss_obj_path))
+ goto err;
+
+ if (properties) {
+ if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
+ goto err;
+
+ wpa_dbus_get_object_properties(iface, bss_obj_path,
+ WPAS_DBUS_NEW_IFACE_BSSID,
+ &iter_dict);
+
+ if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+ goto err;
}
+
+ dbus_connection_send(iface->con, _signal, NULL);
+
+ dbus_message_unref(_signal);
+ return;
+
+err:
+ wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
+ "not enough memory to construct signal.");
dbus_message_unref(_signal);
}
@@ -224,7 +266,7 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
const char *bss_obj_path)
{
- wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded");
+ wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
}
@@ -238,7 +280,7 @@ static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
const char *bss_obj_path)
{
- wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved");
+ wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
}
@@ -322,14 +364,17 @@ static void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
* @wpa_s: %wpa_supplicant network interface data
* @id: new network id
* @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
+ * @properties: determines if add second argument with object properties
*
* Notify listeners about event related with configured network
*/
static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
- int id, const char *sig_name)
+ int id, const char *sig_name,
+ int properties)
{
struct wpas_dbus_priv *iface;
DBusMessage *_signal;
+ DBusMessageIter iter, iter_dict;
const char *path;
char *net_obj_path;
@@ -362,14 +407,33 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
return;
}
- if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
- &net_obj_path, DBUS_TYPE_INVALID)) {
- dbus_connection_send(iface->con, _signal, NULL);
- } else {
- wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
- "not enough memory to construct signal.");
+ dbus_message_iter_init_append(_signal, &iter);
+
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &net_obj_path))
+ goto err;
+
+ if (properties) {
+ if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
+ goto err;
+
+ wpa_dbus_get_object_properties(iface, net_obj_path,
+ WPAS_DBUS_NEW_IFACE_NETWORK,
+ &iter_dict);
+
+ if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+ goto err;
}
+ dbus_connection_send(iface->con, _signal, NULL);
+
+ os_free(net_obj_path);
+ dbus_message_unref(_signal);
+ return;
+
+err:
+ wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
+ "not enough memory to construct signal.");
os_free(net_obj_path);
dbus_message_unref(_signal);
}
@@ -385,7 +449,7 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
int id)
{
- wpas_dbus_signal_network(wpa_s, id, "NetworkAdded");
+ wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
}
@@ -399,7 +463,7 @@ static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
int id)
{
- wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved");
+ wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
}
@@ -413,7 +477,7 @@ static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
static void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s,
int id)
{
- wpas_dbus_signal_network(wpa_s, id, "NetworkSelected");
+ wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
}
@@ -1013,7 +1077,7 @@ static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
R
},
{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
- wpas_dbus_getter_eap_methods,
+ (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
NULL,
R
},
@@ -1024,6 +1088,7 @@ static const struct wpas_dbus_signal wpas_dbus_global_signals[] = {
{ "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
{
{ "path", "o", ARG_OUT },
+ { "properties", "a{sv}", ARG_OUT },
END_ARGS
}
},
@@ -1584,6 +1649,7 @@ static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
{ "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
{
{ "path", "o", ARG_OUT },
+ { "properties", "a{sv}", ARG_OUT },
END_ARGS
}
},
@@ -1608,6 +1674,7 @@ static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
{ "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
{
{ "path", "o", ARG_OUT },
+ { "properties", "a{sv}", ARG_OUT },
END_ARGS
}
},
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c
index e4829f274..e71aba7c6 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.c
+++ b/wpa_supplicant/dbus/dbus_new_helpers.c
@@ -607,6 +607,52 @@ static void recursive_iter_copy(DBusMessageIter *from, DBusMessageIter *to)
}
+static unsigned int fill_dict_with_properties(
+ DBusMessageIter *dict_iter, struct wpa_dbus_property_desc *props,
+ const char *interface, const void *user_data)
+{
+ DBusMessage *reply;
+ DBusMessageIter entry_iter, ret_iter;
+ unsigned int counter = 0;
+ struct wpa_dbus_property_desc *property_dsc;
+
+ for (property_dsc = props; property_dsc;
+ property_dsc = property_dsc->next) {
+ if (!os_strncmp(property_dsc->dbus_interface, interface,
+ WPAS_DBUS_INTERFACE_MAX) &&
+ property_dsc->access != W && property_dsc->getter) {
+ reply = property_dsc->getter(NULL, user_data);
+ if (!reply)
+ continue;
+
+ if (dbus_message_get_type(reply) ==
+ DBUS_MESSAGE_TYPE_ERROR) {
+ dbus_message_unref(reply);
+ continue;
+ }
+
+ dbus_message_iter_init(reply, &ret_iter);
+
+ dbus_message_iter_open_container(dict_iter,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry_iter);
+ dbus_message_iter_append_basic(
+ &entry_iter, DBUS_TYPE_STRING,
+ &(property_dsc->dbus_property));
+
+ recursive_iter_copy(&ret_iter, &entry_iter);
+
+ dbus_message_iter_close_container(dict_iter,
+ &entry_iter);
+ dbus_message_unref(reply);
+ counter++;
+ }
+ }
+
+ return counter;
+}
+
+
/**
* get_all_properties - Responds for GetAll properties calls on object
* @message: Message with GetAll call
@@ -625,12 +671,8 @@ static DBusMessage * get_all_properties(
{
/* Create and initialize the return message */
DBusMessage *reply = dbus_message_new_method_return(message);
- DBusMessage *getterReply = NULL;
- DBusMessageIter iter, dict_iter, entry_iter, ret_iter;
- int counter = 0;
- struct wpa_dbus_property_desc *property_dsc;
-
- property_dsc = obj_dsc->properties;
+ DBusMessageIter iter, dict_iter;
+ int props_num;
dbus_message_iter_init_append(reply, &iter);
@@ -641,37 +683,12 @@ static DBusMessage * get_all_properties(
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict_iter);
- while (property_dsc) {
- if (!os_strncmp(property_dsc->dbus_interface, interface,
- WPAS_DBUS_INTERFACE_MAX) &&
- property_dsc->access != W && property_dsc->getter) {
+ props_num = fill_dict_with_properties(&dict_iter,obj_dsc->properties,
+ interface, obj_dsc->user_data);
- getterReply = property_dsc->getter(
- message, obj_dsc->user_data);
- if (getterReply == NULL)
- goto skip;
- dbus_message_iter_init(getterReply, &ret_iter);
-
- dbus_message_iter_open_container(&dict_iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &entry_iter);
- dbus_message_iter_append_basic(
- &entry_iter, DBUS_TYPE_STRING,
- &(property_dsc->dbus_property));
-
- recursive_iter_copy(&ret_iter, &entry_iter);
-
- dbus_message_iter_close_container(&dict_iter,
- &entry_iter);
- dbus_message_unref(getterReply);
- skip:
- counter++;
- }
- property_dsc = property_dsc->next;
- }
dbus_message_iter_close_container(&iter, &dict_iter);
- if (counter == 0) {
+ if (props_num == 0) {
dbus_message_unref(reply);
reply = dbus_message_new_error(message,
DBUS_ERROR_INVALID_ARGS,
@@ -1574,3 +1591,34 @@ err:
dbus_message_unref(_signal);
}
+
+
+/**
+ * wpa_dbus_get_object_properties - Put object's properties into dictionary
+ * @iface: dbus priv struct
+ * @path: path to DBus object which properties will be obtained
+ * @interface: interface name which properties will be obtained
+ * @dict_iter: correct, open DBus dictionary iterator.
+ *
+ * Iterates over all properties registered with object and execute getters
+ * of those, which are readable and which interface matches interface
+ * specified as argument. Obtained properties values are stored in
+ * dict_iter dictionary.
+ */
+void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
+ const char *path, const char *interface,
+ DBusMessageIter *dict_iter)
+{
+ struct wpa_dbus_object_desc *obj_desc = NULL;
+
+ dbus_connection_get_object_path_data(iface->con, path,
+ (void **) &obj_desc);
+ if (!obj_desc) {
+ wpa_printf(MSG_ERROR, "dbus: wpa_dbus_get_object_properties: "
+ "could not obtain object's private data: %s", path);
+ return;
+ }
+
+ fill_dict_with_properties(dict_iter, obj_desc->properties,
+ interface, obj_desc->user_data);
+}
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
index b18ab9216..f9678332f 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ b/wpa_supplicant/dbus/dbus_new_helpers.h
@@ -23,7 +23,7 @@ typedef DBusMessage * (* WPADBusMethodHandler)(DBusMessage *message,
typedef void (* WPADBusArgumentFreeFunction)(void *handler_arg);
typedef DBusMessage * (* WPADBusPropertyAccessor)(DBusMessage *message,
- void *user_data);
+ const void *user_data);
struct wpa_dbus_object_desc {
DBusConnection *connection;
@@ -116,6 +116,9 @@ void wpa_dbus_signal_property_changed(struct wpas_dbus_priv *iface,
const char *interface_name,
const char *property_name);
+void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
+ const char *path, const char *interface,
+ DBusMessageIter *dict_iter);
#else /* CONFIG_CTRL_IFACE_DBUS_NEW */