bool bthost_connect_rfcomm(struct bthost *bthost, uint16_t handle,
				uint8_t channel, bthost_rfcomm_connect_cb func,
				void *user_data)
{
	struct rfcomm_connection_data *data;
	struct bt_l2cap_pdu_conn_req req;
	struct btconn *conn;

	if (bthost->rfcomm_conn_data)
		return false;

	conn = bthost_find_conn(bthost, handle);
	if (!conn)
		return false;

	data = malloc(sizeof(struct rfcomm_connection_data));
	if (!data)
		return false;

	data->channel = channel;
	data->conn = conn;
	data->cb = func;
	data->user_data = user_data;

	bthost->rfcomm_conn_data = data;

	req.psm = cpu_to_le16(0x0003);
	req.scid = cpu_to_le16(conn->next_cid++);

	return bthost_l2cap_req(bthost, handle, BT_L2CAP_PDU_CONN_REQ,
					&req, sizeof(req), NULL, NULL);
}
static void send_req_new_conn(uint16_t handle, void *user_data)
{
	struct test_data *data = user_data;
	const struct l2cap_data *l2data = data->test_data;
	struct bthost *bthost;

	tester_print("New client connection with handle 0x%04x", handle);

	data->handle = handle;

	if (l2data->send_cmd) {
		bthost_l2cap_rsp_cb cb;

		if (l2data->expect_cmd_code)
			cb = client_l2cap_rsp;
		else
			cb = NULL;

		tester_print("Sending L2CAP Request from client");

		bthost = hciemu_client_get_host(data->hciemu);
		bthost_l2cap_req(bthost, handle, l2data->send_cmd_code,
					l2data->send_cmd, l2data->send_cmd_len,
					cb, data);
	}
}
示例#3
0
static void client_l2cap_rsp(uint8_t code, const void *data, uint16_t len,
							void *user_data)
{
	struct test_data *t_data = tester_get_data();
	struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
	struct emu_l2cap_cid_data *cid_data = user_data;
	const uint16_t *psm = data;
	const struct iovec con_req = raw_pdu(0x13, 0x00,	/* PSM */
						0x41, 0x00);	/* Source CID */

	if (len < sizeof(*psm)) {
		tester_warn("Invalid l2cap response.");
		return;
	}

	switch (*psm) {
	case 0x40:
		bthost_add_cid_hook(bthost, cid_data->handle, 0x40,
						hid_ctrl_cid_hook_cb, cid_data);

		bthost_l2cap_req(bthost, cid_data->handle, 0x02,
					con_req.iov_base, con_req.iov_len,
					client_l2cap_rsp, cid_data);
		break;
	case 0x41:
		bthost_add_cid_hook(bthost, cid_data->handle, 0x41,
						hid_intr_cid_hook_cb, cid_data);
		break;
	default:
		break;
	}
}
示例#4
0
static void hidhost_conn_cb(uint16_t handle, void *user_data)
{
	const struct iovec con_req = raw_pdu(0x11, 0x00,	/* PSM */
						0x40, 0x00);	/* Source CID */

	struct test_data *data = tester_get_data();
	struct bthost *bthost = hciemu_client_get_host(data->hciemu);

	if (data->hciemu_type == HCIEMU_TYPE_BREDR) {
		tester_warn("Not handled device type.");
		return;
	}

	ctrl_cid_data.cid = 0x40;
	ctrl_cid_data.handle = handle;

	tester_print("Sending L2CAP Request from remote");

	bthost_l2cap_req(bthost, handle, 0x02, con_req.iov_base,
					con_req.iov_len, client_l2cap_rsp,
					&ctrl_cid_data);
}