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