コード例 #1
0
ファイル: avctp.c プロジェクト: richardxu/panda-a4
void avctp_unregister(const bdaddr_t *src)
{
	struct avctp_server *server;

	server = find_server(servers, src);
	if (!server)
		return;

	while (server->sessions)
		avctp_disconnected(server->sessions->data);

	servers = g_slist_remove(servers, server);

	g_io_channel_shutdown(server->io, TRUE, NULL);
	g_io_channel_unref(server->io);
	g_free(server);

	if (servers)
		return;

	if (passthrough_id) {
		avctp_unregister_pdu_handler(passthrough_id);
		passthrough_id = 0;
	}

	if (unit_id) {
		avctp_unregister_pdu_handler(unit_id);
		passthrough_id = 0;
	}

	if (subunit_id) {
		avctp_unregister_pdu_handler(subunit_id);
		subunit_id = 0;
	}
}
コード例 #2
0
ファイル: control.c プロジェクト: LittoCats/OT_4010D
static void avctp_set_state(struct control *control, avctp_state_t new_state)
{
	GSList *l;
	struct audio_device *dev = control->dev;
	avdtp_session_state_t old_state = control->state;
	gboolean value;

	switch (new_state) {
	case AVCTP_STATE_DISCONNECTED:
		DBG("AVCTP Disconnected");

		avctp_disconnected(control->dev);

		if (old_state != AVCTP_STATE_CONNECTED)
			break;

		value = FALSE;
		g_dbus_emit_signal(dev->conn, dev->path,
					AUDIO_CONTROL_INTERFACE,
					"Disconnected", DBUS_TYPE_INVALID);
		emit_property_changed(dev->conn, dev->path,
					AUDIO_CONTROL_INTERFACE, "Connected",
					DBUS_TYPE_BOOLEAN, &value);

		if (!audio_device_is_active(dev, NULL))
			audio_device_set_authorized(dev, FALSE);

		break;
	case AVCTP_STATE_CONNECTING:
		DBG("AVCTP Connecting");
		break;
	case AVCTP_STATE_CONNECTED:
		DBG("AVCTP Connected");
		value = TRUE;
		g_dbus_emit_signal(control->dev->conn, control->dev->path,
				AUDIO_CONTROL_INTERFACE, "Connected",
				DBUS_TYPE_INVALID);
		emit_property_changed(control->dev->conn, control->dev->path,
				AUDIO_CONTROL_INTERFACE, "Connected",
				DBUS_TYPE_BOOLEAN, &value);
		break;
	default:
		error("Invalid AVCTP state %d", new_state);
		return;
	}

	control->state = new_state;

	for (l = avctp_callbacks; l != NULL; l = l->next) {
		struct avctp_state_callback *cb = l->data;
		cb->cb(control->dev, old_state, new_state, cb->user_data);
	}
}
コード例 #3
0
ファイル: control.c プロジェクト: LittoCats/OT_4010D
static void path_unregister(void *data)
{
	struct audio_device *dev = data;
	struct control *control = dev->control;

	DBG("Unregistered interface %s on path %s",
		AUDIO_CONTROL_INTERFACE, dev->path);

	if (control->state != AVCTP_STATE_DISCONNECTED)
		avctp_disconnected(dev);

	g_free(control);
	dev->control = NULL;
}
コード例 #4
0
ファイル: avctp.c プロジェクト: richardxu/panda-a4
static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
{
	GSList *l;
	struct audio_device *dev;
	avctp_state_t old_state = session->state;

	dev = manager_get_device(&session->server->src, &session->dst, FALSE);
	if (dev == NULL) {
		error("avdtp_set_state(): no matching audio device");
		return;
	}

	session->state = new_state;

	for (l = callbacks; l != NULL; l = l->next) {
		struct avctp_state_callback *cb = l->data;
		cb->cb(dev, old_state, new_state, cb->user_data);
	}

	switch (new_state) {
	case AVCTP_STATE_DISCONNECTED:
		DBG("AVCTP Disconnected");

		avctp_disconnected(session);

		if (old_state != AVCTP_STATE_CONNECTED)
			break;

		if (!audio_device_is_active(dev, NULL))
			audio_device_set_authorized(dev, FALSE);

		break;
	case AVCTP_STATE_CONNECTING:
		DBG("AVCTP Connecting");
		break;
	case AVCTP_STATE_CONNECTED:
		DBG("AVCTP Connected");
		break;
	default:
		error("Invalid AVCTP state %d", new_state);
		return;
	}
}
コード例 #5
0
ファイル: avctp.c プロジェクト: adityakamath/ArduHack
static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
{
	GSList *l;
	struct audio_device *dev;
	avctp_state_t old_state = session->state;

	dev = manager_get_audio_device(session->device, FALSE);
	if (dev == NULL) {
		error("%s(): No matching audio device", __func__);
		return;
	}

	session->state = new_state;

	for (l = callbacks; l != NULL; l = l->next) {
		struct avctp_state_callback *cb = l->data;
		cb->cb(dev, old_state, new_state, cb->user_data);
	}

	switch (new_state) {
	case AVCTP_STATE_DISCONNECTED:
		DBG("AVCTP Disconnected");
		avctp_disconnected(session);
		break;
	case AVCTP_STATE_CONNECTING:
		DBG("AVCTP Connecting");
		break;
	case AVCTP_STATE_CONNECTED:
		DBG("AVCTP Connected");
		break;
	case AVCTP_STATE_BROWSING_CONNECTING:
		DBG("AVCTP Browsing Connecting");
		break;
	case AVCTP_STATE_BROWSING_CONNECTED:
		DBG("AVCTP Browsing Connected");
		break;
	default:
		error("Invalid AVCTP state %d", new_state);
		return;
	}
}
コード例 #6
0
ファイル: avctp.c プロジェクト: ghent360/bluez
static void avctp_set_state(struct avctp *session, avctp_state_t new_state,
									int err)
{
	GSList *l;
	avctp_state_t old_state = session->state;

	session->state = new_state;

	for (l = callbacks; l != NULL; l = l->next) {
		struct avctp_state_callback *cb = l->data;

		if (cb->dev && cb->dev != session->device)
			continue;

		cb->cb(session->device, old_state, new_state, err,
								cb->user_data);
	}

	switch (new_state) {
	case AVCTP_STATE_DISCONNECTED:
		DBG("AVCTP Disconnected");
		avctp_disconnected(session);
		break;
	case AVCTP_STATE_CONNECTING:
		DBG("AVCTP Connecting");
		break;
	case AVCTP_STATE_CONNECTED:
		DBG("AVCTP Connected");
		break;
	case AVCTP_STATE_BROWSING_CONNECTING:
		DBG("AVCTP Browsing Connecting");
		break;
	case AVCTP_STATE_BROWSING_CONNECTED:
		DBG("AVCTP Browsing Connected");
		break;
	default:
		error("Invalid AVCTP state %d", new_state);
		return;
	}
}
コード例 #7
0
ファイル: avctp.c プロジェクト: MDomagala/bluez
void avctp_unregister(struct btd_adapter *adapter)
{
	struct avctp_server *server;

	server = find_server(servers, adapter);
	if (!server)
		return;

	while (server->sessions)
		avctp_disconnected(server->sessions->data);

	servers = g_slist_remove(servers, server);

	g_io_channel_shutdown(server->browsing_io, TRUE, NULL);
	g_io_channel_unref(server->browsing_io);
	server->browsing_io = NULL;

	g_io_channel_shutdown(server->control_io, TRUE, NULL);
	g_io_channel_unref(server->control_io);
	btd_adapter_unref(server->adapter);
	g_free(server);
}
コード例 #8
0
ファイル: avctp.c プロジェクト: richardxu/panda-a4
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);
}