示例#1
0
static DBusMessage *sink_connect(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct audio_device *dev = data;
	struct sink *sink = dev->sink;
	struct pending_request *pending;

	if (!sink->session)
		sink->session = avdtp_get(&dev->src, &dev->dst);

	if (!sink->session)
		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
						"Unable to get a session");

	if (sink->connect || sink->disconnect)
		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
						"%s", strerror(EBUSY));

	if (sink->state >= AVDTP_STATE_OPEN)
		return g_dbus_create_error(msg, ERROR_INTERFACE
						".AlreadyConnected",
						"Device Already Connected");

	pending = g_new0(struct pending_request, 1);
	pending->conn = dbus_connection_ref(conn);
	pending->msg = dbus_message_ref(msg);
	sink->connect = pending;

	avdtp_discover(sink->session, discovery_complete, sink);

	debug("stream creation in progress");

	return NULL;
}
示例#2
0
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
	uint16_t imtu, omtu;
	GError *gerr = NULL;
	int fd;

	if (err) {
		printf("%s\n", err->message);
		g_main_loop_quit(mainloop);
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_IMTU, &imtu,
			BT_IO_OPT_OMTU, &omtu,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_INVALID);
	if (gerr) {
		printf("%s\n", gerr->message);
		g_main_loop_quit(mainloop);
		return;
	}

	printf("Connected (imtu=%d omtu=%d)\n", imtu, omtu);

	fd = g_io_channel_unix_get_fd(chan);

	if (avdtp && avdtp_stream) {
		if (!avdtp_stream_set_transport(avdtp_stream, fd, imtu, omtu)) {
			printf("avdtp_stream_set_transport: failed\n");
			g_main_loop_quit(mainloop);
		}

		g_io_channel_set_close_on_unref(chan, FALSE);

		send_command();

		return;
	}

	avdtp = avdtp_new(fd, imtu, omtu, version);
	if (!avdtp) {
		printf("Failed to create avdtp instance\n");
		g_main_loop_quit(mainloop);
		return;
	}

	avdtp_add_disconnect_cb(avdtp, disconnect_cb, NULL);

	if (preconf) {
		int ret;

		ret = avdtp_discover(avdtp, discover_cb, NULL);
		if (ret < 0) {
			printf("avdtp_discover failed: %s", strerror(-ret));
			g_main_loop_quit(mainloop);
		}
	}
}
示例#3
0
文件: a2dp.c 项目: BirdAndEarth/RPi
static void signaling_connect_cb(GIOChannel *chan, GError *err,
							gpointer user_data)
{
	struct a2dp_device *dev = user_data;
	uint16_t imtu, omtu;
	GError *gerr = NULL;
	int fd;

	if (err) {
		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
		error("%s", err->message);
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_IMTU, &imtu,
			BT_IO_OPT_OMTU, &omtu,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("%s", gerr->message);
		g_error_free(gerr);
		goto failed;
	}

	fd = g_io_channel_unix_get_fd(chan);

	/* FIXME: Add proper version */
	dev->session = avdtp_new(fd, imtu, omtu, 0x0100);
	if (!dev->session)
		goto failed;

	avdtp_add_disconnect_cb(dev->session, disconnect_cb, dev);

	/* Proceed to stream setup if initiator */
	if (dev->io) {
		int perr;

		g_io_channel_unref(dev->io);
		dev->io = NULL;

		perr = avdtp_discover(dev->session, discover_cb, dev);
		if (perr < 0) {
			error("avdtp_discover: %s", strerror(-perr));
			goto failed;
		}
		bt_avrcp_connect(&dev->dst);
	} else /* Init idle timeout to discover */
		dev->idle_id = g_timeout_add_seconds(IDLE_TIMEOUT, idle_timeout,
									dev);

	return;

failed:
	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
}
示例#4
0
int main(int argc, char *argv[])
{
	bdaddr_t src, dst;
	int opt, sk, dev_id;

	if (argc < 2) {
		usage();
		exit(0);
	}

	bacpy(&src, BDADDR_ANY);
	dev_id = hci_get_route(&src);
	if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) {
		printf("Cannot find any local adapter\n");
		exit(-1);
	}

	while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
		switch (opt) {
		case 'i':
			if (!strncmp(optarg, "hci", 3))
				hci_devba(atoi(optarg + 3), &src);
			else
				str2ba(optarg, &src);
			break;

		case 'h':
		default:
			usage();
			exit(0);
		}
	}

	printf("Connecting ... \n");

	if (bachk(argv[optind]) < 0) {
		printf("Invalid argument\n");
		exit(1);
	}

	str2ba(argv[optind], &dst);
	sk = l2cap_connect(&src, &dst);
	if (sk < 0)
		exit(1);

	if (avdtp_discover(sk) < 0)
		exit(1);

	return 0;
}
示例#5
0
文件: a2dp.c 项目: BirdAndEarth/RPi
static gboolean idle_timeout(gpointer user_data)
{
	struct a2dp_device *dev = user_data;
	int err;

	dev->idle_id = 0;

	err = avdtp_discover(dev->session, discover_cb, dev);
	if (err == 0)
		return FALSE;

	error("avdtp_discover: %s", strerror(-err));
	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);

	return FALSE;
}
示例#6
0
gboolean source_setup_stream(struct source *source, struct avdtp *session)
{
	if (source->connect_id > 0 || source->disconnect_id > 0)
		return FALSE;

	if (session && !source->session)
		source->session = avdtp_ref(session);

	if (!source->session)
		return FALSE;

	if (avdtp_discover(source->session, discovery_complete, source) < 0)
		return FALSE;

	return TRUE;
}
示例#7
0
文件: sink.c 项目: Thread974/bz
gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
{
	if (sink->connect_id > 0 || sink->disconnect_id > 0)
		return FALSE;

	if (session && !sink->session)
		sink->session = avdtp_ref(session);

	if (!sink->session)
		return FALSE;

	if (avdtp_discover(sink->session, discovery_complete, sink) < 0)
		return FALSE;

	return TRUE;
}
示例#8
0
static void start_discovery(struct audio_device *dev, struct unix_client *client)
{
	struct a2dp_data *a2dp;
	int err = 0;

	switch (client->type) {
	case TYPE_SINK:
	case TYPE_SOURCE:
		a2dp = &client->d.a2dp;

		if (!a2dp->session)
			a2dp->session = avdtp_get(&dev->src, &dev->dst);

		if (!a2dp->session) {
			error("Unable to get a session");
			goto failed;
		}

		err = avdtp_discover(a2dp->session, a2dp_discovery_complete,
					client);
		if (err) {
			if (a2dp->session) {
				avdtp_unref(a2dp->session);
				a2dp->session = NULL;
			}
			goto failed;
		}
		break;

	case TYPE_HEADSET:
	case TYPE_GATEWAY:
		headset_discovery_complete(dev, client);
		break;

	default:
		error("No known services for device");
		goto failed;
	}

	client->dev = dev;

	return;

failed:
	unix_ipc_error(client, BT_GET_CAPABILITIES, err ? : EIO);
}
示例#9
0
gboolean sink_setup_stream(struct btd_service *service, struct avdtp *session)
{
	struct sink *sink = btd_service_get_user_data(service);

	if (sink->connect_id > 0 || sink->disconnect_id > 0)
		return FALSE;

	if (session && !sink->session)
		sink->session = avdtp_ref(session);

	if (!sink->session)
		return FALSE;

	if (avdtp_discover(sink->session, discovery_complete, sink) < 0)
		return FALSE;

	return TRUE;
}
gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
{
	if (sink->connect || sink->disconnect)
		return FALSE;

	if (session && !sink->session)
		sink->session = avdtp_ref(session);

	if (!sink->session)
		return FALSE;

	avdtp_set_auto_disconnect(sink->session, FALSE);

	if (avdtp_discover(sink->session, discovery_complete, sink) < 0)
		return FALSE;

	sink->connect = g_new0(struct pending_request, 1);

	return TRUE;
}