/*
 *
 *  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 "advertising.h"

#include <stdint.h>
#include <stdbool.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 "src/shared/ad.h"
#include "src/shared/mgmt.h"
#include "src/shared/queue.h"
#include "src/shared/util.h"

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

struct btd_advertising {
	struct btd_adapter *adapter;
	struct queue *ads;
	struct mgmt *mgmt;
	uint16_t mgmt_index;
	uint8_t max_adv_len;
	uint8_t max_ads;
	unsigned int instance_bitmap;
};

#define AD_TYPE_BROADCAST 0
#define AD_TYPE_PERIPHERAL 1

struct advertisement {
	struct btd_advertising *manager;
	char *owner;
	char *path;
	GDBusClient *client;
	GDBusProxy *proxy;
	DBusMessage *reg;
	uint8_t type; /* Advertising type */
	bool include_tx_power;
	struct bt_ad *data;
	uint8_t instance;
};

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

static bool match_advertisement(const void *a, const void *b)
{
	const struct advertisement *ad = a;
	const struct dbus_obj_match *match = b;

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

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

	return true;
}

static void advertisement_free(void *data)
{
	struct advertisement *ad = data;

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

	bt_ad_unref(ad->data);

	g_dbus_proxy_unref(ad->proxy);

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

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

	free(ad);
}

static gboolean advertisement_free_idle_cb(void *data)
{
	advertisement_free(data);

	return FALSE;
}

static void advertisement_release(void *data)
{
	struct advertisement *ad = data;
	DBusMessage *message;

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

	message = dbus_message_new_method_call(ad->owner, ad->path,
							LE_ADVERTISEMENT_IFACE,
							"Release");

	if (!message) {
		error("Couldn't allocate D-Bus message");
		return;
	}

	g_dbus_send_message(btd_get_dbus_connection(), message);
}

static void advertisement_destroy(void *data)
{
	advertisement_release(data);
	advertisement_free(data);
}

static void advertisement_remove(void *data)
{
	struct advertisement *ad = data;
	struct mgmt_cp_remove_advertising cp;

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

	cp.instance = ad->instance;

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

	queue_remove(ad->manager->ads, ad);

	util_clear_uid(&ad->manager->instance_bitmap, ad->instance);

	g_idle_add(advertisement_free_idle_cb, ad);
}

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

	advertisement_remove(user_data);
}

static bool parse_advertising_type(GDBusProxy *proxy, uint8_t *type)
{
	DBusMessageIter iter;
	const char *msg_type;

	if (!g_dbus_proxy_get_property(proxy, "Type", &iter))
		return false;

	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")) {
		*type = AD_TYPE_BROADCAST;
		return true;
	}

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

	return false;
}

static bool parse_advertising_service_uuids(GDBusProxy *proxy,
					struct bt_ad *data)
{
	DBusMessageIter iter, ariter;

	if (!g_dbus_proxy_get_property(proxy, "ServiceUUIDs", &iter))
		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(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(data, &uuid))
			goto fail;

		dbus_message_iter_next(&ariter);
	}

	return true;

fail:
	bt_ad_clear_service_uuid(data);
	return false;
}

static bool parse_advertising_solicit_uuids(GDBusProxy *proxy,
							struct bt_ad *data)
{
	DBusMessageIter iter, ariter;

	if (!g_dbus_proxy_get_property(proxy, "SolicitUUIDs", &iter))
		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(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(data, &uuid))
			goto fail;

		dbus_message_iter_next(&ariter);
	}

	return true;

fail:
	bt_ad_clear_solicit_uuid(data);
	return false;
}

static bool parse_advertising_manufacturer_data(GDBusProxy *proxy,
							struct bt_ad *data)
{
	DBusMessageIter iter, entries;

	if (!g_dbus_proxy_get_property(proxy, "ManufacturerData", &iter))
		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(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);
		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(data, manuf_id, manuf_data,
									len))
			goto fail;

		dbus_message_iter_next(&entries);
	}

	return true;

fail:
	bt_ad_clear_manufacturer_data(data);
	return false;
}

static bool parse_advertising_service_data(GDBusProxy *proxy,
							struct bt_ad *data)
{
	DBusMessageIter iter, entries;

	if (!g_dbus_proxy_get_property(proxy, "ServiceData", &iter))
		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(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);
		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(data, &uuid, service_data, len))
			goto fail;

		dbus_message_iter_next(&entries);
	}

	return true;

fail:
	bt_ad_clear_service_data(data);
	return false;
}

static bool parse_advertising_include_tx_power(GDBusProxy *proxy,
							bool *included)
{
	DBusMessageIter iter;
	dbus_bool_t b;

	if (!g_dbus_proxy_get_property(proxy, "IncludeTxPower", &iter))
		return true;

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

	dbus_message_iter_get_basic(&iter, &b);

	*included = b;

	return true;
}

static void add_adverting_complete(struct advertisement *ad, uint8_t status)
{
	DBusMessage *reply;

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

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

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

static void add_advertising_callback(uint8_t status, uint16_t length,
					  const void *param, void *user_data)
{
	struct advertisement *ad = 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;
	}

	ad->instance = rp->instance;

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

done:
	add_adverting_complete(ad, status);
}

static size_t calc_max_adv_len(struct advertisement *ad, uint32_t flags)
{
	size_t max = ad->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 DBusMessage *refresh_advertisement(struct advertisement *ad)
{
	struct mgmt_cp_add_advertising *cp;
	uint8_t param_len;
	uint8_t *adv_data;
	size_t adv_data_len;
	uint32_t flags = 0;

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

	if (ad->type == AD_TYPE_PERIPHERAL)
		flags = MGMT_ADV_FLAG_CONNECTABLE | MGMT_ADV_FLAG_DISCOV;

	if (ad->include_tx_power)
		flags |= MGMT_ADV_FLAG_TX_POWER;

	adv_data = bt_ad_generate(ad->data, &adv_data_len);

	if (!adv_data || (adv_data_len > calc_max_adv_len(ad, flags))) {
		error("Advertising data too long or couldn't be generated.");

		return g_dbus_create_error(ad->reg, ERROR_INTERFACE
						".InvalidLength",
						"Advertising data too long.");
	}

	param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len;

	cp = malloc0(param_len);

	if (!cp) {
		error("Couldn't allocate for MGMT!");

		free(adv_data);

		return btd_error_failed(ad->reg, "Failed");
	}

	cp->flags = htobl(flags);
	cp->instance = ad->instance;
	cp->adv_data_len = adv_data_len;
	memcpy(cp->data, adv_data, adv_data_len);

	free(adv_data);

	if (!mgmt_send(ad->manager->mgmt, MGMT_OP_ADD_ADVERTISING,
					ad->manager->mgmt_index, param_len, cp,
					add_advertising_callback, ad, NULL)) {
		error("Failed to add Advertising Data");

		free(cp);

		return btd_error_failed(ad->reg, "Failed");
	}

	free(cp);

	return NULL;
}

static DBusMessage *parse_advertisement(struct advertisement *ad)
{
	if (!parse_advertising_type(ad->proxy, &ad->type)) {
		error("Failed to read \"Type\" property of advertisement");
		goto fail;
	}

	if (!parse_advertising_service_uuids(ad->proxy, ad->data)) {
		error("Property \"ServiceUUIDs\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_solicit_uuids(ad->proxy, ad->data)) {
		error("Property \"SolicitUUIDs\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_manufacturer_data(ad->proxy, ad->data)) {
		error("Property \"ManufacturerData\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_service_data(ad->proxy, ad->data)) {
		error("Property \"ServiceData\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_include_tx_power(ad->proxy,
						&ad->include_tx_power)) {
		error("Property \"IncludeTxPower\" failed to parse");
		goto fail;
	}

	return refresh_advertisement(ad);

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

static void advertisement_proxy_added(GDBusProxy *proxy, void *data)
{
	struct advertisement *ad = data;
	DBusMessage *reply;

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

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

	g_idle_add(advertisement_free_idle_cb, ad);

	g_dbus_send_message(btd_get_dbus_connection(), reply);

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

static struct advertisement *advertisement_create(DBusConnection *conn,
					DBusMessage *msg, const char *path)
{
	struct advertisement *ad;
	const char *sender = dbus_message_get_sender(msg);

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

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

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

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

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

	g_dbus_client_set_proxy_handlers(ad->client, advertisement_proxy_added,
								NULL, NULL, ad);

	ad->reg = dbus_message_ref(msg);

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

	return ad;

fail:
	advertisement_free(ad);
	return NULL;
}

static DBusMessage *register_advertisement(DBusConnection *conn,
						DBusMessage *msg,
						void *user_data)
{
	struct btd_advertising *manager = user_data;
	DBusMessageIter args;
	struct advertisement *ad;
	struct dbus_obj_match match;
	uint8_t instance;

	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->ads, match_advertisement, &match))
		return btd_error_already_exists(msg);

	instance = util_get_uid(&manager->instance_bitmap, manager->max_ads);
	if (!instance)
		return btd_error_failed(msg, "Maximum advertisements reached");

	dbus_message_iter_next(&args);

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

	ad = advertisement_create(conn, msg, match.path);
	if (!ad)
		return btd_error_failed(msg,
					"Failed to register advertisement");

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

	ad->instance = instance;
	ad->manager = manager;

	queue_push_tail(manager->ads, ad);

	return NULL;
}

static DBusMessage *unregister_advertisement(DBusConnection *conn,
						DBusMessage *msg,
						void *user_data)
{
	struct btd_advertising *manager = user_data;
	DBusMessageIter args;
	struct advertisement *ad;
	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);

	ad = queue_find(manager->ads, match_advertisement, &match);
	if (!ad)
		return btd_error_does_not_exist(msg);

	advertisement_remove(ad);

	return dbus_message_new_method_return(msg);
}

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

static void advertising_manager_destroy(void *user_data)
{
	struct btd_advertising *manager = user_data;

	queue_destroy(manager->ads, advertisement_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_advertising *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_ads = feat->max_instances;

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

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

static struct btd_advertising *
advertising_manager_create(struct btd_adapter *adapter)
{
	struct btd_advertising *manager;

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

	manager->mgmt = mgmt_new_default();

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

	manager->mgmt_index = btd_adapter_get_index(adapter);

	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");
		advertising_manager_destroy(manager);
		return NULL;
	}

	manager->ads = queue_new();

	return manager;
}

struct btd_advertising *
btd_advertising_manager_new(struct btd_adapter *adapter)
{
	struct btd_advertising *manager;

	if (!adapter)
		return NULL;

	manager = advertising_manager_create(adapter);
	if (!manager)
		return NULL;

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

	return manager;
}

void btd_advertising_manager_destroy(struct btd_advertising *manager)
{
	if (!manager)
		return;

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

	advertising_manager_destroy(manager);
}
