示例#1
0
static void init_bdaddr(struct test_data *data)
{
	const uint8_t *master_bdaddr, *client_bdaddr;

	master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
	if (!master_bdaddr) {
		tester_warn("No master bdaddr");
		tester_test_failed();
		return;
	}

	client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
	if (!client_bdaddr) {
		tester_warn("No client bdaddr");
		tester_test_failed();
		return;
	}

	data->ia_type = LE_PUBLIC_ADDRESS;
	data->ra_type = LE_PUBLIC_ADDRESS;

	if (data->out) {
		memcpy(data->ia, client_bdaddr, sizeof(data->ia));
		memcpy(data->ra, master_bdaddr, sizeof(data->ra));
	} else {
		memcpy(data->ia, master_bdaddr, sizeof(data->ia));
		memcpy(data->ra, client_bdaddr, sizeof(data->ra));
	}
}
示例#2
0
static int create_sco_sock(struct test_data *data, uint16_t psm)
{
	const uint8_t *master_bdaddr;
	struct sockaddr_sco addr;
	int sk, err;

	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK,
								BTPROTO_SCO);
	if (sk < 0) {
		err = -errno;
		tester_warn("Can't create socket: %s (%d)", strerror(errno),
									errno);
		return err;
	}

	master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
	if (!master_bdaddr) {
		tester_warn("No master bdaddr");
		return -ENODEV;
	}

	memset(&addr, 0, sizeof(addr));
	addr.sco_family = AF_BLUETOOTH;
	bacpy(&addr.sco_bdaddr, (void *) master_bdaddr);

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		err = -errno;
		tester_warn("Can't bind socket: %s (%d)", strerror(errno),
									errno);
		close(sk);
		return err;
	}

	return sk;
}
static void test_connect(const void *test_data)
{
	struct test_data *data = tester_get_data();
	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
	const struct rfcomm_client_data *client_data = data->test_data;
	const uint8_t *client_addr, *master_addr;
	GIOChannel *io;
	int sk;

	bthost_add_l2cap_server(bthost, 0x0003, NULL, NULL);
	bthost_add_rfcomm_server(bthost, client_data->server_channel,
						rfcomm_connect_cb, NULL);

	master_addr = hciemu_get_master_bdaddr(data->hciemu);
	client_addr = hciemu_get_client_bdaddr(data->hciemu);

	sk = create_rfcomm_sock((bdaddr_t *) master_addr, 0);

	if (connect_rfcomm_sock(sk, (const bdaddr_t *) client_addr,
					client_data->client_channel) < 0) {
		close(sk);
		tester_test_failed();
		return;
	}

	io = g_io_channel_unix_new(sk);
	g_io_channel_set_close_on_unref(io, TRUE);

	data->io_id = g_io_add_watch(io, G_IO_OUT, rc_connect_cb, NULL);

	g_io_channel_unref(io);

	tester_print("Connect in progress %d", sk);
}
static int create_l2cap_sock(struct test_data *data, uint16_t psm,
						uint16_t cid, int sec_level)
{
	const uint8_t *master_bdaddr;
	struct sockaddr_l2 addr;
	int sk, err;

	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK,
							BTPROTO_L2CAP);
	if (sk < 0) {
		err = -errno;
		tester_warn("Can't create socket: %s (%d)", strerror(errno),
									errno);
		return err;
	}

	master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
	if (!master_bdaddr) {
		tester_warn("No master bdaddr");
		close(sk);
		return -ENODEV;
	}

	memset(&addr, 0, sizeof(addr));
	addr.l2_family = AF_BLUETOOTH;
	addr.l2_psm = htobs(psm);
	addr.l2_cid = htobs(cid);
	bacpy(&addr.l2_bdaddr, (void *) master_bdaddr);
	if (data->hciemu_type == HCIEMU_TYPE_LE)
		addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
	else
		addr.l2_bdaddr_type = BDADDR_BREDR;

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		err = -errno;
		tester_warn("Can't bind socket: %s (%d)", strerror(errno),
									errno);
		close(sk);
		return err;
	}

	if (sec_level) {
		struct bt_security sec;

		memset(&sec, 0, sizeof(sec));
		sec.level = sec_level;

		if (setsockopt(sk, SOL_BLUETOOTH, BT_SECURITY, &sec,
							sizeof(sec)) < 0) {
			err = -errno;
			tester_warn("Can't set security level: %s (%d)",
						strerror(errno), errno);
			close(sk);
			return err;
		}
	}

	return sk;
}
static void test_server(const void *test_data)
{
	struct test_data *data = tester_get_data();
	const struct l2cap_data *l2data = data->test_data;
	const uint8_t *master_bdaddr;
	uint8_t addr_type;
	struct bthost *bthost;
	GIOChannel *io;
	int sk;

	if (l2data->server_psm || l2data->cid) {
		sk = create_l2cap_sock(data, l2data->server_psm,
					l2data->cid, l2data->sec_level);
		if (sk < 0) {
			tester_test_failed();
			return;
		}

		if (listen(sk, 5) < 0) {
			tester_warn("listening on socket failed: %s (%u)",
					strerror(errno), errno);
			tester_test_failed();
			close(sk);
			return;
		}

		io = g_io_channel_unix_new(sk);
		g_io_channel_set_close_on_unref(io, TRUE);

		data->io_id = g_io_add_watch(io, G_IO_IN, l2cap_listen_cb,
									NULL);
		g_io_channel_unref(io);

		tester_print("Listening for connections");
	}

	master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
	if (!master_bdaddr) {
		tester_warn("No master bdaddr");
		tester_test_failed();
		return;
	}

	bthost = hciemu_client_get_host(data->hciemu);
	bthost_set_connect_cb(bthost, send_req_new_conn, data);

	if (data->hciemu_type == HCIEMU_TYPE_BREDR)
		addr_type = BDADDR_BREDR;
	else
		addr_type = BDADDR_LE_PUBLIC;

	bthost_hci_connect(bthost, master_bdaddr, addr_type);
}
static void test_server(const void *test_data)
{
	struct test_data *data = tester_get_data();
	const struct rfcomm_server_data *server_data = data->test_data;
	const uint8_t *master_addr;
	struct bthost *bthost;
	GIOChannel *io;
	int sk;

	master_addr = hciemu_get_master_bdaddr(data->hciemu);

	sk = create_rfcomm_sock((bdaddr_t *) master_addr,
						server_data->server_channel);
	if (sk < 0) {
		tester_test_failed();
		return;
	}

	if (listen(sk, 5) < 0) {
		tester_warn("listening on socket failed: %s (%u)",
				strerror(errno), errno);
		tester_test_failed();
		close(sk);
		return;
	}

	io = g_io_channel_unix_new(sk);
	g_io_channel_set_close_on_unref(io, TRUE);

	data->io_id = g_io_add_watch(io, G_IO_IN, rfcomm_listen_cb, NULL);
	g_io_channel_unref(io);

	tester_print("Listening for connections");

	bthost = hciemu_client_get_host(data->hciemu);
	bthost_set_connect_cb(bthost, client_new_conn, data);

	bthost_hci_connect(bthost, master_addr, BDADDR_BREDR);
}