/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2015  Google Inc.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 */

#include <stdint.h>
#include <stdbool.h>
#include <errno.h>

#include <dbus/dbus.h>
#include <gdbus/gdbus.h>

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
#include "lib/sdp.h"

#include "adapter.h"
#include "dbus-common.h"
#include "error.h"
#include "log.h"
#include "eir.h"
#include "src/shared/ad.h"
#include "src/shared/mgmt.h"
#include "src/shared/queue.h"
#include "src/shared/util.h"
#include "advertising.h"

#define LE_ADVERTISING_MGR_IFACE "org.bluez.LEAdvertisingManager1"
#define LE_ADVERTISEMENT_IFACE "org.bluez.LEAdvertisement1"

struct btd_adv_manager {
	struct btd_adapter *adapter;
	struct queue *clients;
	struct mgmt *mgmt;
	uint16_t mgmt_index;
	uint8_t max_adv_len;
	uint8_t max_scan_rsp_len;
	uint8_t max_ads;
	uint32_t supported_flags;
	unsigned int instance_bitmap;
};

#define AD_TYPE_BROADCAST 0
#define AD_TYPE_PERIPHERAL 1

struct btd_adv_client {
	struct btd_adv_manager *manager;
	char *owner;
	char *path;
	char *name;
	uint16_t appearance;
	uint16_t duration;
	uint16_t timeout;
	unsigned int to_id;
	GDBusClient *client;
	GDBusProxy *proxy;
	DBusMessage *reg;
	uint8_t type; /* Advertising type */
	uint32_t flags;
	struct bt_ad *data;
	struct bt_ad *scan;
	uint8_t instance;
};

struct dbus_obj_match {
	const char *owner;
	const char *path;
};

static bool match_client(const void *a, const void *b)
{
	const struct btd_adv_client *client = a;
	const struct dbus_obj_match *match = b;

	if (match->owner && g_strcmp0(client->owner, match->owner))
		return false;

	if (match->path && g_strcmp0(client->path, match->path))
		return false;

	return true;
}

static void client_free(void *data)
{
	struct btd_adv_client *client = data;

	if (client->to_id > 0)
		g_source_remove(client->to_id);

	if (client->client) {
		g_dbus_client_set_disconnect_watch(client->client, NULL, NULL);
		g_dbus_client_unref(client->client);
	}

	if (client->instance)
		util_clear_uid(&client->manager->instance_bitmap,
						client->instance);

	bt_ad_unref(client->data);
	bt_ad_unref(client->scan);

	g_dbus_proxy_unref(client->proxy);

	if (client->owner)
		g_free(client->owner);

	if (client->path)
		g_free(client->path);

	free(client->name);
	free(client);
}

static gboolean client_free_idle_cb(void *data)
{
	client_free(data);

	return FALSE;
}

static void client_release(void *data)
{
	struct btd_adv_client *client = data;

	DBG("Releasing advertisement %s, %s", client->owner, client->path);

	g_dbus_proxy_method_call(client->proxy, "Release", NULL, NULL, NULL,
									NULL);
}

static void client_destroy(void *data)
{
	client_release(data);
	client_free(data);
}

static void remove_advertising(struct btd_adv_manager *manager,
						uint8_t instance)
{
	struct mgmt_cp_remove_advertising cp;

	if (instance)
		DBG("instance %u", instance);
	else
		DBG("all instances");

	cp.instance = instance;

	mgmt_send(manager->mgmt, MGMT_OP_REMOVE_ADVERTISING,
			manager->mgmt_index, sizeof(cp), &cp, NULL, NULL, NULL);
}

static void client_remove(void *data)
{
	struct btd_adv_client *client = data;
	struct mgmt_cp_remove_advertising cp;

	g_dbus_client_set_disconnect_watch(client->client, NULL, NULL);

	cp.instance = client->instance;

	mgmt_send(client->manager->mgmt, MGMT_OP_REMOVE_ADVERTISING,
			client->manager->mgmt_index, sizeof(cp), &cp,
			NULL, NULL, NULL);

	queue_remove(client->manager->clients, client);

	g_idle_add(client_free_idle_cb, client);

	g_dbus_emit_property_changed(btd_get_dbus_connection(),
				adapter_get_path(client->manager->adapter),
				LE_ADVERTISING_MGR_IFACE, "SupportedInstances");

	g_dbus_emit_property_changed(btd_get_dbus_connection(),
				adapter_get_path(client->manager->adapter),
				LE_ADVERTISING_MGR_IFACE, "ActiveInstances");
}

static void client_disconnect_cb(DBusConnection *conn, void *user_data)
{
	DBG("Client disconnected");

	client_remove(user_data);
}

static bool parse_type(DBusMessageIter *iter, struct btd_adv_client *client)
{
	const char *msg_type;

	if (!iter)
		return true;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
		return false;

	dbus_message_iter_get_basic(iter, &msg_type);

	if (!g_strcmp0(msg_type, "broadcast")) {
		client->type = AD_TYPE_BROADCAST;
		return true;
	}

	if (!g_strcmp0(msg_type, "peripheral")) {
		client->type = AD_TYPE_PERIPHERAL;
		return true;
	}

	return false;
}

static bool parse_service_uuids(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	DBusMessageIter ariter;

	if (!iter) {
		bt_ad_clear_service_uuid(client->data);
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(iter, &ariter);

	bt_ad_clear_service_uuid(client->data);

	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
		const char *uuid_str;
		bt_uuid_t uuid;

		dbus_message_iter_get_basic(&ariter, &uuid_str);

		DBG("Adding ServiceUUID: %s", uuid_str);

		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
			goto fail;

		if (!bt_ad_add_service_uuid(client->data, &uuid))
			goto fail;

		dbus_message_iter_next(&ariter);
	}

	return true;

fail:
	bt_ad_clear_service_uuid(client->data);
	return false;
}

static bool parse_solicit_uuids(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	DBusMessageIter ariter;

	if (!iter) {
		bt_ad_clear_solicit_uuid(client->data);
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(iter, &ariter);

	bt_ad_clear_solicit_uuid(client->data);

	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
		const char *uuid_str;
		bt_uuid_t uuid;

		dbus_message_iter_get_basic(&ariter, &uuid_str);

		DBG("Adding SolicitUUID: %s", uuid_str);

		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
			goto fail;

		if (!bt_ad_add_solicit_uuid(client->data, &uuid))
			goto fail;

		dbus_message_iter_next(&ariter);
	}

	return true;

fail:
	bt_ad_clear_solicit_uuid(client->data);
	return false;
}

static bool parse_manufacturer_data(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	DBusMessageIter entries;

	if (!iter) {
		bt_ad_clear_manufacturer_data(client->data);
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(iter, &entries);

	bt_ad_clear_manufacturer_data(client->data);

	while (dbus_message_iter_get_arg_type(&entries)
						== DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter value, entry, array;
		uint16_t manuf_id;
		uint8_t *manuf_data;
		int len;

		dbus_message_iter_recurse(&entries, &entry);
		dbus_message_iter_get_basic(&entry, &manuf_id);

		dbus_message_iter_next(&entry);

		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
			goto fail;

		dbus_message_iter_recurse(&entry, &value);

		if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_ARRAY)
			goto fail;

		dbus_message_iter_recurse(&value, &array);

		if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_BYTE)
			goto fail;

		dbus_message_iter_get_fixed_array(&array, &manuf_data, &len);

		DBG("Adding ManufacturerData for %04x", manuf_id);

		if (!bt_ad_add_manufacturer_data(client->data, manuf_id,
							manuf_data, len))
			goto fail;

		dbus_message_iter_next(&entries);
	}

	return true;

fail:
	bt_ad_clear_manufacturer_data(client->data);
	return false;
}

static bool parse_service_data(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	DBusMessageIter entries;

	if (!iter) {
		bt_ad_clear_service_data(client->data);
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(iter, &entries);

	bt_ad_clear_service_data(client->data);

	while (dbus_message_iter_get_arg_type(&entries)
						== DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter value, entry, array;
		const char *uuid_str;
		bt_uuid_t uuid;
		uint8_t *service_data;
		int len;

		dbus_message_iter_recurse(&entries, &entry);
		dbus_message_iter_get_basic(&entry, &uuid_str);

		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
			goto fail;

		dbus_message_iter_next(&entry);

		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
			goto fail;

		dbus_message_iter_recurse(&entry, &value);

		if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_ARRAY)
			goto fail;

		dbus_message_iter_recurse(&value, &array);

		if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_BYTE)
			goto fail;

		dbus_message_iter_get_fixed_array(&array, &service_data, &len);

		DBG("Adding ServiceData for %s", uuid_str);

		if (!bt_ad_add_service_data(client->data, &uuid, service_data,
									len))
			goto fail;

		dbus_message_iter_next(&entries);
	}

	return true;

fail:
	bt_ad_clear_service_data(client->data);
	return false;
}

static struct adv_include {
	uint8_t flag;
	const char *name;
} includes[] = {
	{ MGMT_ADV_FLAG_TX_POWER, "tx-power" },
	{ MGMT_ADV_FLAG_APPEARANCE, "appearance" },
	{ MGMT_ADV_FLAG_LOCAL_NAME, "local-name" },
	{ },
};

static bool parse_includes(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	DBusMessageIter entries;

	if (!iter) {
		client->flags = 0;
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(iter, &entries);

	/* Reset flags before parsing */
	client->flags = 0;

	while (dbus_message_iter_get_arg_type(&entries) == DBUS_TYPE_STRING) {
		const char *str;
		struct adv_include *inc;

		dbus_message_iter_get_basic(&entries, &str);

		for (inc = includes; inc && inc->name; inc++) {
			if (strcmp(str, inc->name))
				continue;

			if (!(client->manager->supported_flags & inc->flag))
				continue;

			DBG("Including Feature: %s", str);

			client->flags |= inc->flag;
		}

		dbus_message_iter_next(&entries);
	}

	return true;
}

static bool parse_local_name(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	const char *name;

	if (!iter) {
		free(client->name);
		client->name = NULL;
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
		return false;

	if (client->flags & MGMT_ADV_FLAG_LOCAL_NAME) {
		error("Local name already included");
		return false;
	}

	dbus_message_iter_get_basic(iter, &name);

	free(client->name);
	client->name = strdup(name);

	return true;
}

static bool parse_appearance(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	if (!iter) {
		client->appearance = 0;
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT16)
		return false;

	if (client->flags & MGMT_ADV_FLAG_APPEARANCE) {
		error("Appearance already included");
		return false;
	}

	dbus_message_iter_get_basic(iter, &client->appearance);

	return true;
}

static bool parse_duration(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	if (!iter) {
		client->duration = 0;
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT16)
		return false;

	dbus_message_iter_get_basic(iter, &client->duration);

	return true;
}

static gboolean client_timeout(void *user_data)
{
	struct btd_adv_client *client = user_data;

	DBG("");

	client->to_id = 0;

	client_release(client);
	client_remove(client);

	return FALSE;
}

static bool parse_timeout(DBusMessageIter *iter,
					struct btd_adv_client *client)
{
	if (!iter) {
		client->timeout = 0;
		g_source_remove(client->to_id);
		client->to_id = 0;
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT16)
		return false;

	dbus_message_iter_get_basic(iter, &client->timeout);

	if (client->to_id)
		g_source_remove(client->to_id);

	client->to_id = g_timeout_add_seconds(client->timeout, client_timeout,
								client);

	return true;
}

static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
{
	DBusMessageIter entries;

	if (!iter) {
		bt_ad_clear_data(client->data);
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(iter, &entries);

	bt_ad_clear_data(client->data);

	while (dbus_message_iter_get_arg_type(&entries)
						== DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter value, entry, array;
		uint8_t type;
		uint8_t *data;
		int len;

		dbus_message_iter_recurse(&entries, &entry);
		dbus_message_iter_get_basic(&entry, &type);

		dbus_message_iter_next(&entry);

		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
			goto fail;

		dbus_message_iter_recurse(&entry, &value);

		if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_ARRAY)
			goto fail;

		dbus_message_iter_recurse(&value, &array);

		if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_BYTE)
			goto fail;

		dbus_message_iter_get_fixed_array(&array, &data, &len);

		DBG("Adding Data for type 0x%02x len %u", type, len);

		if (!bt_ad_add_data(client->data, type, data, len))
			goto fail;

		dbus_message_iter_next(&entries);
	}

	return true;

fail:
	bt_ad_clear_data(client->data);
	return false;
}

static bool set_flags(struct btd_adv_client *client, uint8_t flags)
{
	if (!flags) {
		bt_ad_clear_flags(client->data);
		return true;
	}

	/* Set BR/EDR Not Supported for LE only */
	if (!btd_adapter_get_bredr(client->manager->adapter))
		flags |= 0x04;

	if (!bt_ad_add_flags(client->data, &flags, 1))
		return false;

	return true;
}

static bool parse_discoverable(DBusMessageIter *iter,
				struct btd_adv_client *client)
{
	uint8_t flags;
	dbus_bool_t discoverable;

	if (!iter) {
		bt_ad_clear_flags(client->data);
		return true;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
		return false;

	dbus_message_iter_get_basic(iter, &discoverable);

	if (discoverable)
		flags = 0x02;
	else
		flags = 0x00;

	if (!set_flags(client , flags))
		goto fail;

	DBG("Adding Flags 0x%02x", flags);

	return true;

fail:
	bt_ad_clear_flags(client->data);
	return false;
}

static struct adv_parser {
	const char *name;
	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
} parsers[] = {
	{ "Type", parse_type },
	{ "ServiceUUIDs", parse_service_uuids },
	{ "SolicitUUIDs", parse_solicit_uuids },
	{ "ManufacturerData", parse_manufacturer_data },
	{ "ServiceData", parse_service_data },
	{ "Includes", parse_includes },
	{ "LocalName", parse_local_name },
	{ "Appearance", parse_appearance },
	{ "Duration", parse_duration },
	{ "Timeout", parse_timeout },
	{ "Data", parse_data },
	{ "Discoverable", parse_discoverable },
	{ },
};

static size_t calc_max_adv_len(struct btd_adv_client *client, uint32_t flags)
{
	size_t max = client->manager->max_adv_len;

	/*
	 * Flags which reduce the amount of space available for advertising.
	 * See doc/mgmt-api.txt
	 */
	if (flags & MGMT_ADV_FLAG_TX_POWER)
		max -= 3;

	if (flags & (MGMT_ADV_FLAG_DISCOV | MGMT_ADV_FLAG_LIMITED_DISCOV |
						MGMT_ADV_FLAG_MANAGED_FLAGS))
		max -= 3;

	if (flags & MGMT_ADV_FLAG_APPEARANCE)
		max -= 4;

	return max;
}

static uint8_t *generate_adv_data(struct btd_adv_client *client,
						uint32_t *flags, size_t *len)
{
	if ((*flags & MGMT_ADV_FLAG_APPEARANCE) ||
					client->appearance != UINT16_MAX) {
		uint16_t appearance;

		appearance = client->appearance;
		if (appearance == UINT16_MAX)
			/* TODO: Get the appearance from the adaptor once
			 * supported.
			 */
			appearance = 0x000;

		bt_ad_add_appearance(client->data, appearance);
	}

	return bt_ad_generate(client->data, len);
}

static uint8_t *generate_scan_rsp(struct btd_adv_client *client,
						uint32_t *flags, size_t *len)
{
	struct btd_adv_manager *manager = client->manager;
	const char *name;

	if (!(*flags & MGMT_ADV_FLAG_LOCAL_NAME) && !client->name) {
		*len = 0;
		return NULL;
	}

	*flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;

	name = client->name;
	if (!name)
		name = btd_adapter_get_name(manager->adapter);

	bt_ad_add_name(client->scan, name);

	return bt_ad_generate(client->scan, len);
}

static int refresh_adv(struct btd_adv_client *client, mgmt_request_func_t func)
{
	struct mgmt_cp_add_advertising *cp;
	uint8_t param_len;
	uint8_t *adv_data;
	size_t adv_data_len;
	uint8_t *scan_rsp;
	size_t scan_rsp_len = -1;
	uint32_t flags = 0;

	DBG("Refreshing advertisement: %s", client->path);

	if (client->type == AD_TYPE_PERIPHERAL) {
		flags = MGMT_ADV_FLAG_CONNECTABLE;

		if (btd_adapter_get_discoverable(client->manager->adapter) &&
				!(bt_ad_has_flags(client->data)))
			flags |= MGMT_ADV_FLAG_DISCOV;
	}

	flags |= client->flags;

	adv_data = generate_adv_data(client, &flags, &adv_data_len);
	if (!adv_data || (adv_data_len > calc_max_adv_len(client, flags))) {
		error("Advertising data too long or couldn't be generated.");
		return -EINVAL;
	}

	scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len);
	if (!scan_rsp && scan_rsp_len) {
		error("Scan data couldn't be generated.");
		free(adv_data);
		return -EINVAL;
	}

	param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len +
							scan_rsp_len;

	cp = malloc0(param_len);
	if (!cp) {
		error("Couldn't allocate for MGMT!");
		free(adv_data);
		free(scan_rsp);
		return -ENOMEM;
	}

	cp->flags = htobl(flags);
	cp->instance = client->instance;
	cp->duration = client->duration;
	cp->adv_data_len = adv_data_len;
	cp->scan_rsp_len = scan_rsp_len;
	memcpy(cp->data, adv_data, adv_data_len);
	memcpy(cp->data + adv_data_len, scan_rsp, scan_rsp_len);

	free(adv_data);
	free(scan_rsp);

	if (!mgmt_send(client->manager->mgmt, MGMT_OP_ADD_ADVERTISING,
				client->manager->mgmt_index, param_len, cp,
				func, client, NULL)) {
		error("Failed to add Advertising Data");
		free(cp);
		return -EINVAL;
	}

	free(cp);

	return 0;
}

static void properties_changed(GDBusProxy *proxy, const char *name,
					DBusMessageIter *iter, void *user_data)
{
	struct btd_adv_client *client = user_data;
	struct adv_parser *parser;

	for (parser = parsers; parser && parser->name; parser++) {
		if (strcmp(parser->name, name))
			continue;

		if (parser->func(iter, client)) {
			refresh_adv(client, NULL);
			break;
		}
	}
}

static void add_client_complete(struct btd_adv_client *client, uint8_t status)
{
	DBusMessage *reply;

	if (status) {
		error("Failed to add advertisement: %s (0x%02x)",
						mgmt_errstr(status), status);
		reply = btd_error_failed(client->reg,
					"Failed to register advertisement");
		queue_remove(client->manager->clients, client);
		g_idle_add(client_free_idle_cb, client);

	} else
		reply = dbus_message_new_method_return(client->reg);

	g_dbus_send_message(btd_get_dbus_connection(), reply);
	dbus_message_unref(client->reg);
	client->reg = NULL;
}

static void add_adv_callback(uint8_t status, uint16_t length,
					  const void *param, void *user_data)
{
	struct btd_adv_client *client = user_data;
	const struct mgmt_rp_add_advertising *rp = param;

	if (status)
		goto done;

	if (!param || length < sizeof(*rp)) {
		status = MGMT_STATUS_FAILED;
		goto done;
	}

	client->instance = rp->instance;

	g_dbus_client_set_disconnect_watch(client->client, client_disconnect_cb,
									client);
	DBG("Advertisement registered: %s", client->path);

	g_dbus_emit_property_changed(btd_get_dbus_connection(),
				adapter_get_path(client->manager->adapter),
				LE_ADVERTISING_MGR_IFACE, "SupportedInstances");

	g_dbus_emit_property_changed(btd_get_dbus_connection(),
				adapter_get_path(client->manager->adapter),
				LE_ADVERTISING_MGR_IFACE, "ActiveInstances");

	g_dbus_proxy_set_property_watch(client->proxy, properties_changed,
								client);

done:
	add_client_complete(client, status);
}

static DBusMessage *parse_advertisement(struct btd_adv_client *client)
{
	struct adv_parser *parser;
	int err;

	for (parser = parsers; parser && parser->name; parser++) {
		DBusMessageIter iter;

		if (!g_dbus_proxy_get_property(client->proxy, parser->name,
								&iter))
			continue;

		if (!parser->func(&iter, client)) {
			error("Error parsing %s property", parser->name);
			goto fail;
		}
	}

	/* BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part C page 2042:
	 * A device in the broadcast mode shall not set the
	 * ‘LE General Discoverable Mode’ flag or the
	 * ‘LE Limited Discoverable Mode’ flag in the Flags AD Type as
	 * defined in [Core Specification Supplement], Part A, Section 1.3.
	 */
	if (client->type == AD_TYPE_BROADCAST &&
				bt_ad_has_flags(client->data)) {
		error("Broadcast cannot set flags");
		goto fail;
	}

	err = refresh_adv(client, add_adv_callback);
	if (!err)
		return NULL;

fail:
	return btd_error_failed(client->reg, "Failed to parse advertisement.");
}

static void client_proxy_added(GDBusProxy *proxy, void *data)
{
	struct btd_adv_client *client = data;
	DBusMessage *reply;
	const char *interface;

	interface = g_dbus_proxy_get_interface(proxy);
	if (g_str_equal(interface, LE_ADVERTISEMENT_IFACE) == FALSE)
		return;

	reply = parse_advertisement(client);
	if (!reply)
		return;

	/* Failed to publish for some reason, remove. */
	queue_remove(client->manager->clients, client);

	g_idle_add(client_free_idle_cb, client);

	g_dbus_send_message(btd_get_dbus_connection(), reply);

	dbus_message_unref(client->reg);
	client->reg = NULL;
}

static struct btd_adv_client *client_create(struct btd_adv_manager *manager,
					DBusConnection *conn,
					DBusMessage *msg, const char *path)
{
	struct btd_adv_client *client;
	const char *sender = dbus_message_get_sender(msg);

	if (!path || !g_str_has_prefix(path, "/"))
		return NULL;

	client = new0(struct btd_adv_client, 1);
	client->client = g_dbus_client_new_full(conn, sender, path, path);
	if (!client->client)
		goto fail;

	client->owner = g_strdup(sender);
	if (!client->owner)
		goto fail;

	client->path = g_strdup(path);
	if (!client->path)
		goto fail;

	DBG("Adding proxy for %s", path);
	client->proxy = g_dbus_proxy_new(client->client, path,
						LE_ADVERTISEMENT_IFACE);
	if (!client->proxy)
		goto fail;

	g_dbus_client_set_proxy_handlers(client->client, client_proxy_added,
							NULL, NULL, client);

	client->reg = dbus_message_ref(msg);

	client->data = bt_ad_new();
	if (!client->data)
		goto fail;

	client->scan = bt_ad_new();
	if (!client->scan)
		goto fail;

	client->manager = manager;
	client->appearance = UINT16_MAX;

	return client;

fail:
	client_free(client);
	return NULL;
}

static DBusMessage *register_advertisement(DBusConnection *conn,
						DBusMessage *msg,
						void *user_data)
{
	struct btd_adv_manager *manager = user_data;
	DBusMessageIter args;
	struct btd_adv_client *client;
	struct dbus_obj_match match;

	DBG("RegisterAdvertisement");

	if (!dbus_message_iter_init(msg, &args))
		return btd_error_invalid_args(msg);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
		return btd_error_invalid_args(msg);

	dbus_message_iter_get_basic(&args, &match.path);

	match.owner = dbus_message_get_sender(msg);

	if (queue_find(manager->clients, match_client, &match))
		return btd_error_already_exists(msg);

	dbus_message_iter_next(&args);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
		return btd_error_invalid_args(msg);

	client = client_create(manager, conn, msg, match.path);
	if (!client)
		return btd_error_failed(msg,
					"Failed to register advertisement");

	client->instance = util_get_uid(&manager->instance_bitmap,
							manager->max_ads);
	if (!client->instance) {
		client_free(client);
		return btd_error_not_permitted(msg,
					"Maximum advertisements reached");
	}

	DBG("Registered advertisement at path %s", match.path);

	queue_push_tail(manager->clients, client);

	return NULL;
}

static DBusMessage *unregister_advertisement(DBusConnection *conn,
						DBusMessage *msg,
						void *user_data)
{
	struct btd_adv_manager *manager = user_data;
	DBusMessageIter args;
	struct btd_adv_client *client;
	struct dbus_obj_match match;

	DBG("UnregisterAdvertisement");

	if (!dbus_message_iter_init(msg, &args))
		return btd_error_invalid_args(msg);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
		return btd_error_invalid_args(msg);

	dbus_message_iter_get_basic(&args, &match.path);

	match.owner = dbus_message_get_sender(msg);

	client = queue_find(manager->clients, match_client, &match);
	if (!client)
		return btd_error_does_not_exist(msg);

	client_remove(client);

	return dbus_message_new_method_return(msg);
}

static gboolean get_instances(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct btd_adv_manager *manager = data;
	uint8_t instances;

	instances = manager->max_ads - queue_length(manager->clients);

	dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &instances);

	return TRUE;
}

static gboolean get_active_instances(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct btd_adv_manager *manager = data;
	uint8_t instances;

	instances = queue_length(manager->clients);

	dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &instances);

	return TRUE;
}

static void append_include(struct btd_adv_manager *manager,
						DBusMessageIter *iter)
{
	struct adv_include *inc;

	for (inc = includes; inc && inc->name; inc++) {
		if (manager->supported_flags & inc->flag)
			dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
								&inc->name);
	}
}

static gboolean get_supported_includes(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct btd_adv_manager *manager = data;
	DBusMessageIter entry;

	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
					DBUS_TYPE_STRING_AS_STRING, &entry);

	append_include(manager, &entry);

	dbus_message_iter_close_container(iter, &entry);

	return TRUE;
}

static const GDBusPropertyTable properties[] = {
	{ "ActiveInstances", "y", get_active_instances, NULL, NULL },
	{ "SupportedInstances", "y", get_instances, NULL, NULL },
	{ "SupportedIncludes", "as", get_supported_includes, NULL, NULL },
	{ }
};

static const GDBusMethodTable methods[] = {
	{ GDBUS_ASYNC_METHOD("RegisterAdvertisement",
					GDBUS_ARGS({ "advertisement", "o" },
							{ "options", "a{sv}" }),
					NULL, register_advertisement) },
	{ GDBUS_ASYNC_METHOD("UnregisterAdvertisement",
						GDBUS_ARGS({ "service", "o" }),
						NULL,
						unregister_advertisement) },
	{ }
};

static void manager_destroy(void *user_data)
{
	struct btd_adv_manager *manager = user_data;

	queue_destroy(manager->clients, client_destroy);

	mgmt_unref(manager->mgmt);

	free(manager);
}

static void read_adv_features_callback(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	struct btd_adv_manager *manager = user_data;
	const struct mgmt_rp_read_adv_features *feat = param;

	if (status || !param) {
		error("Failed to read advertising features: %s (0x%02x)",
						mgmt_errstr(status), status);
		return;
	}

	if (length < sizeof(*feat)) {
		error("Wrong size of read adv features response");
		return;
	}

	manager->max_adv_len = feat->max_adv_data_len;
	manager->max_scan_rsp_len = feat->max_scan_rsp_len;
	manager->max_ads = feat->max_instances;
	manager->supported_flags |= feat->supported_flags;

	if (manager->max_ads == 0)
		return;

	/* Reset existing instances */
	if (feat->num_instances)
		remove_advertising(manager, 0);
}

static struct btd_adv_manager *manager_create(struct btd_adapter *adapter,
						struct mgmt *mgmt)
{
	struct btd_adv_manager *manager;

	manager = new0(struct btd_adv_manager, 1);
	manager->adapter = adapter;

	manager->mgmt = mgmt_ref(mgmt);

	if (!manager->mgmt) {
		error("Failed to access management interface");
		free(manager);
		return NULL;
	}

	manager->mgmt_index = btd_adapter_get_index(adapter);
	manager->clients = queue_new();
	manager->supported_flags = MGMT_ADV_FLAG_LOCAL_NAME;

	if (!g_dbus_register_interface(btd_get_dbus_connection(),
					adapter_get_path(manager->adapter),
					LE_ADVERTISING_MGR_IFACE, methods,
					NULL, properties, manager, NULL)) {
		error("Failed to register " LE_ADVERTISING_MGR_IFACE);
		goto fail;
	}

	if (!mgmt_send(manager->mgmt, MGMT_OP_READ_ADV_FEATURES,
				manager->mgmt_index, 0, NULL,
				read_adv_features_callback, manager, NULL)) {
		error("Failed to read advertising features");
		goto fail;
	}

	return manager;

fail:
	manager_destroy(manager);
	return NULL;
}

struct btd_adv_manager *btd_adv_manager_new(struct btd_adapter *adapter,
							struct mgmt *mgmt)
{
	struct btd_adv_manager *manager;

	if (!adapter || !mgmt)
		return NULL;

	manager = manager_create(adapter, mgmt);
	if (!manager)
		return NULL;

	DBG("LE Advertising Manager created for adapter: %s",
						adapter_get_path(adapter));

	return manager;
}

void btd_adv_manager_destroy(struct btd_adv_manager *manager)
{
	if (!manager)
		return;

	g_dbus_unregister_interface(btd_get_dbus_connection(),
					adapter_get_path(manager->adapter),
					LE_ADVERTISING_MGR_IFACE);

	manager_destroy(manager);
}

static void manager_refresh(void *data, void *user_data)
{
	refresh_adv(data, user_data);
}

void btd_adv_manager_refresh(struct btd_adv_manager *manager)
{
	if (!manager)
		return;

	queue_foreach(manager->clients, manager_refresh, NULL);
}
