/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2005  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 <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

#include <dbus/dbus.h>

#include "glib-ectomy.h"

#include "hcid.h"
#include "dbus.h"

static DBusConnection *connection;
static int default_dev = -1;

#define TIMEOUT				(30 * 1000)		/* 30 seconds */
#define DBUS_RECONNECT_TIMER		(5 * 1000 * 1000)	/* 5 sec */
#define MAX_PATH_LENGTH			64
#define MAX_CONN_NUMBER			10

#define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent"
#define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME
#define PIN_REQUEST "PinRequest"
#define PINAGENT_PATH BASE_PATH "/PinAgent"

struct pin_request {
	int dev;
	bdaddr_t bda;
};

typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *);

struct service_data {
	const char		*name;
	service_handler_func_t	*handler_func;
	const char		*signature;
};

struct hci_dbus_data {
	uint16_t dev_id;
	uint16_t path_id;
};

typedef int register_function_t(DBusConnection *conn, uint16_t id);
typedef int unregister_function_t(DBusConnection *conn, uint16_t id);

const struct service_data *get_hci_table(void);

static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id);
static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id);

typedef const struct service_data *get_svc_table_func_t(void);

struct profile_obj_path_data {
	uint16_t		id;
	register_function_t	*reg_func;
	unregister_function_t	*unreg_func;
	get_svc_table_func_t	*get_svc_table;	/* return the service table */
};

/*
 * D-Bus error messages functions and declarations.
 * This section should be moved to a common file 
 * in the future
 *
 */

typedef struct  {
	uint32_t code;
	const char *str;
} bluez_error_t;

typedef struct {
	char *str;
	unsigned int val;
} hci_map;

static hci_map dev_flags_map[] = {
	{ "INIT",	HCI_INIT	},
	{ "RUNNING",	HCI_RUNNING	},
	{ "RAW",	HCI_RAW		},
	{ "PSCAN",	HCI_PSCAN	},
	{ "ISCAN",	HCI_ISCAN	},
	{ "INQUIRY",	HCI_INQUIRY	},
	{ "AUTH",	HCI_AUTH	},
	{ "ENCRYPT",	HCI_ENCRYPT	},
	{ "SECMGR",	HCI_SECMGR	},
	{ NULL }
};

static const bluez_error_t dbus_error_array[] = {
	{ BLUEZ_EDBUS_UNKNOWN_METHOD,	"Method not found"		},
	{ BLUEZ_EDBUS_WRONG_SIGNATURE,	"Wrong method signature"	},
	{ BLUEZ_EDBUS_WRONG_PARAM,	"Invalid parameters"		},
	{ BLUEZ_EDBUS_RECORD_NOT_FOUND,	"No record found"		},
	{ BLUEZ_EDBUS_NO_MEM,		"No memory"			},
	{ BLUEZ_EDBUS_CONN_NOT_FOUND,	"Connection not found"		},
	{ BLUEZ_EDBUS_UNKNOWN_PATH,	"Unknown D-BUS path"		},
	{ 0, NULL }
};

static const bluez_error_t hci_error_array[] = {
	{ HCI_UNKNOWN_COMMAND,			"Unknown HCI Command"						},
	{ HCI_NO_CONNECTION,			"Unknown Connection Identifier"					},
	{ HCI_HARDWARE_FAILURE,			"Hardware Failure"						},
	{ HCI_PAGE_TIMEOUT,			"Page Timeout"							},
	{ HCI_AUTHENTICATION_FAILURE,		"Authentication Failure"					},
	{ HCI_PIN_OR_KEY_MISSING,		"PIN Missing"							},
	{ HCI_MEMORY_FULL,			"Memory Capacity Exceeded"					},
	{ HCI_CONNECTION_TIMEOUT,		"Connection Timeout"						},
	{ HCI_MAX_NUMBER_OF_CONNECTIONS,	"Connection Limit Exceeded"					},
	{ HCI_MAX_NUMBER_OF_SCO_CONNECTIONS,	"Synchronous Connection Limit To A Device Exceeded"		},
	{ HCI_ACL_CONNECTION_EXISTS,		"ACL Connection Already Exists"					},
	{ HCI_COMMAND_DISALLOWED,		"Command Disallowed"						},
	{ HCI_REJECTED_LIMITED_RESOURCES,	"Connection Rejected due to Limited Resources"			},
	{ HCI_REJECTED_SECURITY,		"Connection Rejected Due To Security Reasons"			},
	{ HCI_REJECTED_PERSONAL,		"Connection Rejected due to Unacceptable BD_ADDR"		},
	{ HCI_HOST_TIMEOUT,			"Connection Accept Timeout Exceeded"				},
	{ HCI_UNSUPPORTED_FEATURE,		"Unsupported Feature or Parameter Value"			},
	{ HCI_INVALID_PARAMETERS,		"Invalid HCI Command Parameters"				},
	{ HCI_OE_USER_ENDED_CONNECTION,		"Remote User Terminated Connection"				},
	{ HCI_OE_LOW_RESOURCES,			"Remote Device Terminated Connection due to Low Resources"	},
	{ HCI_OE_POWER_OFF,			"Remote Device Terminated Connection due to Power Off"		},
	{ HCI_CONNECTION_TERMINATED,		"Connection Terminated By Local Host"				},
	{ HCI_REPEATED_ATTEMPTS,		"Repeated Attempts"						},
	{ HCI_PAIRING_NOT_ALLOWED,		"Pairing Not Allowed"						},
	{ HCI_UNKNOWN_LMP_PDU,			"Unknown LMP PDU"						},
	{ HCI_UNSUPPORTED_REMOTE_FEATURE,	"Unsupported Remote Feature"					},
	{ HCI_SCO_OFFSET_REJECTED,		"SCO Offset Rejected"						},
	{ HCI_SCO_INTERVAL_REJECTED,		"SCO Interval Rejected"						},
	{ HCI_AIR_MODE_REJECTED,		"SCO Air Mode Rejected"						},
	{ HCI_INVALID_LMP_PARAMETERS,		"Invalid LMP Parameters"					},
	{ HCI_UNSPECIFIED_ERROR,		"Unspecified Error"						},
	{ HCI_UNSUPPORTED_LMP_PARAMETER_VALUE,	"Unsupported LMP Parameter Value"				},
	{ HCI_ROLE_CHANGE_NOT_ALLOWED,		"Role Change Not Allowed"					},
	{ HCI_LMP_RESPONSE_TIMEOUT,		"LMP Response Timeout"						},
	{ HCI_LMP_ERROR_TRANSACTION_COLLISION,	"LMP Error Transaction Collision"				},
	{ HCI_LMP_PDU_NOT_ALLOWED,		"LMP PDU Not Allowed"						},
	{ HCI_ENCRYPTION_MODE_NOT_ACCEPTED,	"Encryption Mode Not Acceptable"				},
	{ HCI_UNIT_LINK_KEY_USED,		"Link Key Can Not be Changed"					},
	{ HCI_QOS_NOT_SUPPORTED,		"Requested QoS Not Supported"					},
	{ HCI_INSTANT_PASSED,			"Instant Passed"						},
	{ HCI_PAIRING_NOT_SUPPORTED,		"Pairing With Unit Key Not Supported"				},
	{ HCI_TRANSACTION_COLLISION,		"Different Transaction Collision"				},
	{ HCI_QOS_UNACCEPTABLE_PARAMETER,	"QoS Unacceptable Parameter"					},
	{ HCI_QOS_REJECTED,			"QoS Rejected"							},
	{ HCI_CLASSIFICATION_NOT_SUPPORTED,	"Channel Classification Not Supported"				},
	{ HCI_INSUFFICIENT_SECURITY,		"Insufficient Security"						},
	{ HCI_PARAMETER_OUT_OF_RANGE,		"Parameter Out Of Mandatory Range"				},
	{ HCI_ROLE_SWITCH_PENDING,		"Role Switch Pending"						},
	{ HCI_SLOT_VIOLATION,			"Reserved Slot Violation"					},
	{ HCI_ROLE_SWITCH_FAILED,		"Role Switch Failed"						},
	{ 0, NULL },
};

static const char *bluez_dbus_error_to_str(const uint32_t ecode) 
{
	const bluez_error_t *ptr;
	uint32_t raw_code = 0;

	if (ecode & BLUEZ_ESYSTEM_OFFSET) {
		/* System error */
		raw_code = (~BLUEZ_ESYSTEM_OFFSET) & ecode;
		syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code));
		return strerror(raw_code);
	} else if (ecode & BLUEZ_EDBUS_OFFSET) {
		/* D-Bus error */
		for (ptr = dbus_error_array; ptr->code; ptr++) {
			if (ptr->code == ecode) {
				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str);
				return ptr->str;
			}
		}
	} else {
		/* BLUEZ_EBT_OFFSET - Bluetooth HCI errors */
		for (ptr = hci_error_array; ptr->code; ptr++) {
			if (ptr->code == ecode) {
				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str);
				return ptr->str;
			}
		}
	}

	return NULL;
}

static DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode)
{
	DBusMessageIter iter;
	DBusMessage *reply;
	const char *error_msg;

	error_msg = bluez_dbus_error_to_str(ecode);
	if (!error_msg)
		return NULL;

	reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg);

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode);

	return reply;
}

/*
 * Object path register/unregister functions 
 *
 */
static struct profile_obj_path_data obj_path_table[] = {
	{ HCI_PATH_ID, hci_dbus_reg_obj_path, hci_dbus_unreg_obj_path, get_hci_table },
	/* add other profiles here */
	{ INVALID_PATH_ID, NULL, NULL, NULL }
};

/*
 * Virtual table that handle the object path hierarchy
 */
static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data);
static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data);
static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data);

static const DBusObjectPathVTable obj_dev_vtable = {
	.message_function	= &msg_func_device,
	.unregister_function	= NULL
};

static const DBusObjectPathVTable obj_mgr_vtable = {
	.message_function	= &msg_func_manager,
	.unregister_function	= NULL
};

/*
 * Services provided under the path DEVICE_PATH
 */
static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data);
static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data);
static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data);
static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data);
static DBusMessage* handle_device_set_propety_req_name(DBusMessage *msg, void *data);
static DBusMessage* handle_device_get_propety_req_name(DBusMessage *msg, void *data);

static const struct service_data device_services[] = {
	{ DEV_UP,		handle_device_up_req,		DEV_UP_SIGNATURE		},
	{ DEV_DOWN,		handle_device_down_req,		DEV_DOWN_SIGNATURE		},
	{ DEV_SET_PROPERTY,	handle_device_set_propety_req,	DEV_SET_PROPERTY_SIGNATURE_BOOL	},
	{ DEV_SET_PROPERTY,	handle_device_set_propety_req,	DEV_SET_PROPERTY_SIGNATURE_STR	},
	{ DEV_SET_PROPERTY,	handle_device_set_propety_req,	DEV_SET_PROPERTY_SIGNATURE_BYTE	},
	{ DEV_GET_PROPERTY,	handle_device_get_propety_req,	DEV_GET_PROPERTY_SIGNATURE	},
	{ NULL, NULL, NULL}
};

static const struct service_data set_property_services[] = {
	{ DEV_PROPERTY_AUTH,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BOOL		},
	{ DEV_PROPERTY_ENCRYPT,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BOOL		},
	{ DEV_PROPERTY_PSCAN,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BOOL		},
	{ DEV_PROPERTY_ISCAN,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BOOL		},
	{ DEV_PROPERTY_NAME,		handle_device_set_propety_req_name,	DEV_SET_PROPERTY_SIGNATURE_STR		},
	{ DEV_PROPERTY_INCMODE,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BYTE		},
	{ NULL, NULL, NULL}
};

static const struct service_data get_property_services[] = {
	{ DEV_PROPERTY_DEV_INFO,	handle_not_implemented_req,		DEV_GET_PROPERTY_SIGNATURE 	},
	{ DEV_PROPERTY_NAME,		handle_device_get_propety_req_name,	DEV_GET_PROPERTY_SIGNATURE 	},
	{ DEV_PROPERTY_INCMODE,		handle_not_implemented_req,		DEV_GET_PROPERTY_SIGNATURE 	},
	{ NULL, NULL, NULL}
};

/*
 * Services provided under the path MANAGER_PATH
 */
static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data);
static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data);

static const struct service_data manager_services[] = {
	{ MGR_DEVICE_LIST,	handle_device_list_req,		MGR_GET_DEV_SIGNATURE		},
	{ MGR_DEFAULT_DEVICE,	handle_default_device_req,	MGR_DEFAULT_DEV_SIGNATURE	},
	{ MGR_INIT,		handle_not_implemented_req,	NULL				},
	{ MGR_ENABLE,		handle_not_implemented_req,	NULL				},
	{ MGR_DISABLE,		handle_not_implemented_req,	NULL				},
	{ NULL, NULL, NULL }
};

/*
 * HCI D-Bus services
 */
static DBusHandlerResult hci_signal_filter(DBusConnection *conn, DBusMessage *msg, void *data);

static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data);
static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data);
static DBusMessage* handle_inq_req(DBusMessage *msg, void *data);
static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data);
static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data);
static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data);
static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data);
static DBusMessage* handle_auth_req(DBusMessage *msg, void *data);

static const struct service_data device_hci_services[] = {
	{ HCI_PERIODIC_INQ,		handle_periodic_inq_req,	HCI_PERIODIC_INQ_SIGNATURE		},
	{ HCI_PERIODIC_INQ,		handle_periodic_inq_req,	HCI_PERIODIC_INQ_EXT_SIGNATURE		},
	{ HCI_CANCEL_PERIODIC_INQ,	handle_cancel_periodic_inq_req,	HCI_CANCEL_PERIODIC_INQ_SIGNATURE	},
	{ HCI_ROLE_SWITCH,		handle_role_switch_req,		HCI_ROLE_SWITCH_SIGNATURE		},
	{ HCI_INQ,			handle_inq_req,			HCI_INQ_SIGNATURE			},
	{ HCI_INQ,			handle_inq_req,			HCI_INQ_EXT_SIGNATURE			},
	{ HCI_CANCEL_INQ,		handle_cancel_inq_req,		HCI_CANCEL_INQ_SIGNATURE		},
	{ HCI_REMOTE_NAME,		handle_remote_name_req,		HCI_REMOTE_NAME_SIGNATURE		},
	{ HCI_CONNECTIONS,		handle_display_conn_req,	HCI_CONNECTIONS_SIGNATURE		},
	{ HCI_AUTHENTICATE,		handle_auth_req,		HCI_AUTHENTICATE_SIGNATURE		},
	{ NULL, NULL, NULL }
};

static void reply_handler_function(DBusPendingCall *call, void *user_data)
{
	struct pin_request *req = (struct pin_request *) user_data;
	pin_code_reply_cp pr;
	DBusMessage *message;
	DBusMessageIter iter;
	int arg_type;
	int msg_type;
	size_t len;
	char *pin;
	const char *error_msg;

	message = dbus_pending_call_steal_reply(call);

	if (!message)
		goto done;

	msg_type = dbus_message_get_type(message);
	dbus_message_iter_init(message, &iter);

	if (msg_type == DBUS_MESSAGE_TYPE_ERROR) {
		dbus_message_iter_get_basic(&iter, &error_msg);

		/* handling WRONG_ARGS_ERROR, DBUS_ERROR_NO_REPLY, DBUS_ERROR_SERVICE_UNKNOWN */
		syslog(LOG_ERR, "%s: %s", dbus_message_get_error_name(message), error_msg);
		hci_send_cmd(req->dev, OGF_LINK_CTL,
					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);
	} else {
		/* check signature */
		arg_type = dbus_message_iter_get_arg_type(&iter);
		if (arg_type != DBUS_TYPE_STRING) {
			syslog(LOG_ERR, "Wrong reply signature: expected PIN");
			hci_send_cmd(req->dev, OGF_LINK_CTL,
					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);
		} else {
			dbus_message_iter_get_basic(&iter, &pin);
			len = strlen(pin);

			memset(&pr, 0, sizeof(pr));
			bacpy(&pr.bdaddr, &req->bda);
			memcpy(pr.pin_code, pin, len);
			pr.pin_len = len;
			hci_send_cmd(req->dev, OGF_LINK_CTL,
				OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);
		}
	}

	dbus_message_unref(message);

done:
	dbus_pending_call_unref(call);
}

static void free_pin_req(void *req)
{
	free(req);
}

static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t dev_id,
				const DBusObjectPathVTable *pvtable, gboolean fallback)
{
	gboolean ret = FALSE;
	struct hci_dbus_data *data = NULL;

	data = malloc(sizeof(struct hci_dbus_data));
	if (data == NULL) {
		syslog(LOG_ERR, "Failed to alloc memory to DBUS path register data (%s)", path);
		goto failed;
	}

	data->path_id = path_id;
	data->dev_id = dev_id;

	if (fallback) {
		if (!dbus_connection_register_fallback(connection, path, pvtable, data)) {
			syslog(LOG_ERR, "DBUS failed to register %s fallback", path);
			goto failed;
		}
	} else {
		if (!dbus_connection_register_object_path(connection, path, pvtable, data)) {
			syslog(LOG_ERR, "DBUS failed to register %s object", path);
			goto failed;
		}
	}

	ret = TRUE;

failed:
	if (!ret && data)
		free(data);

	return ret;
}

static gboolean unregister_dbus_path(const char *path)
{
	void *data;

	if (dbus_connection_get_object_path_data(connection, path, &data) && data)
		free(data);

	if (!dbus_connection_unregister_object_path (connection, path)) {
		syslog(LOG_ERR, "DBUS failed to unregister %s object", path);
		return FALSE;
	}

	return TRUE;
}

void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci)
{
	DBusMessage *message;
	DBusPendingCall *pending = NULL;
	struct pin_request *req;
	uint8_t *addr = (uint8_t *) &ci->bdaddr;
	dbus_bool_t out = ci->out;

	message = dbus_message_new_method_call(PINAGENT_SERVICE_NAME, PINAGENT_PATH,
						PINAGENT_INTERFACE, PIN_REQUEST);
	if (message == NULL) {
		syslog(LOG_ERR, "Couldn't allocate D-BUS message");
		goto failed;
	}

	req = malloc(sizeof(*req));
	req->dev = dev;
	bacpy(&req->bda, &ci->bdaddr);

	dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &out,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
			&addr, sizeof(bdaddr_t), DBUS_TYPE_INVALID);

	if (dbus_connection_send_with_reply(connection, message,
						&pending, TIMEOUT) == FALSE) {
		syslog(LOG_ERR, "D-BUS send failed");
		goto failed;
	}

	dbus_pending_call_set_notify(pending, reply_handler_function,
							req, free_pin_req);

	dbus_connection_flush(connection);

	dbus_message_unref(message);

	return;

failed:
	dbus_message_unref(message);
	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr);
}

void hcid_dbus_inquiry_start(bdaddr_t *local)
{
	DBusMessage *message = NULL;
	char path[MAX_PATH_LENGTH];
	char *local_addr;
	bdaddr_t tmp;
	int id;

	baswap(&tmp, local); local_addr = batostr(&tmp);

	id = hci_devid(local_addr);
	if (id < 0) {
		syslog(LOG_ERR, "No matching device id for %s", local_addr);
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);

	message = dbus_message_new_signal(path, DEV_HCI_INTERFACE,
						BLUEZ_HCI_INQ_START);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message");
		goto failed;
	}

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS inquiry start message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);
	bt_free(local_addr);
}

void hcid_dbus_inquiry_complete(bdaddr_t *local)
{
	DBusMessage *message = NULL;
	char path[MAX_PATH_LENGTH];
	char *local_addr;
	bdaddr_t tmp;
	int id;

	baswap(&tmp, local); local_addr = batostr(&tmp);

	id = hci_devid(local_addr);
	if (id < 0) {
		syslog(LOG_ERR, "No matching device id for %s", local_addr);
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);

	message = dbus_message_new_signal(path, DEV_HCI_INTERFACE,
						BLUEZ_HCI_INQ_COMPLETE);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message");
		goto failed;
	}

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS inquiry complete message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);
	bt_free(local_addr);
}

void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi)
{
	DBusMessage *message = NULL;
	char path[MAX_PATH_LENGTH];
	char *local_addr, *peer_addr;
	dbus_uint32_t tmp_class = class;
	dbus_int32_t tmp_rssi = rssi;
	bdaddr_t tmp;
	int id;

	baswap(&tmp, local); local_addr = batostr(&tmp);
	baswap(&tmp, peer); peer_addr = batostr(&tmp);

	id = hci_devid(local_addr);
	if (id < 0) {
		syslog(LOG_ERR, "No matching device id for %s", local_addr);
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);

	message = dbus_message_new_signal(path, DEV_HCI_INTERFACE,
						BLUEZ_HCI_INQ_RESULT);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS inquiry result message");
		goto failed;
	}

	dbus_message_append_args(message,
					DBUS_TYPE_STRING, &peer_addr,
					DBUS_TYPE_UINT32, &tmp_class,
					DBUS_TYPE_INT32, &tmp_rssi,
					DBUS_TYPE_INVALID);

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS inquiry result message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);

	bt_free(local_addr);
	bt_free(peer_addr);
}

void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
{
	DBusMessage *message = NULL;
	char path[MAX_PATH_LENGTH];
	char *local_addr, *peer_addr;
	bdaddr_t tmp;
	int id;

	baswap(&tmp, local); local_addr = batostr(&tmp);
	baswap(&tmp, peer); peer_addr = batostr(&tmp);

	id = hci_devid(local_addr);
	if (id < 0) {
		syslog(LOG_ERR, "No matching device id for %s", local_addr);
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);

	message = dbus_message_new_signal(path, DEV_HCI_INTERFACE,
						BLUEZ_HCI_REMOTE_NAME);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");
		goto failed;
	}

	dbus_message_append_args(message,
					DBUS_TYPE_STRING, &peer_addr,
					DBUS_TYPE_STRING, &name,
					DBUS_TYPE_INVALID);

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS remote name message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);

	bt_free(local_addr);
	bt_free(peer_addr);
}

void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status)
{
	DBusMessage *message = NULL;
	char path[MAX_PATH_LENGTH];
	char *local_addr, *peer_addr;
	bdaddr_t tmp;
	int id;

	baswap(&tmp, local); local_addr = batostr(&tmp);
	baswap(&tmp, peer); peer_addr = batostr(&tmp);

	id = hci_devid(local_addr);
	if (id < 0) {
		syslog(LOG_ERR, "No matching device id for %s", local_addr);
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);

	message = dbus_message_new_signal(path, DEV_HCI_INTERFACE,
						BLUEZ_HCI_REMOTE_NAME_FAILED);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");
		goto failed;
	}

	dbus_message_append_args(message,
					DBUS_TYPE_STRING, &peer_addr,
					DBUS_TYPE_BYTE, &status,
					DBUS_TYPE_INVALID);

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS remote name message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);

	bt_free(local_addr);
	bt_free(peer_addr);
}

void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer)
{
}

void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason)
{
}

void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status)
{
	DBusMessage *message = NULL;
	char *local_addr, *peer_addr;
	bdaddr_t tmp;
	char path[MAX_PATH_LENGTH];
	int id;

	baswap(&tmp, local); local_addr = batostr(&tmp);
	baswap(&tmp, peer); peer_addr = batostr(&tmp);

	id = hci_devid(local_addr);
	if (id < 0) {
		syslog(LOG_ERR, "No matching device id for %s", local_addr);
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);

	message = dbus_message_new_signal(path, DEV_HCI_INTERFACE,
						BLUEZ_HCI_AUTH_COMPLETE);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");
		goto failed;
	}

	dbus_message_append_args(message,
					DBUS_TYPE_STRING, &peer_addr,
					DBUS_TYPE_BYTE, &status,
					DBUS_TYPE_INVALID);

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS remote name message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);

	bt_free(local_addr);
	bt_free(peer_addr);
}

gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	DBusWatch *watch = (DBusWatch *) data;
	int flags = 0;

	if (cond & G_IO_IN)  flags |= DBUS_WATCH_READABLE;
	if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
	if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
	if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;

	dbus_watch_handle(watch, flags);

	dbus_connection_ref(connection);

	/* Dispatch messages */
	while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS);

	dbus_connection_unref(connection);

	return TRUE;
}

dbus_bool_t add_watch(DBusWatch *watch, void *data)
{
	GIOCondition cond = G_IO_HUP | G_IO_ERR;
	GIOChannel *io;
	guint *id;
	int fd, flags;

	if (!dbus_watch_get_enabled(watch))
		return TRUE;

	id = malloc(sizeof(guint));
	if (id == NULL)
		return FALSE;

	fd = dbus_watch_get_fd(watch);
	io = g_io_channel_unix_new(fd);
	flags = dbus_watch_get_flags(watch);

	if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN;
	if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT;

	*id = g_io_add_watch(io, cond, watch_func, watch);

	dbus_watch_set_data(watch, id, NULL);

	return TRUE;
}

static void remove_watch(DBusWatch *watch, void *data)
{
	guint *id = dbus_watch_get_data(watch);

	dbus_watch_set_data(watch, NULL, NULL);

	if (id) {
		g_io_remove_watch(*id);
		free(id);
	}
}

static void watch_toggled(DBusWatch *watch, void *data)
{
	/* Because we just exit on OOM, enable/disable is
	 * no different from add/remove */
	if (dbus_watch_get_enabled(watch))
		add_watch(watch, data);
	else
		remove_watch(watch, data);
}

static gboolean unregister_device_path(const char *path)
{
	char **children = NULL;

	if (!dbus_connection_list_registered(connection, path, &children))
		goto done;

	for (; *children; children++) {
		char child_path[MAX_PATH_LENGTH];

		snprintf(child_path, sizeof(child_path), "%s/%s", path, *children);

		unregister_dbus_path(child_path);
	}

	if (*children)
		dbus_free_string_array(children);

done:
	return unregister_dbus_path(path);
}

gboolean hcid_dbus_init(void)
{
	DBusError error;

	dbus_error_init(&error);

	connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

	if (dbus_error_is_set(&error)) {
		syslog(LOG_ERR, "Can't open system message bus connection: %s",
								error.message);
		dbus_error_free(&error);
		return FALSE;
	}

	dbus_connection_set_exit_on_disconnect(connection, FALSE);

	dbus_bus_request_name(connection, BASE_INTERFACE,
				DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &error);

	if (dbus_error_is_set(&error)) {
		syslog(LOG_ERR, "Can't get system message bus name: %s",
								error.message);
		dbus_error_free(&error);
		return FALSE;
	}

	if (!register_dbus_path(DEVICE_PATH, DEVICE_ROOT_ID, INVALID_DEV_ID,
				&obj_dev_vtable, TRUE))
		return FALSE;

	if (!register_dbus_path(MANAGER_PATH, MANAGER_ROOT_ID, INVALID_DEV_ID,
				&obj_mgr_vtable, FALSE))
		return FALSE;

	if (!dbus_connection_add_filter(connection, hci_signal_filter, NULL, NULL)) {
		syslog(LOG_ERR, "Can't add new HCI filter");
		return FALSE;
	}

	dbus_connection_set_watch_functions(connection,
			add_watch, remove_watch, watch_toggled, NULL, NULL);

	return TRUE;
}

void hcid_dbus_exit(void)
{
	char **children = NULL;

	if (!connection)
		return;

	/* Unregister all paths in Device path hierarchy */
	if (dbus_connection_list_registered(connection, DEVICE_PATH, &children)) {

		for (; *children; children++) {
			char dev_path[MAX_PATH_LENGTH];

			snprintf(dev_path, sizeof(dev_path), "%s/%s", DEVICE_PATH, *children);

			unregister_device_path(dev_path);
		}

		if (*children)
			dbus_free_string_array(children);
	}

	unregister_dbus_path(DEVICE_PATH);
	unregister_dbus_path(MANAGER_PATH);

	dbus_connection_close(connection);
}

gboolean hcid_dbus_register_device(uint16_t id) 
{
	char path[MAX_PATH_LENGTH];
	char *pptr = path;
	gboolean ret;
	DBusMessage *message = NULL;

	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);

	message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE,
							BLUEZ_MGR_DEV_ADDED);

	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");
		goto failed;
	}

	dbus_message_append_args(message,
					DBUS_TYPE_STRING, &pptr,
					DBUS_TYPE_INVALID);

	if (!dbus_connection_send(connection, message, NULL)) {
		syslog(LOG_ERR, "Can't send D-BUS added device message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);

	ret = register_dbus_path(path, DEVICE_PATH_ID, id, &obj_dev_vtable, FALSE);

	if (ret && default_dev < 0)
		default_dev = id;

	return ret;
}

gboolean hcid_dbus_unregister_device(uint16_t id)
{
	gboolean ret;
	DBusMessage *message = NULL;
	char path[MAX_PATH_LENGTH];
	char *pptr = path;

	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);

	message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE,
							BLUEZ_MGR_DEV_REMOVED);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");
		goto failed;
	}

	dbus_message_append_args(message,
					DBUS_TYPE_STRING, &pptr,
					DBUS_TYPE_INVALID);

	if (!dbus_connection_send(connection, message, NULL)) {
		syslog(LOG_ERR, "Can't send D-BUS added device message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	dbus_message_unref(message);

	ret = unregister_device_path(path);

	/* FIXME: If there are any devices left after this removal the default
	 * device should be changed to one of them */
	if (ret && default_dev == id)
		default_dev = -1;

	return ret;
}

gboolean hcid_dbus_dev_up(uint16_t id)
{
	char path[MAX_PATH_LENGTH];
	struct profile_obj_path_data *ptr = obj_path_table;
	DBusMessage *message = NULL;

	if (!connection)
		return FALSE;

	for (; ptr->id != INVALID_PATH_ID; ptr++) {
		if (ptr->reg_func(connection, id) < 0)
			goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);

	message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_UP);

	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");
		goto failed;
	}

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS added device message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	/* if the signal can't be sent ignore the error */

	dbus_message_unref(message);

	return TRUE;
}

gboolean hcid_dbus_dev_down(uint16_t id)
{
	char path[MAX_PATH_LENGTH];
	struct profile_obj_path_data *ptr = obj_path_table;
	DBusMessage *message = NULL;

	if (!connection)
		return FALSE;

	for (; ptr->id != INVALID_PATH_ID; ptr++) {
		if (ptr->unreg_func(connection, id) < 0)
			syslog(LOG_ERR, "Unregistering profile id 0x%04x failed", ptr->id);
	}

	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);

	message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_DOWN);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS device removed  message");
		goto failed;
	}

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS removed device message");
		goto failed;
	}

	dbus_connection_flush(connection);

failed:
	/* if the signal can't be sent ignore the error */

	dbus_message_unref(message);

	return TRUE;
}

/*
 * @brief HCI object path register function
 * Detailed description: function responsible for register a new hci 
 * D-Bus path. If necessary the default path must be registered too.
 * @param conn D-Bus connection
 * @param id hci device identification
 * @return (0-Success/-1 failure)
 */
static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id)
{
	char path[MAX_PATH_LENGTH];

	/* register the default path*/
	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);
	if (!register_dbus_path(path, HCI_PATH_ID, id, &obj_dev_vtable, FALSE))
		return -1;

	return 0;
}

/*
 * @brief HCI object path unregister function
 * Detailed description: function responsible for unregister HCI D-Bus
 * path for a detached hci device. If necessary the default path must 
 * be registered too.
 * @param conn D-Bus connection
 * @param unreg_dft register the default path(0 or !0)
 * @param id hci device identification
 * @return (0-Success/-1 failure)
 */
static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id) 
{
	char path[MAX_PATH_LENGTH];

	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);
	if (!unregister_dbus_path(path))
		return -1;

	return 0;
}

const struct service_data *get_hci_table(void)
{
	return device_hci_services;
}

/*****************************************************************
 *
 *  Section reserved to re-connection timer
 *
 *****************************************************************/
static void reconnect_timer_handler(int signum)
{
	struct hci_dev_list_req *dl = NULL;
	struct hci_dev_req *dr;
	int sk;
	int i;

	if (hcid_dbus_init() == FALSE)
		return;

	/* stop the timer */
	sigaction(SIGALRM, NULL, NULL);
	setitimer(ITIMER_REAL, NULL, NULL);

	/* register the device based paths */

	/* Create and bind HCI socket */
	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (sk < 0) {
		syslog(LOG_ERR, "Can't open HCI socket: %s (%d)",
							strerror(errno), errno);
		return;
	}

	dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));
	if (!dl) {
		syslog(LOG_ERR, "Can't allocate memory");
		goto failed;
	}

	dl->dev_num = HCI_MAX_DEV;
	dr = dl->dev_req;

	if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) {
		syslog(LOG_INFO, "Can't get device list: %s (%d)",
							strerror(errno), errno);
		goto failed;
	}

	/* reset the default device */
	default_dev = -1;

	for (i = 0; i < dl->dev_num; i++, dr++) {

		hcid_dbus_register_device(dr->dev_id);

		if (hci_test_bit(HCI_UP, &dr->dev_opt))
			hcid_dbus_dev_up(dr->dev_id);
	}
failed:
	if (sk >= 0)
		close(sk);

	if (dl)
		free(dl);

}

static void reconnect_timer_start(void)
{
	struct sigaction sa;
	struct itimerval timer;

	memset (&sa, 0, sizeof (sa));
	sa.sa_handler = &reconnect_timer_handler;
	sigaction(SIGALRM, &sa, NULL);

	/* expire after X  msec... */
	timer.it_value.tv_sec = 0;
	timer.it_value.tv_usec = DBUS_RECONNECT_TIMER;

	/* ... and every x msec after that. */
	timer.it_interval.tv_sec = 0;
	timer.it_interval.tv_usec = DBUS_RECONNECT_TIMER;

	setitimer(ITIMER_REAL, &timer, NULL);
}

/*****************************************************************
 *  
 *  Section reserved to HCI D-Bus services 
 *  
 *****************************************************************/
static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data)
{
	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	const char *iface;
	const char *method;

	if (!msg || !conn)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_SIGNAL)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	iface = dbus_message_get_interface(msg);
	method = dbus_message_get_member(msg);

	if ((strcmp(iface, DBUS_INTERFACE_LOCAL) == 0) &&
			(strcmp(method, "Disconnected") == 0)) {
		syslog(LOG_ERR, "Got disconnected from the system message bus");
		dbus_connection_dispatch(conn);
		dbus_connection_close(conn);
		dbus_connection_unref(conn);
		reconnect_timer_start();
		ret = DBUS_HANDLER_RESULT_HANDLED;
	} else if (strcmp(iface, DBUS_INTERFACE_DBUS) == 0) {
		if (strcmp(method, "NameOwnerChanged") == 0)
			ret = DBUS_HANDLER_RESULT_HANDLED;
		else if (strcmp(method, "NameAcquired") == 0)
			ret = DBUS_HANDLER_RESULT_HANDLED;
	}

	return ret;
}

static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data)
{
	const struct service_data *handlers = NULL;
	DBusMessage *reply = NULL;
	struct hci_dbus_data *dbus_data = data;
	const char *method;
	const char *signature;
	const char *path;
	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD;
	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	path = dbus_message_get_path(msg);
	method = dbus_message_get_member(msg);
	signature = dbus_message_get_signature(msg);

	if (dbus_data->path_id == DEVICE_ROOT_ID) {
		/* Device is down(path unregistered) or the path is wrong */
		ret = DBUS_HANDLER_RESULT_HANDLED;
		error = BLUEZ_EDBUS_UNKNOWN_PATH;
		goto failed;
	}

	if (dbus_data->path_id == DEVICE_PATH_ID)
		handlers = device_services;
	else {
		struct profile_obj_path_data *profile;
		for (profile = obj_path_table; profile->id != INVALID_PATH_ID; profile++) {
			if (profile->id == dbus_data->path_id) {
				handlers = profile->get_svc_table();
				break;
			}
		}
	}

	if (!handlers)
		goto failed;

	for (; handlers->name != NULL; handlers++) {
		if (strcmp(handlers->name, method))
			continue;

		ret = DBUS_HANDLER_RESULT_HANDLED;

		if (!strcmp(handlers->signature, signature)) {
			reply = handlers->handler_func(msg, data);
			error = 0;
			break;
		} else {
			/* Set the error, but continue looping incase there is
			 * another method with the same name but a different
			 * signature */
			error = BLUEZ_EDBUS_WRONG_SIGNATURE;
			continue;
		}
	}

failed:
	if (error)
		reply = bluez_new_failure_msg(msg, error);

	if (reply) {
		if (!dbus_connection_send (conn, reply, NULL))
			syslog(LOG_ERR, "Can't send reply message!");
		dbus_message_unref(reply);
	}

	return ret;
}

static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data)
{
	const struct service_data *handlers;
	DBusMessage *reply = NULL;
	const char *iface;
	const char *method;
	const char *signature;
	const char *path;
	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD;
	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	path = dbus_message_get_path(msg);
	iface = dbus_message_get_interface(msg);
	method = dbus_message_get_member(msg);
	signature = dbus_message_get_signature(msg);

	if (strcmp(iface, MANAGER_INTERFACE) != 0)
		return ret;

	for (handlers = manager_services; handlers->name != NULL; handlers++) {
		if (strcmp(handlers->name, method))
			continue;

		if (strcmp(handlers->signature, signature) != 0)
			error = BLUEZ_EDBUS_WRONG_SIGNATURE;
		else {
			reply = handlers->handler_func(msg, data);
			error = 0;
		}

		ret = DBUS_HANDLER_RESULT_HANDLED;
	}

	if (error)
		reply = bluez_new_failure_msg(msg, error);

	if (reply) {
		if (!dbus_connection_send (conn, reply, NULL))
			syslog(LOG_ERR, "Can't send reply message!");
		dbus_message_unref(reply);
	}

	return ret;
}

static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data)
{
	periodic_inquiry_cp inq_param;
	struct hci_request rq;
	uint8_t status;
	DBusMessage *reply = NULL;
	struct hci_dbus_data *dbus_data = data;
	uint8_t length, num_rsp = 0;
	uint16_t max_period;
	uint16_t min_period;
	uint32_t lap = 0x9e8b33;
	int dd = -1;

	dd = hci_open_dev(dbus_data->dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "HCI device open failed");
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}

	if (dbus_message_has_signature(msg, HCI_PERIODIC_INQ_EXT_SIGNATURE))
		dbus_message_get_args(msg, NULL,
						DBUS_TYPE_BYTE, &length,
						DBUS_TYPE_UINT16, &min_period,
						DBUS_TYPE_UINT16, &max_period,
						DBUS_TYPE_UINT32, &lap,
						DBUS_TYPE_INVALID);
	else
		dbus_message_get_args(msg, NULL,
						DBUS_TYPE_BYTE, &length,
						DBUS_TYPE_UINT16, &min_period,
						DBUS_TYPE_UINT16, &max_period,
						DBUS_TYPE_INVALID);

	/* Check for valid parameters */
	if (length >= min_period || min_period >= max_period
					|| length < 0x01 || length > 0x30
					|| lap < 0x9e8b00 || lap > 0x9e8b3f) {
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
		goto failed;
	}

	inq_param.num_rsp = num_rsp;
	inq_param.length  = length;

	inq_param.max_period = htobs(max_period);
	inq_param.min_period = htobs(min_period);

	inq_param.lap[0] = lap & 0xff;
	inq_param.lap[1] = (lap >> 8) & 0xff;
	inq_param.lap[2] = (lap >> 16) & 0xff;

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_PERIODIC_INQUIRY;
	rq.cparam = &inq_param;
	rq.clen   = PERIODIC_INQUIRY_CP_SIZE;
	rq.rparam = &status;
	rq.rlen   = sizeof(status);

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Sending periodic inquiry command failed: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (status) {
		syslog(LOG_ERR, "Periodic inquiry failed with status 0x%02x", status);
		reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (dd >= 0)
		close(dd);

	return reply;
}

static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data)
{
	DBusMessage *reply = NULL;
	struct hci_request rq;
	struct hci_dbus_data *dbus_data = data;
	uint8_t status;
	int dd = -1;

	dd = hci_open_dev(dbus_data->dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "HCI device open failed");
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_EXIT_PERIODIC_INQUIRY;
	rq.rparam = &status;
	rq.rlen   = sizeof(status);

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Sending exit periodic inquiry command failed: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (status) {
		syslog(LOG_ERR, "Exit periodic inquiry failed with status 0x%02x", status);
		reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (dd >= 0)
		close(dd);

	return reply;
}

static DBusMessage* handle_inq_req(DBusMessage *msg, void *data)
{
	DBusMessage *reply = NULL;
	inquiry_cp cp;
	evt_cmd_status rp;
	struct hci_request rq;
	struct hci_dbus_data *dbus_data = data;
	int dd = -1;
	uint8_t length = 8, num_rsp = 0;
	uint32_t lap = 0x9e8b33;

	if (dbus_message_has_signature(msg, HCI_INQ_EXT_SIGNATURE)) {
		dbus_message_get_args(msg, NULL,
						DBUS_TYPE_BYTE, &length,
						DBUS_TYPE_UINT32, &lap,
						DBUS_TYPE_INVALID);

		if (length < 0x01 || length > 0x30
					|| lap < 0x9e8b00 || lap > 0x9e8b3f) {
			reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
			goto failed;
		}
	}

	dd = hci_open_dev(dbus_data->dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "Unable to open device %d: %s (%d)",
					dbus_data->dev_id, strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	memset(&cp, 0, sizeof(cp));
	cp.lap[0]  = lap & 0xff;
	cp.lap[1]  = (lap >> 8) & 0xff;
	cp.lap[2]  = (lap >> 16) & 0xff;
	cp.length  = length;
	cp.num_rsp = num_rsp;

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_INQUIRY;
	rq.cparam = &cp;
	rq.clen   = INQUIRY_CP_SIZE;
	rq.rparam = &rp;
	rq.rlen   = EVT_CMD_STATUS_SIZE;
	rq.event  = EVT_CMD_STATUS;

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Unable to start inquiry: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (dd >= 0)
		hci_close_dev(dd);

	return reply;
}

static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data)
{
	DBusMessage *reply = NULL;
	struct hci_request rq;
	struct hci_dbus_data *dbus_data = data;
	uint8_t status;
	int dd = -1;

	dd = hci_open_dev(dbus_data->dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "Unable to open device %d: %s (%d)",
					dbus_data->dev_id, strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_INQUIRY_CANCEL;
	rq.rparam = &status;
	rq.rlen   = sizeof(status);

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Sending cancel inquiry failed: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (status) {
		syslog(LOG_ERR, "Cancel inquiry failed with status 0x%02x", status);
		reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (dd >= 0)
		hci_close_dev(dd);

	return reply;
}

static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data)
{
	DBusMessage *reply = NULL;
	char *str_bdaddr = NULL;
	struct hci_dbus_data *dbus_data = data;
	bdaddr_t bdaddr;
	uint8_t role;
	int dev_id = -1, dd = -1;

	dbus_message_get_args(msg, NULL,
					DBUS_TYPE_STRING, &str_bdaddr,
					DBUS_TYPE_BYTE, &role,
					DBUS_TYPE_INVALID);

	str2ba(str_bdaddr, &bdaddr);

	dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);

	if (dev_id < 0) {
		syslog(LOG_ERR, "Bluetooth device failed");
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}

	if (dbus_data->dev_id != dev_id) {
		syslog(LOG_ERR, "Connection not found");
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND);
		goto failed;
	}

	dd = hci_open_dev(dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "HCI device open failed");
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}

	if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) {
		syslog(LOG_ERR, "Switch role request failed");
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	return reply;
}

static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data)
{
	DBusMessage *reply = NULL;
	struct hci_dbus_data *dbus_data = data;
	int dd = -1;
	const char *str_bdaddr;
	bdaddr_t bdaddr;
	struct hci_request rq;
	remote_name_req_cp cp;
	evt_cmd_status rp;

	dbus_message_get_args(msg, NULL,
					DBUS_TYPE_STRING, &str_bdaddr,
					DBUS_TYPE_INVALID);

	str2ba(str_bdaddr, &bdaddr);

	dd = hci_open_dev(dbus_data->dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "Unable to open device %d: %s (%d)",
					dbus_data->dev_id, strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	memset(&cp, 0, sizeof(cp));
	cp.bdaddr = bdaddr;
	cp.pscan_rep_mode = 0x01;

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_REMOTE_NAME_REQ;
	rq.cparam = &cp;
	rq.clen   = REMOTE_NAME_REQ_CP_SIZE;
	rq.rparam = &rp;
	rq.rlen   = EVT_CMD_STATUS_SIZE;
	rq.event  = EVT_CMD_STATUS;

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Unable to send remote name request: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (dd >= 0)
		hci_close_dev(dd);

	return reply;
}

static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data)
{
	struct hci_conn_list_req *cl = NULL;
	struct hci_conn_info *ci = NULL;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	DBusMessageIter  struct_iter;
	char addr[18];
	const char array_sig[] = HCI_CONN_INFO_STRUCT_SIGNATURE;
	const char *paddr = addr;
	struct hci_dbus_data *dbus_data = data;
	int sk = -1;
	int i;

	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (sk < 0) {
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	cl = malloc(MAX_CONN_NUMBER * sizeof(*ci) + sizeof(*cl));
	if (!cl) {
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM);
		goto failed;
	}

	cl->dev_id = dbus_data->dev_id;
	cl->conn_num = MAX_CONN_NUMBER;
	ci = cl->conn_info;

	if (ioctl(sk, HCIGETCONNLIST, (void *) cl) < 0) {
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);
	if (reply == NULL) {
		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return");
		goto failed;
	}

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter);

	for (i = 0; i < cl->conn_num; i++, ci++) {
		ba2str(&ci->bdaddr, addr);

		dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter);
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 ,&(ci->handle));
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING ,&paddr);
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE ,&(ci->type));
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE ,&(ci->out));
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 ,&(ci->state));
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32 ,&(ci->link_mode));
		dbus_message_iter_close_container(&array_iter, &struct_iter);
	}

	dbus_message_iter_close_container(&iter, &array_iter);

failed:
	if (sk >= 0)
		close(sk);

	if (cl)
		free(cl);

	return reply;
}

static DBusMessage* handle_auth_req(DBusMessage *msg, void *data)
{
	struct hci_request rq;
	auth_requested_cp cp;
	evt_cmd_status rp;
	DBusMessage *reply = NULL;
	char *str_bdaddr = NULL;
	struct hci_dbus_data *dbus_data = data;
	struct hci_conn_info_req *cr = NULL;
	bdaddr_t bdaddr;
	int dev_id = -1;
	int dd = -1;

	dbus_message_get_args(msg, NULL,
					DBUS_TYPE_STRING, &str_bdaddr,
					DBUS_TYPE_INVALID);

	str2ba(str_bdaddr, &bdaddr);

	dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);

	if (dev_id < 0) {
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND);
		goto failed;
	}

	if (dbus_data->dev_id != dev_id) {
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND);
		goto failed;
	}

	dd = hci_open_dev(dev_id);
	if (dd < 0) {
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}

	cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
	if (!cr) {
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM);
		goto failed;
	}

	bacpy(&cr->bdaddr, &bdaddr);
	cr->type = ACL_LINK;

	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	memset(&cp, 0, sizeof(cp));
	cp.handle = cr->conn_info->handle;

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_AUTH_REQUESTED;
	rq.cparam = &cp;
	rq.clen   = AUTH_REQUESTED_CP_SIZE;
	rq.rparam = &rp;
	rq.rlen   = EVT_CMD_STATUS_SIZE;
	rq.event  = EVT_CMD_STATUS;

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Unable to send authentication request: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (dd >= 0)
		close(dd);

	if (cr)
		free(cr);

	return reply;
}

/*****************************************************************
 *  
 *  Section reserved to local device configuration D-Bus Services
 *  
 *****************************************************************/
static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data)
{
	DBusMessage *reply = NULL;
	struct hci_dbus_data *dbus_data = data;
	struct hci_dev_info di;
	struct hci_dev_req dr;
	int sk = -1;

	/* Create and bind HCI socket */
	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (sk < 0) {
		syslog(LOG_ERR, "Can't open HCI socket: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (ioctl(sk, HCIDEVUP, dbus_data->dev_id) < 0 && errno != EALREADY) {
		syslog(LOG_ERR, "Can't init device hci%d: %s (%d)",
					dbus_data->dev_id, strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (ioctl(sk, HCIGETDEVINFO, (void *) &di) >= 0 &&
					!hci_test_bit(HCI_RAW, &di.flags)) {
		dr.dev_id  = dbus_data->dev_id;
		dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; /* piscan */
		if (ioctl(sk, HCISETSCAN, (unsigned long) &dr) < 0) {
			syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)",
					dbus_data->dev_id, strerror(errno), errno);
			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
			goto failed;
		}
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (sk >= 0)
		close(sk);

	return reply;
}

static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data)
{
	DBusMessage *reply = NULL;
	struct hci_dbus_data *dbus_data = data;
	int sk = -1;

	/* Create and bind HCI socket */
	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (sk < 0) {
		syslog(LOG_ERR, "Can't open HCI socket: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (ioctl(sk, HCIDEVDOWN, dbus_data->dev_id) < 0) {
		syslog(LOG_ERR, "Can't down device hci%d: %s (%d)",
					dbus_data->dev_id, strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (sk >= 0)
		close(sk);

	return reply;
}

static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data)
{
	const struct service_data *handlers = set_property_services;
	DBusMessageIter iter;
	DBusMessage *reply = NULL;
	const char *signature;
	char *str_name;
	uint32_t error = BLUEZ_EDBUS_WRONG_PARAM;

	signature = dbus_message_get_signature(msg);

	dbus_message_iter_init(msg, &iter);
	dbus_message_iter_get_basic(&iter, &str_name);

	for (; handlers->name != NULL; handlers++) {
		if (strcasecmp(handlers->name, str_name))
			continue;

		if (strcmp(handlers->signature, signature) == 0) {
			reply = handlers->handler_func(msg, data);
			error = 0;
			break;
		} else {
			error = BLUEZ_EDBUS_WRONG_SIGNATURE;
			break;
		}
	}

	if (error)
		reply = bluez_new_failure_msg(msg, error);

	return reply;
}

static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data)
{
	const struct service_data *handlers = get_property_services;
	DBusMessageIter iter;
	DBusMessage *reply = NULL;
	char *str_name;
	uint32_t error = BLUEZ_EDBUS_WRONG_PARAM;


	dbus_message_iter_init(msg, &iter);
	dbus_message_iter_get_basic(&iter, &str_name);

	for (; handlers->name != NULL; handlers++) {
		if (!strcasecmp(handlers->name, str_name)) {
			reply = handlers->handler_func(msg, data);
			error = 0;
			break;
		}
	}

	if (error)
		reply = bluez_new_failure_msg(msg, error);

	return reply;
}

static DBusMessage* handle_device_set_propety_req_name(DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	DBusMessageIter iter;
	DBusMessage *reply = NULL;
	char *str_name;
	int dd = -1;
	uint8_t status;
	change_local_name_cp cp;
	struct hci_request rq;

	dbus_message_iter_init(msg, &iter);
	dbus_message_iter_next(&iter);
	dbus_message_iter_get_basic(&iter, &str_name);

	if(strlen(str_name) == 0) {
		syslog(LOG_ERR, "HCI change name failed - Invalid Name!");
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
		goto failed;
	}

	dd = hci_open_dev(dbus_data->dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}

	memset(&rq, 0, sizeof(rq));
	strncpy((char *) cp.name, str_name, sizeof(cp.name));
	rq.ogf    = OGF_HOST_CTL;
	rq.ocf    = OCF_CHANGE_LOCAL_NAME;
	rq.cparam = &cp;
	rq.clen   = CHANGE_LOCAL_NAME_CP_SIZE;
	rq.rparam = &status;
	rq.rlen   = sizeof(status);

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Sending change name command failed: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (status) {
		syslog(LOG_ERR, "Setting name failed with status 0x%02x", status);
		reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);

failed:
	if (dd >= 0)
		close(dd);

	return reply;
}

void hcid_dbus_setname_complete(bdaddr_t *local)
{
	DBusMessage *message = NULL;
	char path[MAX_PATH_LENGTH];
	char *local_addr;
	bdaddr_t tmp;
	int id;
	int dd = -1;
	read_local_name_rp rp;
	struct hci_request rq;
	const char *pname = (char*) rp.name;
	char name[249];

	baswap(&tmp, local); local_addr = batostr(&tmp);

	id = hci_devid(local_addr);
	if (id < 0) {
		syslog(LOG_ERR, "No matching device id for %s", local_addr);
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);

	message = dbus_message_new_signal(path, DEVICE_INTERFACE,
						BLUEZ_HCI_SET_NAME);
	if (message == NULL) {
		syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message");
		goto failed;
	}

	dd = hci_open_dev(id);
	memset(&rq, 0, sizeof(rq));
	if (dd < 0) {
		syslog(LOG_ERR, "HCI device open failed: hci%d", id);
	} else {
		rq.ogf    = OGF_HOST_CTL;
		rq.ocf    = OCF_READ_LOCAL_NAME;
		rq.rparam = &rp;
		rq.rlen   = READ_LOCAL_NAME_RP_SIZE;
		if (hci_send_req(dd, &rq, 100) < 0) {
			syslog(LOG_ERR,
				"Sending getting name command failed: %s (%d)",
				strerror(errno), errno);
			rp.name[0] = '\0';
		}
		if (rp.status) {
			syslog(LOG_ERR,
				"Getting name failed with status 0x%02x",
				rp.status);
			rp.name[0] = '\0';
		}
	}

	strncpy(name,pname,sizeof(name)-1);
	name[248]='\0';
	pname = name;

	dbus_message_append_args(message,
				DBUS_TYPE_STRING, &pname,
				DBUS_TYPE_INVALID);

	if (dbus_connection_send(connection, message, NULL) == FALSE) {
		syslog(LOG_ERR, "Can't send D-BUS NameChanged signal");
		goto failed;
	}
	dbus_connection_flush(connection);

failed:
	if (dd >= 0)
		close(dd);
	dbus_message_unref(message);
	bt_free(local_addr);
}

static DBusMessage* handle_device_get_propety_req_name(DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	DBusMessage *reply = NULL;
	int dd = -1;
	read_local_name_rp rp;
	struct hci_request rq;
	const char *pname = (char*) rp.name;
	char name[249];

	dd = hci_open_dev(dbus_data->dev_id);
	if (dd < 0) {
		syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}
	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_HOST_CTL;
	rq.ocf    = OCF_READ_LOCAL_NAME;
	rq.rparam = &rp;
	rq.rlen   = READ_LOCAL_NAME_RP_SIZE;

	if (hci_send_req(dd, &rq, 100) < 0) {
		syslog(LOG_ERR, "Sending getting name command failed: %s (%d)",
							strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	if (rp.status) {
		syslog(LOG_ERR, "Getting name failed with status 0x%02x", rp.status);
		reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);
	if (reply == NULL) {
		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return");
		goto failed;
	}

	strncpy(name,pname,sizeof(name)-1);
	name[248]='\0';
	pname = name;

	dbus_message_append_args(reply,
				DBUS_TYPE_STRING, &pname,
				DBUS_TYPE_INVALID);

failed:
	if (dd >= 0)
		close(dd);

	return reply;
}

static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data)
{
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	DBusMessage *reply = NULL;
	struct hci_dev_list_req *dl = NULL;
	struct hci_dev_req *dr      = NULL;
	int sk = -1;
	int i;
	const char array_sig[] = MGR_GET_DEV_REPLY_STRUCT_SIGNATURE;

	/* Create and bind HCI socket */
	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (sk < 0) {
		syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno);
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));
	if (!dl) {
		syslog(LOG_ERR, "Can't allocate memory");
		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM);
		goto failed;
	}

	dl->dev_num = HCI_MAX_DEV;
	dr = dl->dev_req;

	if (ioctl(sk, HCIGETDEVLIST, dl) < 0) {
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
		goto failed;
	}

	/* active bluetooth adapter found */
	reply = dbus_message_new_method_return(msg);
	if (reply == NULL) {
		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return");
		goto failed;
	}

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter);
	dr = dl->dev_req;

	for (i = 0; i < dl->dev_num; i++, dr++) {
		char apath[MAX_PATH_LENGTH];
		char aaddr[18];
		char *paddr = aaddr;
		char *ppath = apath;
		char *ptype;
		const char *flag;
		DBusMessageIter flag_array_iter, struct_iter;
		struct hci_dev_info di;
		hci_map *mp;

		mp = dev_flags_map;
		memset(&di, 0 , sizeof(struct hci_dev_info));
		di.dev_id = dr->dev_id;

		if (ioctl(sk, HCIGETDEVINFO, &di) < 0)
			continue;

		snprintf(apath, sizeof(apath), "%s/%s", DEVICE_PATH, di.name);

		ba2str(&di.bdaddr, aaddr);
		ptype = hci_dtypetostr(di.type);

		dbus_message_iter_open_container(&array_iter,
				DBUS_TYPE_STRUCT, NULL, &struct_iter);

		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &ppath);
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &paddr);
		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &ptype);

		if (hci_test_bit(HCI_UP, &dr->dev_opt))
			flag = "UP";
		else
			flag = "DOWN";

		dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &flag);

		dbus_message_iter_open_container(&struct_iter,
					DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &flag_array_iter);

		while (mp->str) {
			if (hci_test_bit(mp->val, &dr->dev_opt))
				dbus_message_iter_append_basic(&flag_array_iter, DBUS_TYPE_STRING, &mp->str);
			mp++;
		}
		dbus_message_iter_close_container(&struct_iter, &flag_array_iter);
		dbus_message_iter_close_container(&array_iter, &struct_iter);
	}

	dbus_message_iter_close_container(&iter, &array_iter);

failed:
	if (sk >= 0)
		close(sk);

	if (dl)
		free(dl);

	return reply;
}

/*****************************************************************
 *  
 *  Section reserved to Manager D-Bus services
 *  
 *****************************************************************/
static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data) {
	char path[MAX_PATH_LENGTH];
	char *pptr = path;
	DBusMessage *reply = NULL;

	if (default_dev < 0) {
		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
		goto failed;
	}

	reply = dbus_message_new_method_return(msg);
	if (reply == NULL) {
		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return");
		goto failed;
	}

	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, default_dev);
	dbus_message_append_args(reply,
					DBUS_TYPE_STRING, &pptr,
					DBUS_TYPE_INVALID);

failed:
	return reply;
}

static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data) 
{
	const char *path = dbus_message_get_path(msg);
	const char *iface = dbus_message_get_interface(msg);
	const char *method = dbus_message_get_member(msg);

	syslog(LOG_INFO, "Not Implemented - path %s iface %s method %s",
							path, iface, method);

	return NULL;
}
