struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
{
	struct btd_gatt_database *database;
	GError *gerr = NULL;
	const bdaddr_t *addr;

	if (!adapter)
		return NULL;

	database = new0(struct btd_gatt_database, 1);
	database->adapter = btd_adapter_ref(adapter);
	database->db = gatt_db_new();
	database->records = queue_new();
	database->device_states = queue_new();
	database->apps = queue_new();
	database->profiles = queue_new();
	database->ccc_callbacks = queue_new();

	addr = btd_adapter_get_address(adapter);
	database->le_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_SOURCE_TYPE,
					btd_adapter_get_address_type(adapter),
					BT_IO_OPT_CID, BT_ATT_CID,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
	if (!database->le_io) {
		error("Failed to start listening: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	/* If just just 1 channel is enabled EATT is not required */
	if (btd_opts.gatt_channels == 1)
		goto bredr;

	/* EATT socket */
	database->eatt_io = bt_io_listen(connect_cb, NULL, NULL, NULL,
					&gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_SOURCE_TYPE,
					btd_adapter_get_address_type(adapter),
					BT_IO_OPT_PSM, BT_ATT_EATT_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_MTU, btd_opts.gatt_mtu,
					BT_IO_OPT_INVALID);
	if (!database->eatt_io) {
		g_error_free(gerr);
		goto fail;
	}

bredr:
	/* BR/EDR socket */
	database->bredr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_PSM, BT_ATT_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_MTU, btd_opts.gatt_mtu,
					BT_IO_OPT_INVALID);
	if (database->bredr_io == NULL) {
		error("Failed to start listening: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	if (g_dbus_register_interface(btd_get_dbus_connection(),
						adapter_get_path(adapter),
						GATT_MANAGER_IFACE,
						manager_methods, NULL, NULL,
						database, NULL))
		DBG("GATT Manager registered for adapter: %s",
						adapter_get_path(adapter));

	register_core_services(database);

	database->db_id = gatt_db_register(database->db, gatt_db_service_added,
							gatt_db_service_removed,
							database, NULL);
	if (!database->db_id)
		goto fail;

	return database;

fail:
	gatt_database_free(database);

	return NULL;
}
struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
{
	struct btd_gatt_database *database;
	GError *gerr = NULL;
	const bdaddr_t *addr;

	if (!adapter)
		return NULL;

	database = new0(struct btd_gatt_database, 1);
	database->adapter = btd_adapter_ref(adapter);
	database->db = gatt_db_new();
	database->records = queue_new();
	database->device_states = queue_new();
	database->apps = queue_new();
	database->profiles = queue_new();
	database->ccc_callbacks = queue_new();

	addr = btd_adapter_get_address(adapter);
	database->le_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_SOURCE_TYPE,
					btd_adapter_get_address_type(adapter),
					BT_IO_OPT_CID, BT_ATT_CID,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
	if (!database->le_io) {
		error("Failed to start listening: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	 
	if (btd_opts.gatt_channels == 1)
		goto bredr;

	 
	database->eatt_io = bt_io_listen(connect_cb, NULL, NULL, NULL,
					&gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_SOURCE_TYPE,
					btd_adapter_get_address_type(adapter),
					BT_IO_OPT_PSM, BT_ATT_EATT_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_MTU, btd_opts.gatt_mtu,
					BT_IO_OPT_INVALID);
	if (!database->eatt_io) {
		g_error_free(gerr);
		goto fail;
	}

bredr:
	 
	database->bredr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_PSM, BT_ATT_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_MTU, btd_opts.gatt_mtu,
					BT_IO_OPT_INVALID);
	if (database->bredr_io == NULL) {
		error("Failed to start listening: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	if (g_dbus_register_interface(btd_get_dbus_connection(),
						adapter_get_path(adapter),
						GATT_MANAGER_IFACE,
						manager_methods, NULL, NULL,
						database, NULL))
		DBG("GATT Manager registered for adapter: %s",
						adapter_get_path(adapter));

	register_core_services(database);

	database->db_id = gatt_db_register(database->db, gatt_db_service_added,
							gatt_db_service_removed,
							database, NULL);
	if (!database->db_id)
		goto fail;

	return database;

fail:
	gatt_database_free(database);

	return NULL;
}