dbus: Add second properties arg to *Added signals
authorWitold Sowa <witold.sowa@gmail.com>
Fri, 1 Jan 2010 10:47:59 +0000 (12:47 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 1 Jan 2010 10:47:59 +0000 (12:47 +0200)
Add a dictionary argument containing all properties of the newly added
object to BSSAdded, NetworkAdded, and InterfaceAdded signals.

doc/dbus.doxygen
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new_helpers.c
wpa_supplicant/dbus/dbus_new_helpers.h

index 04bdf5a..9f5f17e 100644 (file)
@@ -117,13 +117,17 @@ registered in the bus with fi.w1.wpa_supplicant1 name.
 
     <ul>
       <li>
-       <h3>InterfaceAdded ( o : interface )</h3>
+       <h3>InterfaceAdded ( o : interface, a{sv} : properties )</h3>
        <p>A new interface was added to %wpa_supplicant.</p>
        <h4>Arguments</h4>
        <dl>
          <dt>o : interface</dt>
          <dd>A D-Bus path to an object representing the added interface</dd>
        </dl>
+       <dl>
+         <dt>a{sv} : properties</dt>
+         <dd>A dictionary containing properties of added interface.</dd>
+       </dl>
       </li>
 
       <li>
@@ -402,13 +406,17 @@ fi.w1.wpa_supplicant1.CreateInterface.
       </li>
 
       <li>
-       <h3>BSSAdded ( o : BSS )</h3>
+       <h3>BSSAdded ( o : BSS, a{sv} : properties )</h3>
        <p>Interface became aware of a new BSS.</p>
        <h4>Arguments</h4>
        <dl>
          <dt>o : BSS</dt>
          <dd>A D-Bus path to an object representing the new BSS.</dd>
        </dl>
+       <dl>
+         <dt>a{sv} : properties</dt>
+         <dd>A dictionary containing properties of added BSS.</dd>
+       </dl>
       </li>
 
       <li>
@@ -442,13 +450,17 @@ fi.w1.wpa_supplicant1.CreateInterface.
       </li>
 
       <li>
-       <h3>NetworkAdded ( o : network )</h3>
+       <h3>NetworkAdded ( o : network, a{sv} : properties )</h3>
        <p>A new network has been added to the interface.</p>
        <h4>Arguments</h4>
        <dl>
          <dt>o : network</dt>
          <dd>A D-Bus path to an object representing the added network.</dd>
        </dl>
+       <dl>
+         <dt>a{sv} : properties</dt>
+         <dd>A dictionary containing properties of added network.</dd>
+       </dl>
       </li>
 
       <li>
index f8d5767..568bb62 100644 (file)
@@ -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
          }
        },
index e4829f2..e71aba7 100644 (file)
@@ -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);
+}
index b18ab92..f967833 100644 (file)
@@ -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 */