18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / dbus-based control interface
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify
68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation.
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license.
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details.
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <dbus/dbus.h>
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../config.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../wpa_supplicant_i.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../bss.h"
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_old.h"
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_old_handlers.h"
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_common.h"
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_common_i.h"
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_decompose_object_path - Decompose an interface object path into parts
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @path: The dbus object path
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @network: (out) the configured network this object path refers to, if any
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bssid: (out) the scanned bssid this object path refers to, if any
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: The object path of the network interface this path refers to
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For a given object path, decomposes the object path into object id, network,
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and BSSID parts, if those parts exist.
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * wpas_dbus_decompose_object_path(const char *path, char **network,
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       char **bssid)
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const unsigned int dev_path_prefix_len =
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		strlen(WPAS_DBUS_PATH_INTERFACES "/");
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *obj_path_only;
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *next_sep;
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Be a bit paranoid about path */
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!path || strncmp(path, WPAS_DBUS_PATH_INTERFACES "/",
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     dev_path_prefix_len))
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Ensure there's something at the end of the path */
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((path + dev_path_prefix_len)[0] == '\0')
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	obj_path_only = os_strdup(path);
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (obj_path_only == NULL)
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	next_sep = strchr(obj_path_only + dev_path_prefix_len, '/');
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next_sep != NULL) {
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const char *net_part = strstr(next_sep,
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WPAS_DBUS_NETWORKS_PART "/");
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const char *bssid_part = strstr(next_sep,
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						WPAS_DBUS_BSSIDS_PART "/");
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (network && net_part) {
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Deal with a request for a configured network */
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *net_name = net_part +
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				strlen(WPAS_DBUS_NETWORKS_PART "/");
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*network = NULL;
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (strlen(net_name))
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*network = os_strdup(net_name);
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (bssid && bssid_part) {
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Deal with a request for a scanned BSSID */
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *bssid_name = bssid_part +
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				strlen(WPAS_DBUS_BSSIDS_PART "/");
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (strlen(bssid_name))
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*bssid = os_strdup(bssid_name);
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*bssid = NULL;
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Cut off interface object path before "/" */
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*next_sep = '\0';
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return obj_path_only;
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message this error refers to
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus error message
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Convenience function to create and return an invalid interface error
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message)
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return dbus_message_new_error(message, WPAS_ERROR_INVALID_IFACE,
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "wpa_supplicant knows nothing about "
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "this interface.");
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_new_invalid_network_error - Return a new invalid network error message
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message this error refers to
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus error message
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Convenience function to create and return an invalid network error
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message)
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return dbus_message_new_error(message, WPAS_ERROR_INVALID_NETWORK,
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "The requested network does not exist.");
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message this error refers to
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus error message
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Convenience function to create and return an invalid bssid error
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic DBusMessage * wpas_dbus_new_invalid_bssid_error(DBusMessage *message)
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return dbus_message_new_error(message, WPAS_ERROR_INVALID_BSSID,
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "The BSSID requested was invalid.");
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dispatch_network_method - dispatch messages for configured networks
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: the incoming dbus message
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: a network interface's data
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @network_id: id of the configured network we're interested in
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a reply dbus message, or a dbus error message
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function dispatches all incoming dbus messages for configured networks.
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic DBusMessage * wpas_dispatch_network_method(DBusMessage *message,
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  struct wpa_supplicant *wpa_s,
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  int network_id)
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *method = dbus_message_get_member(message);
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, network_id);
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL)
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_network_error(message);
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!strcmp(method, "set"))
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_iface_set_network(message, wpa_s, ssid);
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (!strcmp(method, "enable"))
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid);
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (!strcmp(method, "disable"))
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid);
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dispatch_bssid_method - dispatch messages for scanned networks
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: the incoming dbus message
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: a network interface's data
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bssid: bssid of the scanned network we're interested in
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a reply dbus message, or a dbus error message
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function dispatches all incoming dbus messages for scanned networks.
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message,
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						struct wpa_supplicant *wpa_s,
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						const char *bssid_txt)
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss;
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0)
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_bssid_error(message);
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss = wpa_bss_get_bssid(wpa_s, bssid);
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss == NULL)
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_bssid_error(message);
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Dispatch the method call against the scanned bssid */
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(dbus_message_get_member(message), "properties") == 0)
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_bssid_properties(message, wpa_s, bss);
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_iface_message_handler - Dispatch messages for interfaces or networks
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @connection: Connection to the system message bus
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: An incoming dbus message
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @user_data: A pointer to a dbus control interface data structure
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Whether or not the message was handled
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function dispatches all incoming dbus messages for network interfaces,
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * or objects owned by them, such as scanned BSSIDs and configured networks.
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    DBusMessage *message,
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    void *user_data)
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *method = dbus_message_get_member(message);
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *path = dbus_message_get_path(message);
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *msg_interface = dbus_message_get_interface(message);
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *iface_obj_path = NULL;
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *network = NULL;
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *bssid = NULL;
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Caller must specify a message interface */
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg_interface)
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface_obj_path = wpas_dbus_decompose_object_path(path, &network,
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                                                 &bssid);
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface_obj_path == NULL) {
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_iface_error(message);
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Make sure the message's object path actually refers to the
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * wpa_supplicant structure it's supposed to (which is wpa_s)
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global,
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                                          iface_obj_path) != wpa_s) {
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_iface_error(message);
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) {
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* A method for one of this interface's configured networks */
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int nid = strtoul(network, NULL, 10);
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (errno != EINVAL)
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dispatch_network_method(message, wpa_s,
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							     nid);
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_network_error(message);
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) {
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* A method for one of this interface's scanned BSSIDs */
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dispatch_bssid_method(message, wpa_s, bssid);
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) {
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* A method for an interface only. */
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strcmp(method, "scan"))
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_scan(message, wpa_s);
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "scanResults"))
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_scan_results(message, wpa_s);
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "addNetwork"))
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_add_network(message, wpa_s);
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "removeNetwork"))
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_remove_network(message, wpa_s);
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "selectNetwork"))
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_select_network(message, wpa_s);
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "capabilities"))
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_capabilities(message, wpa_s);
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "disconnect"))
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_disconnect(message, wpa_s);
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "setAPScan"))
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "setSmartcardModules"))
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_set_smartcard_modules(message,
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt								      wpa_s);
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "state"))
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_get_state(message, wpa_s);
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "scanning"))
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_get_scanning(message, wpa_s);
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "setBlobs"))
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_set_blobs(message, wpa_s);
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!strcmp(method, "removeBlobs"))
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!os_strcmp(method, "wpsPbc"))
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!os_strcmp(method, "wpsPin"))
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_wps_pin(message, wpa_s);
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!os_strcmp(method, "wpsReg"))
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_wps_reg(message, wpa_s);
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (!os_strcmp(method, "flush"))
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_iface_flush(message, wpa_s);
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* If the message was handled, send back the reply */
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply) {
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!dbus_message_get_no_reply(message))
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dbus_connection_send(connection, reply, NULL);
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_unref(reply);
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(iface_obj_path);
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(network);
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(bssid);
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply ? DBUS_HANDLER_RESULT_HANDLED :
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_message_handler - dispatch incoming dbus messages
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @connection: connection to the system message bus
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: an incoming dbus message
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @user_data: a pointer to a dbus control interface data structure
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: whether or not the message was handled
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function dispatches all incoming dbus messages to the correct
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handlers, depending on what the message's target object path is,
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and what the method call is.
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic DBusHandlerResult wpas_message_handler(DBusConnection *connection,
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *message, void *user_data)
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpas_dbus_priv *ctrl_iface = user_data;
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *method;
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *path;
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *msg_interface;
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	method = dbus_message_get_member(message);
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	path = dbus_message_get_path(message);
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	msg_interface = dbus_message_get_interface(message);
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!method || !path || !ctrl_iface || !msg_interface)
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Validate the method interface */
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0)
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!strcmp(path, WPAS_DBUS_PATH)) {
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* dispatch methods against our global dbus interface here */
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strcmp(method, "addInterface")) {
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_global_add_interface(
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, ctrl_iface->global);
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (!strcmp(method, "removeInterface")) {
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_global_remove_interface(
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, ctrl_iface->global);
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (!strcmp(method, "getInterface")) {
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_global_get_interface(
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, ctrl_iface->global);
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (!strcmp(method, "setDebugParams")) {
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_global_set_debugparams(
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, ctrl_iface->global);
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* If the message was handled, send back the reply */
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply) {
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!dbus_message_get_no_reply(message))
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dbus_connection_send(connection, reply, NULL);
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_unref(reply);
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply ? DBUS_HANDLER_RESULT_HANDLED :
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: %wpa_supplicant network interface data
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify listeners that this interface has updated scan results.
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *_signal;
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Do nothing if the control interface is not turned on */
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface == NULL)
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_signal = dbus_message_new_signal(wpa_s->dbus_path,
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  WPAS_DBUS_IFACE_INTERFACE,
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  "ScanResultsAvailable");
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (_signal == NULL) {
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Not enough memory to send scan "
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "results signal");
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_connection_send(iface->con, _signal, NULL);
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_unref(_signal);
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_dbus_notify_state_change - Send a state change signal
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: %wpa_supplicant network interface data
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @new_state: new state wpa_supplicant is entering
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @old_state: old state wpa_supplicant is leaving
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify listeners that wpa_supplicant has changed state
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     enum wpa_states new_state,
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     enum wpa_states old_state)
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpas_dbus_priv *iface;
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *_signal = NULL;
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *new_state_str, *old_state_str;
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->dbus_path == NULL)
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* Skip signal since D-Bus setup is not yet ready */
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Do nothing if the control interface is not turned on */
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global == NULL)
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface = wpa_s->global->dbus;
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface == NULL)
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Only send signal if state really changed */
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_state == old_state)
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_signal = dbus_message_new_signal(wpa_s->dbus_path,
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  WPAS_DBUS_IFACE_INTERFACE,
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  "StateChange");
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (_signal == NULL) {
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR,
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "dbus: wpa_supplicant_dbus_notify_state_change: "
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "could not create dbus signal; likely out of "
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "memory");
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	new_state_str = wpa_supplicant_state_txt(new_state);
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_state_str = wpa_supplicant_state_txt(old_state);
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_state_str == NULL || old_state_str == NULL) {
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR,
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "dbus: wpa_supplicant_dbus_notify_state_change: "
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "Could not convert state strings");
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_append_args(_signal,
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                              DBUS_TYPE_STRING, &new_state_str,
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                              DBUS_TYPE_STRING, &old_state_str,
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                              DBUS_TYPE_INVALID)) {
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR,
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "dbus: wpa_supplicant_dbus_notify_state_change: "
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "Not enough memory to construct state change "
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "signal");
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_connection_send(iface->con, _signal, NULL);
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_unref(_signal);
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_dbus_notify_scanning - send scanning status
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: %wpa_supplicant network interface data
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify listeners of interface scanning state changes
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *_signal;
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Do nothing if the control interface is not turned on */
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface == NULL)
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_signal = dbus_message_new_signal(wpa_s->dbus_path,
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  WPAS_DBUS_IFACE_INTERFACE,
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  "Scanning");
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (_signal == NULL) {
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Not enough memory to send scan "
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "results signal");
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dbus_message_append_args(_signal,
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                             DBUS_TYPE_BOOLEAN, &scanning,
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                             DBUS_TYPE_INVALID)) {
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_connection_send(iface->con, _signal, NULL);
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Not enough memory to construct "
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "signal");
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_unref(_signal);
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 const struct wps_credential *cred)
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpas_dbus_priv *iface;
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *_signal = NULL;
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Do nothing if the control interface is not turned on */
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global == NULL)
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface = wpa_s->global->dbus;
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface == NULL)
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_signal = dbus_message_new_signal(wpa_s->dbus_path,
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  WPAS_DBUS_IFACE_INTERFACE,
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  "WpsCred");
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (_signal == NULL) {
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR,
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "dbus: wpa_supplicant_dbus_notify_wps_cred: "
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "Could not create dbus signal; likely out of "
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "memory");
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_append_args(_signal,
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                              DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      &cred->cred_attr, cred->cred_attr_len,
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                              DBUS_TYPE_INVALID)) {
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR,
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "dbus: wpa_supplicant_dbus_notify_wps_cred: "
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		           "Not enough memory to construct signal");
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_connection_send(iface->con, _signal, NULL);
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_unref(_signal);
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_WPS */
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 const struct wps_credential *cred)
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
552c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtvoid wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
553c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					      int depth, const char *subject,
554c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					      const char *cert_hash,
555c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					      const struct wpabuf *cert)
556c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt{
557c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	struct wpas_dbus_priv *iface;
558c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	DBusMessage *_signal = NULL;
559c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	const char *hash;
560c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	const char *cert_hex;
561c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	int cert_hex_len;
562c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
563c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	/* Do nothing if the control interface is not turned on */
564c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	if (wpa_s->global == NULL)
565c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		return;
566c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	iface = wpa_s->global->dbus;
567c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	if (iface == NULL)
568c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		return;
569c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
570c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	_signal = dbus_message_new_signal(wpa_s->dbus_path,
571c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					  WPAS_DBUS_IFACE_INTERFACE,
572c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					  "Certification");
573c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	if (_signal == NULL) {
574c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		wpa_printf(MSG_ERROR,
575c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		           "dbus: wpa_supplicant_dbus_notify_certification: "
576c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		           "Could not create dbus signal; likely out of "
577c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		           "memory");
578c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		return;
579c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	}
580c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
581c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	hash = cert_hash ? cert_hash : "";
582c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	cert_hex = cert ? wpabuf_head(cert) : "";
583c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	cert_hex_len = cert ? wpabuf_len(cert) : 0;
584c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
585c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	if (!dbus_message_append_args(_signal,
586c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				      DBUS_TYPE_INT32,&depth,
587c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				      DBUS_TYPE_STRING, &subject,
588c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	                              DBUS_TYPE_STRING, &hash,
589c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	                              DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
590c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				      &cert_hex, cert_hex_len,
591c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	                              DBUS_TYPE_INVALID)) {
592c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		wpa_printf(MSG_ERROR,
593c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		           "dbus: wpa_supplicant_dbus_notify_certification: "
594c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		           "Not enough memory to construct signal");
595c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		goto out;
596c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	}
597c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
598c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	dbus_connection_send(iface->con, _signal, NULL);
599c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
600c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtout:
601c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	dbus_message_unref(_signal);
602c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
603c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt}
604c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Initialize the dbus control interface and start receiving commands from
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * external programs over the bus.
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface)
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusError error;
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret = -1;
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusObjectPathVTable wpas_vtable = {
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		NULL, &wpas_message_handler, NULL, NULL, NULL, NULL
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	};
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Register the message handler for the global dbus interface */
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_connection_register_object_path(iface->con,
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  WPAS_DBUS_PATH, &wpas_vtable,
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  iface)) {
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Could not set up message "
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "handler");
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Register our service with the message bus */
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_error_init(&error);
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (dbus_bus_request_name(iface->con, WPAS_DBUS_SERVICE,
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      0, &error)) {
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = 0;
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case DBUS_REQUEST_NAME_REPLY_EXISTS:
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Could not request service name: "
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "already registered");
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Could not request service name: "
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%s %s", error.name, error.message);
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_error_free(&error);
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != 0)
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "'.");
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_register_new_iface - Register a new interface with dbus
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: %wpa_supplicant interface description structure to register
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on error
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Registers a new interface with dbus and assigns it a dbus object path.
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusConnection * con;
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 next;
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusObjectPathVTable vtable = {
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	};
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Do nothing if the control interface is not turned on */
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ctrl_iface == NULL)
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	con = ctrl_iface->con;
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	next = ctrl_iface->next_objid++;
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Create and set the interface's object path */
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->dbus_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->dbus_path == NULL)
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_snprintf(wpa_s->dbus_path, WPAS_DBUS_OBJECT_PATH_MAX,
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    WPAS_DBUS_PATH_INTERFACES "/%u",
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    next);
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Register the message handler for the interface functions */
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_connection_register_fallback(con, wpa_s->dbus_path, &vtable,
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       wpa_s)) {
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Could not set up message "
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "handler for interface %s", wpa_s->ifname);
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_unregister_iface - Unregister an interface from dbus
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant interface structure
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Unregisters the interface with dbus
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpas_dbus_priv *ctrl_iface;
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusConnection *con;
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Do nothing if the control interface is not turned on */
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL || wpa_s->global == NULL)
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctrl_iface = wpa_s->global->dbus;
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ctrl_iface == NULL)
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	con = ctrl_iface->con;
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path))
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->dbus_path);
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->dbus_path = NULL;
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @path: Pointer to a dbus object path representing an interface
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the interface or %NULL if not found
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global, const char *path)
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (strcmp(wpa_s->dbus_path, path) == 0)
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return wpa_s;
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
751