⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hci_event.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	BT_DBG("%s status 0x%x", hdev->name, status);	if (!status)		return;	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);	if (!cp)		return;	handle = __le16_to_cpu(cp->handle);	BT_DBG("%s handle %d", hdev->name, handle);	hci_dev_lock(hdev);	acl = hci_conn_hash_lookup_handle(hdev, handle);	if (acl && (sco = acl->link)) {		sco->state = BT_CLOSED;		hci_proto_connect_cfm(sco, status);		hci_conn_del(sco);	}	hci_dev_unlock(hdev);}static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status){	BT_DBG("%s status 0x%x", hdev->name, status);}static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status){	struct hci_cp_setup_sync_conn *cp;	struct hci_conn *acl, *sco;	__u16 handle;	BT_DBG("%s status 0x%x", hdev->name, status);	if (!status)		return;	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);	if (!cp)		return;	handle = __le16_to_cpu(cp->handle);	BT_DBG("%s handle %d", hdev->name, handle);	hci_dev_lock(hdev);	acl = hci_conn_hash_lookup_handle(hdev, handle);	if (acl && (sco = acl->link)) {		sco->state = BT_CLOSED;		hci_proto_connect_cfm(sco, status);		hci_conn_del(sco);	}	hci_dev_unlock(hdev);}static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status){	struct hci_cp_sniff_mode *cp;	struct hci_conn *conn;	BT_DBG("%s status 0x%x", hdev->name, status);	if (!status)		return;	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);	if (!cp)		return;	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));	if (conn)		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);	hci_dev_unlock(hdev);}static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status){	struct hci_cp_exit_sniff_mode *cp;	struct hci_conn *conn;	BT_DBG("%s status 0x%x", hdev->name, status);	if (!status)		return;	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);	if (!cp)		return;	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));	if (conn)		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);	hci_dev_unlock(hdev);}static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	__u8 status = *((__u8 *) skb->data);	BT_DBG("%s status %d", hdev->name, status);	clear_bit(HCI_INQUIRY, &hdev->flags);	hci_req_complete(hdev, status);	hci_conn_check_pending(hdev);}static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct inquiry_data data;	struct inquiry_info *info = (void *) (skb->data + 1);	int num_rsp = *((__u8 *) skb->data);	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);	if (!num_rsp)		return;	hci_dev_lock(hdev);	for (; num_rsp; num_rsp--) {		bacpy(&data.bdaddr, &info->bdaddr);		data.pscan_rep_mode	= info->pscan_rep_mode;		data.pscan_period_mode	= info->pscan_period_mode;		data.pscan_mode		= info->pscan_mode;		memcpy(data.dev_class, info->dev_class, 3);		data.clock_offset	= info->clock_offset;		data.rssi		= 0x00;		info++;		hci_inquiry_cache_update(hdev, &data);	}	hci_dev_unlock(hdev);}static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_conn_complete *ev = (void *) skb->data;	struct hci_conn *conn;	BT_DBG("%s", hdev->name);	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);	if (!conn)		goto unlock;	if (!ev->status) {		conn->handle = __le16_to_cpu(ev->handle);		conn->state  = BT_CONNECTED;		if (test_bit(HCI_AUTH, &hdev->flags))			conn->link_mode |= HCI_LM_AUTH;		if (test_bit(HCI_ENCRYPT, &hdev->flags))			conn->link_mode |= HCI_LM_ENCRYPT;		/* Get remote features */		if (conn->type == ACL_LINK) {			struct hci_cp_read_remote_features cp;			cp.handle = ev->handle;			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp);		}		/* Set link policy */		if (conn->type == ACL_LINK && hdev->link_policy) {			struct hci_cp_write_link_policy cp;			cp.handle = ev->handle;			cp.policy = cpu_to_le16(hdev->link_policy);			hci_send_cmd(hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp);		}		/* Set packet type for incoming connection */		if (!conn->out) {			struct hci_cp_change_conn_ptype cp;			cp.handle = ev->handle;			cp.pkt_type = (conn->type == ACL_LINK) ?				cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):				cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), &cp);		} else {			/* Update disconnect timer */			hci_conn_hold(conn);			hci_conn_put(conn);		}	} else		conn->state = BT_CLOSED;	if (conn->type == ACL_LINK) {		struct hci_conn *sco = conn->link;		if (sco) {			if (!ev->status) {				if (lmp_esco_capable(hdev))					hci_setup_sync(sco, conn->handle);				else					hci_add_sco(sco, conn->handle);			} else {				hci_proto_connect_cfm(sco, ev->status);				hci_conn_del(sco);			}		}	}	hci_proto_connect_cfm(conn, ev->status);	if (ev->status)		hci_conn_del(conn);unlock:	hci_dev_unlock(hdev);	hci_conn_check_pending(hdev);}static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_conn_request *ev = (void *) skb->data;	int mask = hdev->link_mode;	BT_DBG("%s bdaddr %s type 0x%x", hdev->name,					batostr(&ev->bdaddr), ev->link_type);	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);	if (mask & HCI_LM_ACCEPT) {		/* Connection accepted */		struct hci_conn *conn;		hci_dev_lock(hdev);		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);		if (!conn) {			if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {				BT_ERR("No memmory for new connection");				hci_dev_unlock(hdev);				return;			}		}		memcpy(conn->dev_class, ev->dev_class, 3);		conn->state = BT_CONNECT;		hci_dev_unlock(hdev);		if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {			struct hci_cp_accept_conn_req cp;			bacpy(&cp.bdaddr, &ev->bdaddr);			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))				cp.role = 0x00; /* Become master */			else				cp.role = 0x01; /* Remain slave */			hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,							sizeof(cp), &cp);		} else {			struct hci_cp_accept_sync_conn_req cp;			bacpy(&cp.bdaddr, &ev->bdaddr);			cp.pkt_type = cpu_to_le16(hdev->esco_type);			cp.tx_bandwidth   = cpu_to_le32(0x00001f40);			cp.rx_bandwidth   = cpu_to_le32(0x00001f40);			cp.max_latency    = cpu_to_le16(0xffff);			cp.content_format = cpu_to_le16(hdev->voice_setting);			cp.retrans_effort = 0xff;			hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,							sizeof(cp), &cp);		}	} else {		/* Connection rejected */		struct hci_cp_reject_conn_req cp;		bacpy(&cp.bdaddr, &ev->bdaddr);		cp.reason = 0x0f;		hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);	}}static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_disconn_complete *ev = (void *) skb->data;	struct hci_conn *conn;	BT_DBG("%s status %d", hdev->name, ev->status);	if (ev->status)		return;	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));	if (conn) {		conn->state = BT_CLOSED;		hci_proto_disconn_ind(conn, ev->reason);		hci_conn_del(conn);	}	hci_dev_unlock(hdev);}static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_auth_complete *ev = (void *) skb->data;	struct hci_conn *conn;	BT_DBG("%s status %d", hdev->name, ev->status);	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));	if (conn) {		if (!ev->status)			conn->link_mode |= HCI_LM_AUTH;		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);		hci_auth_cfm(conn, ev->status);		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {			if (!ev->status) {				struct hci_cp_set_conn_encrypt cp;				cp.handle  = cpu_to_le16(conn->handle);				cp.encrypt = 1;				hci_send_cmd(conn->hdev,					HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);			} else {				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);				hci_encrypt_cfm(conn, ev->status, 0x00);			}		}	}	hci_dev_unlock(hdev);}static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);	hci_conn_check_pending(hdev);}static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_encrypt_change *ev = (void *) skb->data;	struct hci_conn *conn;	BT_DBG("%s status %d", hdev->name, ev->status);	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));	if (conn) {		if (!ev->status) {			if (ev->encrypt)				conn->link_mode |= HCI_LM_ENCRYPT;			else				conn->link_mode &= ~HCI_LM_ENCRYPT;		}		clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);		hci_encrypt_cfm(conn, ev->status, ev->encrypt);	}	hci_dev_unlock(hdev);}static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_change_link_key_complete *ev = (void *) skb->data;	struct hci_conn *conn;	BT_DBG("%s status %d", hdev->name, ev->status);	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));	if (conn) {		if (!ev->status)			conn->link_mode |= HCI_LM_SECURE;		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);		hci_key_change_cfm(conn, ev->status);	}	hci_dev_unlock(hdev);}static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_remote_features *ev = (void *) skb->data;	struct hci_conn *conn;	BT_DBG("%s status %d", hdev->name, ev->status);	if (ev->status)		return;	hci_dev_lock(hdev);	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));	if (conn)		memcpy(conn->features, ev->features, 8);	hci_dev_unlock(hdev);}static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);}static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);}static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_cmd_complete *ev = (void *) skb->data;	__u16 opcode;	skb_pull(skb, sizeof(*ev));	opcode = __le16_to_cpu(ev->opcode);	switch (opcode) {	case HCI_OP_INQUIRY_CANCEL:		hci_cc_inquiry_cancel(hdev, skb);		break;	case HCI_OP_EXIT_PERIODIC_INQ:		hci_cc_exit_periodic_inq(hdev, skb);		break;	case HCI_OP_REMOTE_NAME_REQ_CANCEL:		hci_cc_remote_name_req_cancel(hdev, skb);		break;	case HCI_OP_ROLE_DISCOVERY:		hci_cc_role_discovery(hdev, skb);		break;	case HCI_OP_WRITE_LINK_POLICY:		hci_cc_write_link_policy(hdev, skb);		break;	case HCI_OP_RESET:		hci_cc_reset(hdev, skb);		break;	case HCI_OP_WRITE_LOCAL_NAME:		hci_cc_write_local_name(hdev, skb);		break;	case HCI_OP_READ_LOCAL_NAME:		hci_cc_read_local_name(hdev, skb);		break;	case HCI_OP_WRITE_AUTH_ENABLE:		hci_cc_write_auth_enable(hdev, skb);		break;	case HCI_OP_WRITE_ENCRYPT_MODE:		hci_cc_write_encrypt_mode(hdev, skb);		break;	case HCI_OP_WRITE_SCAN_ENABLE:		hci_cc_write_scan_enable(hdev, skb);		break;	case HCI_OP_READ_CLASS_OF_DEV:		hci_cc_read_class_of_dev(hdev, skb);		break;	case HCI_OP_WRITE_CLASS_OF_DEV:		hci_cc_write_class_of_dev(hdev, skb);		break;	case HCI_OP_READ_VOICE_SETTING:		hci_cc_read_voice_setting(hdev, skb);		break;	case HCI_OP_WRITE_VOICE_SETTING:		hci_cc_write_voice_setting(hdev, skb);		break;	case HCI_OP_HOST_BUFFER_SIZE:		hci_cc_host_buffer_size(hdev, skb);		break;	case HCI_OP_READ_LOCAL_VERSION:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -