123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- #include "utils/includes.h"
- #include <libxml/tree.h>
- #include "utils/common.h"
- #include "dbus_common_i.h"
- #include "dbus_new_helpers.h"
- struct interfaces {
- struct interfaces *next;
- char *dbus_interface;
- xmlNodePtr interface_node;
- };
- static struct interfaces * extract_interfaces(
- struct wpa_dbus_object_desc *obj_dsc, xmlNodePtr root_node)
- {
- struct wpa_dbus_method_desc *method_dsc;
- struct wpa_dbus_signal_desc *signal_dsc;
- struct wpa_dbus_property_desc *property_dsc;
- struct interfaces *head = NULL;
- struct interfaces *iface, *last;
-
- for (method_dsc = obj_dsc->methods; method_dsc;
- method_dsc = method_dsc->next) {
- iface = head;
- last = NULL;
-
- while (iface) {
- if (!os_strcmp(iface->dbus_interface,
- method_dsc->dbus_interface))
- break;
- last = iface;
- iface = iface->next;
- }
- if (iface)
- continue;
- iface = os_zalloc(sizeof(struct interfaces));
- if (!iface)
- continue;
- if (last)
- last->next = iface;
- else
- head = iface;
- iface->dbus_interface = os_strdup(method_dsc->dbus_interface);
- if (!iface->dbus_interface)
- continue;
- iface->interface_node = xmlNewChild(root_node, NULL,
- BAD_CAST "interface",
- NULL);
- xmlNewProp(iface->interface_node, BAD_CAST "name",
- BAD_CAST method_dsc->dbus_interface);
- }
-
- for (signal_dsc = obj_dsc->signals; signal_dsc;
- signal_dsc = signal_dsc->next) {
- iface = head;
- last = NULL;
-
- while (iface) {
- if (!os_strcmp(iface->dbus_interface,
- signal_dsc->dbus_interface))
- break;
- last = iface;
- iface = iface->next;
- }
- if (iface)
- continue;
- iface = os_zalloc(sizeof(struct interfaces));
- if (!iface)
- continue;
- if (last)
- last->next = iface;
- else
- head = iface;
- iface->dbus_interface = os_strdup(signal_dsc->dbus_interface);
- if (!iface->dbus_interface)
- continue;
- iface->interface_node = xmlNewChild(root_node, NULL,
- BAD_CAST "interface",
- NULL);
- xmlNewProp(iface->interface_node, BAD_CAST "name",
- BAD_CAST signal_dsc->dbus_interface);
- }
-
- for (property_dsc = obj_dsc->properties; property_dsc;
- property_dsc = property_dsc->next) {
- iface = head;
- last = NULL;
-
- while (iface) {
- if (!os_strcmp(iface->dbus_interface,
- property_dsc->dbus_interface))
- break;
- last = iface;
- iface = iface->next;
- }
- if (iface)
- continue;
- iface = os_zalloc(sizeof(struct interfaces));
- if (!iface)
- continue;
- if (last)
- last->next = iface;
- else
- head = iface;
- iface->dbus_interface =
- os_strdup(property_dsc->dbus_interface);
- if (!iface->dbus_interface)
- continue;
- iface->interface_node = xmlNewChild(root_node, NULL,
- BAD_CAST "interface",
- NULL);
- xmlNewProp(iface->interface_node, BAD_CAST "name",
- BAD_CAST property_dsc->dbus_interface);
- }
- return head;
- }
- DBusMessage * wpa_dbus_introspect(DBusMessage *message,
- struct wpa_dbus_object_desc *obj_dsc)
- {
- DBusMessage *reply;
- struct interfaces *ifaces, *tmp;
- struct wpa_dbus_signal_desc *signal_dsc;
- struct wpa_dbus_method_desc *method_dsc;
- struct wpa_dbus_property_desc *property_dsc;
- xmlChar *intro_str;
- char **children;
- int i, s;
- xmlDocPtr doc = NULL;
- xmlNodePtr root_node = NULL, node = NULL, iface_node = NULL;
- xmlNodePtr method_node = NULL, signal_node = NULL;
- xmlNodePtr property_node = NULL, arg_node = NULL;
-
- doc = xmlNewDoc(BAD_CAST "1.0");
- root_node = xmlNewNode(NULL, BAD_CAST "node");
- xmlDocSetRootElement(doc, root_node);
- xmlCreateIntSubset(doc, BAD_CAST "node",
- BAD_CAST DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER,
- BAD_CAST DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER);
-
- iface_node = xmlNewChild(root_node, NULL, BAD_CAST "interface", NULL);
- xmlNewProp(iface_node, BAD_CAST "name",
- BAD_CAST WPA_DBUS_INTROSPECTION_INTERFACE);
-
- method_node = xmlNewChild(iface_node, NULL, BAD_CAST "method", NULL);
- xmlNewProp(method_node, BAD_CAST "name",
- BAD_CAST WPA_DBUS_INTROSPECTION_METHOD);
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "data");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "s");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "out");
-
- iface_node = xmlNewChild(root_node, NULL,
- BAD_CAST "interface", NULL);
- xmlNewProp(iface_node, BAD_CAST "name",
- BAD_CAST WPA_DBUS_PROPERTIES_INTERFACE);
-
- method_node = xmlNewChild(iface_node, NULL, BAD_CAST "method", NULL);
- xmlNewProp(method_node, BAD_CAST "name",
- BAD_CAST WPA_DBUS_PROPERTIES_GET);
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "interface");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "s");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "in");
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "propname");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "s");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "in");
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "value");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "v");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "out");
- method_node = xmlNewChild(iface_node, NULL, BAD_CAST "method", NULL);
-
- xmlNewProp(method_node, BAD_CAST "name",
- BAD_CAST WPA_DBUS_PROPERTIES_GETALL);
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "interface");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "s");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "in");
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "props");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "a{sv}");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "out");
- method_node = xmlNewChild(iface_node, NULL, BAD_CAST "method", NULL);
-
- xmlNewProp(method_node, BAD_CAST "name",
- BAD_CAST WPA_DBUS_PROPERTIES_SET);
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "interface");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "s");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "in");
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "propname");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "s");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "in");
- arg_node = xmlNewChild(method_node, NULL, BAD_CAST "arg", NULL);
- xmlNewProp(arg_node, BAD_CAST "name", BAD_CAST "value");
- xmlNewProp(arg_node, BAD_CAST "type", BAD_CAST "v");
- xmlNewProp(arg_node, BAD_CAST "direction", BAD_CAST "in");
-
- ifaces = extract_interfaces(obj_dsc, root_node);
-
- for (method_dsc = obj_dsc->methods; method_dsc;
- method_dsc = method_dsc->next) {
- struct interfaces *iface = ifaces;
- while (iface) {
- if (!os_strcmp(iface->dbus_interface,
- method_dsc->dbus_interface))
- break;
- iface = iface->next;
- }
- if (!iface)
- continue;
- iface_node = iface->interface_node;
- method_node = xmlNewChild(iface_node, NULL, BAD_CAST "method",
- NULL);
- xmlNewProp(method_node, BAD_CAST "name",
- BAD_CAST method_dsc->dbus_method);
-
- for (i = 0; i < method_dsc->args_num; i++) {
- struct wpa_dbus_argument arg = method_dsc->args[i];
- arg_node = xmlNewChild(method_node, NULL,
- BAD_CAST "arg", NULL);
- if (arg.name && strlen(arg.name)) {
- xmlNewProp(arg_node, BAD_CAST "name",
- BAD_CAST arg.name);
- }
- xmlNewProp(arg_node, BAD_CAST "type",
- BAD_CAST arg.type);
- xmlNewProp(arg_node, BAD_CAST "direction",
- BAD_CAST (arg.dir == ARG_IN ?
- "in" : "out"));
- }
- }
-
- for (signal_dsc = obj_dsc->signals; signal_dsc;
- signal_dsc = signal_dsc->next) {
- struct interfaces *iface = ifaces;
- while (iface) {
- if (!os_strcmp(iface->dbus_interface,
- signal_dsc->dbus_interface))
- break;
- iface = iface->next;
- }
- if (!iface)
- continue;
- iface_node = iface->interface_node;
- signal_node = xmlNewChild(iface_node, NULL, BAD_CAST "signal",
- NULL);
- xmlNewProp(signal_node, BAD_CAST "name",
- BAD_CAST signal_dsc->dbus_signal);
-
- for (i = 0; i < signal_dsc->args_num; i++) {
- struct wpa_dbus_argument arg = signal_dsc->args[i];
- arg_node = xmlNewChild(signal_node, NULL,
- BAD_CAST "arg", NULL);
- if (arg.name && strlen(arg.name)) {
- xmlNewProp(arg_node, BAD_CAST "name",
- BAD_CAST arg.name);
- }
- xmlNewProp(arg_node, BAD_CAST "type",
- BAD_CAST arg.type);
- }
- }
-
- for (property_dsc = obj_dsc->properties; property_dsc;
- property_dsc = property_dsc->next) {
- struct interfaces *iface = ifaces;
- while (iface) {
- if (!os_strcmp(iface->dbus_interface,
- property_dsc->dbus_interface))
- break;
- iface = iface->next;
- }
- if (!iface)
- continue;
- iface_node = iface->interface_node;
- property_node = xmlNewChild(iface_node, NULL,
- BAD_CAST "property", NULL);
- xmlNewProp(property_node, BAD_CAST "name",
- BAD_CAST property_dsc->dbus_property);
- xmlNewProp(property_node, BAD_CAST "type",
- BAD_CAST property_dsc->type);
- xmlNewProp(property_node, BAD_CAST "access", BAD_CAST
- (property_dsc->access == R ? "read" :
- (property_dsc->access == W ?
- "write" : "readwrite")));
- }
-
- dbus_connection_list_registered(obj_dsc->connection,
- dbus_message_get_path(message),
- &children);
- for (i = 0; children[i]; i++) {
- node = xmlNewChild(root_node, NULL, BAD_CAST "node", NULL);
- xmlNewProp(node, BAD_CAST "name", BAD_CAST children[i]);
- }
- dbus_free_string_array(children);
- xmlDocDumpFormatMemory(doc, &intro_str, &s, 1);
- xmlFreeDoc(doc);
- while (ifaces) {
- tmp = ifaces;
- ifaces = ifaces->next;
- os_free(tmp->dbus_interface);
- os_free(tmp);
- }
- reply = dbus_message_new_method_return(message);
- if (reply == NULL) {
- xmlFree(intro_str);
- return NULL;
- }
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &intro_str,
- DBUS_TYPE_INVALID);
- xmlFree(intro_str);
- return reply;
- }
|