dbus_new_introspect.c
Go to the documentation of this file.
00001 /*
00002  * wpa_supplicant - D-Bus introspection
00003  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
00004  * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
00005  * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as
00009  * published by the Free Software Foundation.
00010  *
00011  * Alternatively, this software may be distributed under the terms of BSD
00012  * license.
00013  *
00014  * See README and COPYING for more details.
00015  */
00016 
00017 #include "utils/includes.h"
00018 
00019 #include "utils/common.h"
00020 #include "utils/list.h"
00021 #include "utils/wpabuf.h"
00022 #include "dbus_common_i.h"
00023 #include "dbus_new_helpers.h"
00024 
00025 
00026 struct interfaces {
00027         struct dl_list list;
00028         char *dbus_interface;
00029         struct wpabuf *xml;
00030 };
00031 
00032 
00033 static struct interfaces * add_interface(struct dl_list *list,
00034                                          const char *dbus_interface)
00035 {
00036         struct interfaces *iface;
00037 
00038         dl_list_for_each(iface, list, struct interfaces, list) {
00039                 if (os_strcmp(iface->dbus_interface, dbus_interface) == 0)
00040                         return iface; /* already in the list */
00041         }
00042 
00043         iface = os_zalloc(sizeof(struct interfaces));
00044         if (!iface)
00045                 return NULL;
00046         iface->xml = wpabuf_alloc(3000);
00047         if (iface->xml == NULL) {
00048                 os_free(iface);
00049                 return NULL;
00050         }
00051         wpabuf_printf(iface->xml, "<interface name=\"%s\">", dbus_interface);
00052         dl_list_add_tail(list, &iface->list);
00053         iface->dbus_interface = os_strdup(dbus_interface);
00054         return iface;
00055 }
00056 
00057 
00058 static void add_arg(struct wpabuf *xml, const char *name, const char *type,
00059                     const char *direction)
00060 {
00061         wpabuf_printf(xml, "<arg name=\"%s\"", name);
00062         if (type)
00063                 wpabuf_printf(xml, " type=\"%s\"", type);
00064         if (direction)
00065                 wpabuf_printf(xml, " direction=\"%s\"", direction);
00066         wpabuf_put_str(xml, "/>");
00067 }
00068 
00069 
00070 static void add_entry(struct wpabuf *xml, const char *type, const char *name,
00071                       const struct wpa_dbus_argument *args, int include_dir)
00072 {
00073         const struct wpa_dbus_argument *arg;
00074 
00075         if (args == NULL || args->name == NULL) {
00076                 wpabuf_printf(xml, "<%s name=\"%s\"/>", type, name);
00077                 return;
00078         }
00079         wpabuf_printf(xml, "<%s name=\"%s\">", type, name);
00080         for (arg = args; arg && arg->name; arg++) {
00081                 add_arg(xml, arg->name, arg->type,
00082                         include_dir ? (arg->dir == ARG_IN ? "in" : "out") :
00083                         NULL);
00084         }
00085         wpabuf_printf(xml, "</%s>", type);
00086 }
00087 
00088 
00089 static void add_property(struct wpabuf *xml,
00090                          const struct wpa_dbus_property_desc *dsc)
00091 {
00092         wpabuf_printf(xml, "<property name=\"%s\" type=\"%s\" access=\"%s\"/>",
00093                       dsc->dbus_property, dsc->type,
00094                       (dsc->access == R ? "read" :
00095                        (dsc->access == W ? "write" : "readwrite")));
00096 }
00097 
00098 
00099 static void extract_interfaces_methods(
00100         struct dl_list *list, const struct wpa_dbus_method_desc *methods)
00101 {
00102         const struct wpa_dbus_method_desc *dsc;
00103         struct interfaces *iface;
00104         for (dsc = methods; dsc && dsc->dbus_method; dsc++) {
00105                 iface = add_interface(list, dsc->dbus_interface);
00106                 if (iface)
00107                         add_entry(iface->xml, "method", dsc->dbus_method,
00108                                   dsc->args, 1);
00109         }
00110 }
00111 
00112 
00113 static void extract_interfaces_signals(
00114         struct dl_list *list, const struct wpa_dbus_signal_desc *signals)
00115 {
00116         const struct wpa_dbus_signal_desc *dsc;
00117         struct interfaces *iface;
00118         for (dsc = signals; dsc && dsc->dbus_signal; dsc++) {
00119                 iface = add_interface(list, dsc->dbus_interface);
00120                 if (iface)
00121                         add_entry(iface->xml, "signal", dsc->dbus_signal,
00122                                   dsc->args, 0);
00123         }
00124 }
00125 
00126 
00127 static void extract_interfaces_properties(
00128         struct dl_list *list, const struct wpa_dbus_property_desc *properties)
00129 {
00130         const struct wpa_dbus_property_desc *dsc;
00131         struct interfaces *iface;
00132         for (dsc = properties; dsc && dsc->dbus_property; dsc++) {
00133                 iface = add_interface(list, dsc->dbus_interface);
00134                 if (iface)
00135                         add_property(iface->xml, dsc);
00136         }
00137 }
00138 
00139 
00150 static void extract_interfaces(struct dl_list *list,
00151                                struct wpa_dbus_object_desc *obj_dsc)
00152 {
00153         extract_interfaces_methods(list, obj_dsc->methods);
00154         extract_interfaces_signals(list, obj_dsc->signals);
00155         extract_interfaces_properties(list, obj_dsc->properties);
00156 }
00157 
00158 
00159 static void add_interfaces(struct dl_list *list, struct wpabuf *xml)
00160 {
00161         struct interfaces *iface, *n;
00162         dl_list_for_each_safe(iface, n, list, struct interfaces, list) {
00163                 if (wpabuf_len(iface->xml) + 20 < wpabuf_tailroom(xml)) {
00164                         wpabuf_put_buf(xml, iface->xml);
00165                         wpabuf_put_str(xml, "</interface>");
00166                 }
00167                 dl_list_del(&iface->list);
00168                 wpabuf_free(iface->xml);
00169                 os_free(iface->dbus_interface);
00170                 os_free(iface);
00171         }
00172 }
00173 
00174 
00175 static void add_child_nodes(struct wpabuf *xml, DBusConnection *con,
00176                             const char *path)
00177 {
00178         char **children;
00179         int i;
00180 
00181         /* add child nodes to introspection tree */
00182         dbus_connection_list_registered(con, path, &children);
00183         for (i = 0; children[i]; i++)
00184                 wpabuf_printf(xml, "<node name=\"%s\"/>", children[i]);
00185         dbus_free_string_array(children);
00186 }
00187 
00188 
00189 static void add_introspectable_interface(struct wpabuf *xml)
00190 {
00191         wpabuf_printf(xml, "<interface name=\"%s\">"
00192                       "<method name=\"%s\">"
00193                       "<arg name=\"data\" type=\"s\" direction=\"out\"/>"
00194                       "</method>"
00195                       "</interface>",
00196                       WPA_DBUS_INTROSPECTION_INTERFACE,
00197                       WPA_DBUS_INTROSPECTION_METHOD);
00198 }
00199 
00200 
00201 static void add_properties_interface(struct wpabuf *xml)
00202 {
00203         wpabuf_printf(xml, "<interface name=\"%s\">",
00204                       WPA_DBUS_PROPERTIES_INTERFACE);
00205 
00206         wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_GET);
00207         add_arg(xml, "interface", "s", "in");
00208         add_arg(xml, "propname", "s", "in");
00209         add_arg(xml, "value", "v", "out");
00210         wpabuf_put_str(xml, "</method>");
00211 
00212         wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_GETALL);
00213         add_arg(xml, "interface", "s", "in");
00214         add_arg(xml, "props", "a{sv}", "out");
00215         wpabuf_put_str(xml, "</method>");
00216 
00217         wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_SET);
00218         add_arg(xml, "interface", "s", "in");
00219         add_arg(xml, "propname", "s", "in");
00220         add_arg(xml, "value", "v", "in");
00221         wpabuf_put_str(xml, "</method>");
00222 
00223         wpabuf_put_str(xml, "</interface>");
00224 }
00225 
00226 
00227 static void add_wpas_interfaces(struct wpabuf *xml,
00228                                 struct wpa_dbus_object_desc *obj_dsc)
00229 {
00230         struct dl_list ifaces;
00231         dl_list_init(&ifaces);
00232         extract_interfaces(&ifaces, obj_dsc);
00233         add_interfaces(&ifaces, xml);
00234 }
00235 
00236 
00246 DBusMessage * wpa_dbus_introspect(DBusMessage *message,
00247                                   struct wpa_dbus_object_desc *obj_dsc)
00248 {
00249 
00250         DBusMessage *reply;
00251         struct wpabuf *xml;
00252 
00253         xml = wpabuf_alloc(4000);
00254         if (xml == NULL)
00255                 return NULL;
00256 
00257         wpabuf_put_str(xml, "<?xml version=\"1.0\"?>\n");
00258         wpabuf_put_str(xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
00259         wpabuf_put_str(xml, "<node>");
00260 
00261         add_introspectable_interface(xml);
00262         add_properties_interface(xml);
00263         add_wpas_interfaces(xml, obj_dsc);
00264         add_child_nodes(xml, obj_dsc->connection,
00265                         dbus_message_get_path(message));
00266 
00267         wpabuf_put_str(xml, "</node>\n");
00268 
00269         reply = dbus_message_new_method_return(message);
00270         if (reply) {
00271                 const char *intro_str = wpabuf_head(xml);
00272                 dbus_message_append_args(reply, DBUS_TYPE_STRING, &intro_str,
00273                                          DBUS_TYPE_INVALID);
00274         }
00275         wpabuf_free(xml);
00276 
00277         return reply;
00278 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34