/*
 *
 *  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 ?
								TRUE : FALSE;

		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 ? TRUE : FALSE;

	/* 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;
	static gboolean startup = TRUE;

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

	if (startup) {
		startup = FALSE;
		return;
	}

	/* 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))
		mce_bt_set = powered;
	else
		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)
