示例#1
0
struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
{
	struct avctp *session;
	GError *err = NULL;
	GIOChannel *io;

	session = avctp_get_internal(src, dst);
	if (!session)
		return NULL;

	if (session->state > AVCTP_STATE_DISCONNECTED)
		return session;

	avctp_set_state(session, AVCTP_STATE_CONNECTING);

	io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, session, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
				BT_IO_OPT_DEST_BDADDR, &session->dst,
				BT_IO_OPT_PSM, AVCTP_PSM,
				BT_IO_OPT_INVALID);
	if (err) {
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
		error("%s", err->message);
		g_error_free(err);
		return NULL;
	}

	session->io = io;

	return session;
}
示例#2
0
struct avctp *avctp_connect(struct audio_device *device)
{
	struct avctp *session;
	GError *err = NULL;
	GIOChannel *io;

	session = avctp_get_internal(device->btd_dev);
	if (!session)
		return NULL;

	if (session->state > AVCTP_STATE_DISCONNECTED)
		return session;

	avctp_set_state(session, AVCTP_STATE_CONNECTING);

	io = bt_io_connect(avctp_connect_cb, session, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR,
				adapter_get_address(session->server->adapter),
				BT_IO_OPT_DEST_BDADDR,
				device_get_address(session->device),
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
				BT_IO_OPT_INVALID);
	if (err) {
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
		error("%s", err->message);
		g_error_free(err);
		return NULL;
	}

	session->control = avctp_channel_create(session, io, NULL);
	g_io_channel_unref(io);

	return session;
}
示例#3
0
static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
{
	struct avctp *session;
	struct audio_device *dev;
	char address[18];
	bdaddr_t src, dst;
	GError *err = NULL;
	uint16_t psm;
	struct btd_device *device;

	bt_io_get(chan, &err,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST, address,
			BT_IO_OPT_PSM, &psm,
			BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		g_io_channel_shutdown(chan, TRUE, NULL);
		return;
	}

	DBG("AVCTP: incoming connect from %s", address);

	device = adapter_find_device(adapter_find(&src), &dst);
	if (!device)
		return;

	session = avctp_get_internal(device);
	if (session == NULL)
		return;

	dev = manager_get_audio_device(device, TRUE);
	if (!dev) {
		error("Unable to get audio device object for %s", address);
		goto drop;
	}

	if (dev->control == NULL) {
		btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID);
		if (dev->control == NULL)
			goto drop;
	}

	switch (psm) {
	case AVCTP_CONTROL_PSM:
		avctp_control_confirm(session, chan, dev);
		break;
	case AVCTP_BROWSING_PSM:
		avctp_browsing_confirm(session, chan, dev);
		break;
	}

	return;

drop:
	if (psm == AVCTP_CONTROL_PSM)
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
}
示例#4
0
文件: avctp.c 项目: ghent360/bluez
static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
{
	struct avctp *session;
	char address[18];
	bdaddr_t src, dst;
	GError *err = NULL;
	uint16_t psm;
	struct btd_device *device;

	bt_io_get(chan, &err,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST, address,
			BT_IO_OPT_PSM, &psm,
			BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		g_io_channel_shutdown(chan, TRUE, NULL);
		return;
	}

	DBG("AVCTP: incoming connect from %s", address);

	device = btd_adapter_find_device(adapter_find(&src), &dst,
								BDADDR_BREDR);
	if (!device)
		return;

	session = avctp_get_internal(device);
	if (session == NULL)
		return;

	if (btd_device_get_service(device, AVRCP_REMOTE_UUID) == NULL)
		btd_device_add_uuid(device, AVRCP_REMOTE_UUID);

	if (btd_device_get_service(device, AVRCP_TARGET_UUID) == NULL)
		btd_device_add_uuid(device, AVRCP_TARGET_UUID);

	switch (psm) {
	case AVCTP_CONTROL_PSM:
		avctp_control_confirm(session, chan, device);
		break;
	case AVCTP_BROWSING_PSM:
		avctp_browsing_confirm(session, chan, device);
		break;
	}

	return;
}
示例#5
0
文件: avctp.c 项目: MDomagala/bluez
struct avctp *avctp_get(struct btd_device *device)
{
	return avctp_get_internal(device);
}
示例#6
0
static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
{
	struct avctp *session;
	struct audio_device *dev;
	char address[18];
	bdaddr_t src, dst;
	GError *err = NULL;

	bt_io_get(chan, BT_IO_L2CAP, &err,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST, address,
			BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		g_io_channel_shutdown(chan, TRUE, NULL);
		return;
	}

	DBG("AVCTP: incoming connect from %s", address);

	session = avctp_get_internal(&src, &dst);
	if (!session)
		goto drop;

	dev = manager_get_device(&src, &dst, FALSE);
	if (!dev) {
		dev = manager_get_device(&src, &dst, TRUE);
		if (!dev) {
			error("Unable to get audio device object for %s",
					address);
			goto drop;
		}
	}

	if (dev->control == NULL) {
		btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID);
		if (dev->control == NULL)
			goto drop;
	}

	if (session->io) {
		/* AVCTP collision fix. (Collision was found with Sony headset DR-BT30Q). */
		DBG("Canceling outgoing and accepting incoming connection from %s", address);
		avctp_disconnected(session);
	       session = avctp_get_internal(&src, &dst);
	       if (!session)
			goto drop;
	}

	avctp_set_state(session, AVCTP_STATE_CONNECTING);
	session->io = g_io_channel_ref(chan);

	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
						auth_cb, session) < 0)
		goto drop;

	session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
							session_cb, session);
	return;

drop:
	if (!session || !session->io)
		g_io_channel_shutdown(chan, TRUE, NULL);
	if (session)
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
}
示例#7
0
struct avctp *avctp_get(const bdaddr_t *src, const bdaddr_t *dst)
{
	return avctp_get_internal(src, dst);
}
示例#8
0
struct avctp *avctp_get(struct audio_device *device)
{
	return avctp_get_internal(device->btd_dev);
}