static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
				struct l2conn *l2conn, const void *data,
				uint16_t len)
{
	const struct rfcomm_cmd *ua_hdr = data;
	uint8_t channel = RFCOMM_GET_CHANNEL(ua_hdr->address);
	struct rfcomm_connection_data *conn_data = bthost->rfcomm_conn_data;
	uint8_t type = RFCOMM_GET_TYPE(ua_hdr->control);
	uint8_t buf[14];
	struct rfcomm_hdr *hdr;
	struct rfcomm_mcc *mcc;
	struct rfcomm_pn *pn_cmd;

	if (channel && conn_data && conn_data->channel == channel) {
		if (conn_data->cb)
			conn_data->cb(conn->handle, l2conn->scid,
						conn_data->user_data, true);
		free(bthost->rfcomm_conn_data);
		bthost->rfcomm_conn_data = NULL;
		return;
	}

	if (!conn_data || !RFCOMM_TEST_CR(type))
		return;

	memset(buf, 0, sizeof(buf));

	hdr = (struct rfcomm_hdr *) buf;
	mcc = (struct rfcomm_mcc *) (buf + sizeof(*hdr));
	pn_cmd = (struct rfcomm_pn *) (buf + sizeof(*hdr) + sizeof(*mcc));

	hdr->address = RFCOMM_ADDR(1, 0);
	hdr->control = RFCOMM_CTRL(RFCOMM_UIH, 0);
	hdr->length  = RFCOMM_LEN8(sizeof(*mcc) + sizeof(*pn_cmd));

	mcc->type = RFCOMM_MCC_TYPE(1, RFCOMM_PN);
	mcc->length = RFCOMM_LEN8(sizeof(*pn_cmd));

	pn_cmd->dlci = conn_data->channel * 2;
	pn_cmd->priority = 7;
	pn_cmd->ack_timer = 0;
	pn_cmd->max_retrans = 0;
	pn_cmd->mtu = 667;
	pn_cmd->credits = 7;

	buf[sizeof(*hdr) + sizeof(*mcc) + sizeof(*pn_cmd)] = rfcomm_fcs(buf);

	send_acl(bthost, conn->handle, l2conn->dcid, buf, sizeof(buf));
}
static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
				struct l2conn *l2conn, const void *data,
				uint16_t len)
{
	const struct rfcomm_cmd *hdr = data;
	uint8_t channel = RFCOMM_GET_CHANNEL(hdr->address);
	struct rfcomm_connection_data *conn_data = bthost->rfcomm_conn_data;

	if (conn_data && conn_data->channel == channel) {
		if (conn_data->cb)
			conn_data->cb(conn->handle, l2conn->scid,
						conn_data->user_data, false);
		free(bthost->rfcomm_conn_data);
		bthost->rfcomm_conn_data = NULL;
	}
}
static void rfcomm_sabm_recv(struct bthost *bthost, struct btconn *conn,
				struct l2conn *l2conn, const void *data,
				uint16_t len)
{
	const struct rfcomm_cmd *hdr = data;
	uint8_t dlci = RFCOMM_GET_DLCI(hdr->address);
	struct rfcomm_conn_cb_data *cb;
	uint8_t chan = RFCOMM_GET_CHANNEL(hdr->address);

	cb = bthost_find_rfcomm_cb_by_channel(bthost, chan);
	if (!dlci || cb) {
		rfcomm_ua_send(bthost, conn, l2conn, 1, dlci);
		if (cb && cb->func)
			cb->func(conn->handle, l2conn->scid, cb->user_data,
									true);
	} else {
		rfcomm_dm_send(bthost, conn, l2conn, 1, dlci);
	}
}
示例#4
0
文件: rfcomm.c 项目: hut/bluez-mod
static bool uih_frame(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	uint8_t credits;
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_lhdr *hdr = &rfcomm_frame->hdr;

	if (!RFCOMM_GET_CHANNEL(hdr->address))
		return mcc_frame(rfcomm_frame, indent);

	/* fetching credits from UIH frame */
	if (GET_PF(hdr->control)) {
		if (!l2cap_frame_get_u8(frame, &credits))
			return false;
		hdr->credits = credits;
		print_field("%*cCredits: %d", indent, ' ', hdr->credits);
	}

	packet_hexdump(frame->data, frame->size);
	return true;
}