/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2010  Nokia Corporation
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

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

#include "adapter.h"
#include "plugin.h"
#include "log.h"
#include "gdbus.h"

/* from mce/mode-names.h */
#define MCE_RADIO_STATE_BLUETOOTH	(1 << 3)

/* from mce/dbus-names.h */
#define MCE_SERVICE			"com.nokia.mce"
#define MCE_REQUEST_IF			"com.nokia.mce.request"
#define MCE_SIGNAL_IF			"com.nokia.mce.signal"
#define MCE_REQUEST_PATH		"/com/nokia/mce/request"
#define MCE_SIGNAL_PATH			"/com/nokia/mce/signal"
#define MCE_RADIO_STATES_CHANGE_REQ	"req_radio_states_change"
#define MCE_RADIO_STATES_GET		"get_radio_states"
#define MCE_RADIO_STATES_SIG		"radio_states_ind"

static guint watch_id;
static DBusConnection *conn = NULL;
static gboolean mce_bt_set = FALSE;
static gboolean collision = FALSE;

static gboolean mce_signal_callback(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	DBusMessageIter args;
	uint32_t sigvalue;
	struct btd_adapter *adapter = user_data;

	DBG("received mce signal");

	if (!dbus_message_iter_init(message, &args))
		error("message has no arguments");
	else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
		error("argument is not uint32");
	else {
		dbus_message_iter_get_basic(&args, &sigvalue);
		DBG("got signal with value %u", sigvalue);

		/* set the adapter according to the mce signal
		   and remember the value */
		mce_bt_set = !!(sigvalue & MCE_RADIO_STATE_BLUETOOTH);

		if (mce_bt_set)
			btd_adapter_switch_online(adapter);
		else
			btd_adapter_switch_offline(adapter);
	}

	return TRUE;
}

static void read_radio_states_cb(DBusPendingCall *call, void *user_data)
{
	DBusError err;
	DBusMessage *reply;
	dbus_uint32_t radio_states;
	struct btd_adapter *adapter = user_data;

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, reply)) {
		error("mce replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	dbus_error_init(&err);
	if (dbus_message_get_args(reply, &err,
				DBUS_TYPE_UINT32, &radio_states,
				DBUS_TYPE_INVALID) == FALSE) {
		error("unable to parse get_radio_states reply: %s, %s",
							err.name, err.message);
		dbus_error_free(&err);
		goto done;
	}

	DBG("radio_states: %d", radio_states);

	mce_bt_set = radio_states & MCE_RADIO_STATE_BLUETOOTH;

	/* check if the adapter has not completed the initial power
	 * cycle, if so delay action to mce_notify_powered */
	collision = mce_bt_set && adapter_powering_down(adapter);

	if (collision)
		goto done;

	if (mce_bt_set)
		btd_adapter_switch_online(adapter);
	else
		btd_adapter_switch_offline(adapter);

done:
	dbus_message_unref(reply);
}

static void adapter_powered(struct btd_adapter *adapter, gboolean powered)
{
	DBusMessage *msg;
	dbus_uint32_t radio_states = 0;
	dbus_uint32_t radio_mask = MCE_RADIO_STATE_BLUETOOTH;

	DBG("adapter_powered called with %d", powered);

	/* check if the plugin got the get_radio_states reply from the
	 * mce when the adapter was not yet down during the power
	 * cycling when bluetoothd is started */
	if (collision) {
		error("maemo6: powered state collision");
		collision = FALSE;

		if (mce_bt_set)
			btd_adapter_switch_online(adapter);

		return;
	}

	/* nothing to do if the states match */
	if (mce_bt_set == powered)
		return;

	/* set the mce value according to the state of the adapter */
	msg = dbus_message_new_method_call(MCE_SERVICE, MCE_REQUEST_PATH,
				MCE_REQUEST_IF, MCE_RADIO_STATES_CHANGE_REQ);

	if (powered)
		radio_states = MCE_RADIO_STATE_BLUETOOTH;

	dbus_message_append_args(msg, DBUS_TYPE_UINT32, &radio_states,
				DBUS_TYPE_UINT32, &radio_mask,
				DBUS_TYPE_INVALID);

	if (!dbus_connection_send(conn, msg, NULL))
		error("calling %s failed", MCE_RADIO_STATES_CHANGE_REQ);

	dbus_message_unref(msg);
}

static int mce_probe(struct btd_adapter *adapter)
{
	DBusMessage *msg;
	DBusPendingCall *call;

	DBG("path %s", adapter_get_path(adapter));

	msg = dbus_message_new_method_call(MCE_SERVICE, MCE_REQUEST_PATH,
					MCE_REQUEST_IF, MCE_RADIO_STATES_GET);

	if (!dbus_connection_send_with_reply(conn, msg, &call, -1)) {
		error("calling %s failed", MCE_RADIO_STATES_GET);
		dbus_message_unref(msg);
		return -1;
	}

	dbus_pending_call_set_notify(call, read_radio_states_cb, adapter, NULL);
	dbus_pending_call_unref(call);
	dbus_message_unref(msg);

	watch_id = g_dbus_add_signal_watch(conn, NULL, MCE_SIGNAL_PATH,
					MCE_SIGNAL_IF, MCE_RADIO_STATES_SIG,
					mce_signal_callback, adapter, NULL);

	btd_adapter_register_powered_callback(adapter, adapter_powered);

	return 0;
}

static void mce_remove(struct btd_adapter *adapter)
{
	DBG("path %s", adapter_get_path(adapter));

	if (watch_id > 0)
		g_dbus_remove_watch(conn, watch_id);

	btd_adapter_unregister_powered_callback(adapter, adapter_powered);
}

static struct btd_adapter_driver mce_driver = {
	.name	= "mce",
	.probe	= mce_probe,
	.remove	= mce_remove,
};

static int maemo6_init(void)
{
	DBG("init maemo6 plugin");

	conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
	if (conn == NULL) {
		error("Unable to connect to D-Bus");
		return -1;
	}

	return btd_register_adapter_driver(&mce_driver);
}

static void maemo6_exit(void)
{
	DBG("exit maemo6 plugin");

	if (conn != NULL)
		dbus_connection_unref(conn);

	btd_unregister_adapter_driver(&mce_driver);
}

BLUETOOTH_PLUGIN_DEFINE(maemo6, VERSION,
		BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, maemo6_init, maemo6_exit)
