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

📄 hci_event.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		hci_cc_read_local_version(hdev, skb);		break;	case HCI_OP_READ_LOCAL_COMMANDS:		hci_cc_read_local_commands(hdev, skb);		break;	case HCI_OP_READ_LOCAL_FEATURES:		hci_cc_read_local_features(hdev, skb);		break;	case HCI_OP_READ_BUFFER_SIZE:		hci_cc_read_buffer_size(hdev, skb);		break;	case HCI_OP_READ_BD_ADDR:		hci_cc_read_bd_addr(hdev, skb);		break;	default:		BT_DBG("%s opcode 0x%x", hdev->name, opcode);		break;	}	if (ev->ncmd) {		atomic_set(&hdev->cmd_cnt, 1);		if (!skb_queue_empty(&hdev->cmd_q))			hci_sched_cmd(hdev);	}}static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_cmd_status *ev = (void *) skb->data;	__u16 opcode;	skb_pull(skb, sizeof(*ev));	opcode = __le16_to_cpu(ev->opcode);	switch (opcode) {	case HCI_OP_INQUIRY:		hci_cs_inquiry(hdev, ev->status);		break;	case HCI_OP_CREATE_CONN:		hci_cs_create_conn(hdev, ev->status);		break;	case HCI_OP_ADD_SCO:		hci_cs_add_sco(hdev, ev->status);		break;	case HCI_OP_REMOTE_NAME_REQ:		hci_cs_remote_name_req(hdev, ev->status);		break;	case HCI_OP_SETUP_SYNC_CONN:		hci_cs_setup_sync_conn(hdev, ev->status);		break;	case HCI_OP_SNIFF_MODE:		hci_cs_sniff_mode(hdev, ev->status);		break;	case HCI_OP_EXIT_SNIFF_MODE:		hci_cs_exit_sniff_mode(hdev, ev->status);		break;	default:		BT_DBG("%s opcode 0x%x", hdev->name, opcode);		break;	}	if (ev->ncmd) {		atomic_set(&hdev->cmd_cnt, 1);		if (!skb_queue_empty(&hdev->cmd_q))			hci_sched_cmd(hdev);	}}static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_role_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_ba(hdev, ACL_LINK, &ev->bdaddr);	if (conn) {		if (!ev->status) {			if (ev->role)				conn->link_mode &= ~HCI_LM_MASTER;			else				conn->link_mode |= HCI_LM_MASTER;		}		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);		hci_role_switch_cfm(conn, ev->status, ev->role);	}	hci_dev_unlock(hdev);}static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_num_comp_pkts *ev = (void *) skb->data;	__le16 *ptr;	int i;	skb_pull(skb, sizeof(*ev));	BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);	if (skb->len < ev->num_hndl * 4) {		BT_DBG("%s bad parameters", hdev->name);		return;	}	tasklet_disable(&hdev->tx_task);	for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {		struct hci_conn *conn;		__u16  handle, count;		handle = __le16_to_cpu(get_unaligned(ptr++));		count  = __le16_to_cpu(get_unaligned(ptr++));		conn = hci_conn_hash_lookup_handle(hdev, handle);		if (conn) {			conn->sent -= count;			if (conn->type == ACL_LINK) {				if ((hdev->acl_cnt += count) > hdev->acl_pkts)					hdev->acl_cnt = hdev->acl_pkts;			} else {				if ((hdev->sco_cnt += count) > hdev->sco_pkts)					hdev->sco_cnt = hdev->sco_pkts;			}		}	}	hci_sched_tx(hdev);	tasklet_enable(&hdev->tx_task);}static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_mode_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) {		conn->mode = ev->mode;		conn->interval = __le16_to_cpu(ev->interval);		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {			if (conn->mode == HCI_CM_ACTIVE)				conn->power_save = 1;			else				conn->power_save = 0;		}	}	hci_dev_unlock(hdev);}static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);}static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);}static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);}static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_clock_offset *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 && !ev->status) {		struct inquiry_entry *ie;		if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {			ie->data.clock_offset = ev->clock_offset;			ie->timestamp = jiffies;		}	}	hci_dev_unlock(hdev);}static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;	struct inquiry_entry *ie;	BT_DBG("%s", hdev->name);	hci_dev_lock(hdev);	if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {		ie->data.pscan_rep_mode = ev->pscan_rep_mode;		ie->timestamp = jiffies;	}	hci_dev_unlock(hdev);}static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct inquiry_data data;	int num_rsp = *((__u8 *) skb->data);	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);	if (!num_rsp)		return;	hci_dev_lock(hdev);	if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {		struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);		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		= info->rssi;			info++;			hci_inquiry_cache_update(hdev, &data);		}	} else {		struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);		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		= 0x00;			memcpy(data.dev_class, info->dev_class, 3);			data.clock_offset	= info->clock_offset;			data.rssi		= info->rssi;			info++;			hci_inquiry_cache_update(hdev, &data);		}	}	hci_dev_unlock(hdev);}static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);}static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_sync_conn_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_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;	} else		conn->state = BT_CLOSED;	hci_proto_connect_cfm(conn, ev->status);	if (ev->status)		hci_conn_del(conn);unlock:	hci_dev_unlock(hdev);}static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb){	BT_DBG("%s", hdev->name);}static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_ev_sniff_subrate *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) {	}	hci_dev_unlock(hdev);}static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb){	struct inquiry_data data;	struct extended_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         = 0x00;		memcpy(data.dev_class, info->dev_class, 3);		data.clock_offset       = info->clock_offset;		data.rssi               = info->rssi;		info++;		hci_inquiry_cache_update(hdev, &data);	}	hci_dev_unlock(hdev);}void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb){	struct hci_event_hdr *hdr = (void *) skb->data;	__u8 event = hdr->evt;	skb_pull(skb, HCI_EVENT_HDR_SIZE);	switch (event) {	case HCI_EV_INQUIRY_COMPLETE:		hci_inquiry_complete_evt(hdev, skb);		break;	case HCI_EV_INQUIRY_RESULT:		hci_inquiry_result_evt(hdev, skb);		break;	case HCI_EV_CONN_COMPLETE:		hci_conn_complete_evt(hdev, skb);		break;	case HCI_EV_CONN_REQUEST:		hci_conn_request_evt(hdev, skb);		break;	case HCI_EV_DISCONN_COMPLETE:		hci_disconn_complete_evt(hdev, skb);		break;	case HCI_EV_AUTH_COMPLETE:		hci_auth_complete_evt(hdev, skb);		break;	case HCI_EV_REMOTE_NAME:		hci_remote_name_evt(hdev, skb);		break;	case HCI_EV_ENCRYPT_CHANGE:		hci_encrypt_change_evt(hdev, skb);		break;	case HCI_EV_CHANGE_LINK_KEY_COMPLETE:		hci_change_link_key_complete_evt(hdev, skb);		break;	case HCI_EV_REMOTE_FEATURES:		hci_remote_features_evt(hdev, skb);		break;	case HCI_EV_REMOTE_VERSION:		hci_remote_version_evt(hdev, skb);		break;	case HCI_EV_QOS_SETUP_COMPLETE:		hci_qos_setup_complete_evt(hdev, skb);		break;	case HCI_EV_CMD_COMPLETE:		hci_cmd_complete_evt(hdev, skb);		break;	case HCI_EV_CMD_STATUS:		hci_cmd_status_evt(hdev, skb);		break;	case HCI_EV_ROLE_CHANGE:		hci_role_change_evt(hdev, skb);		break;	case HCI_EV_NUM_COMP_PKTS:		hci_num_comp_pkts_evt(hdev, skb);		break;	case HCI_EV_MODE_CHANGE:		hci_mode_change_evt(hdev, skb);		break;	case HCI_EV_PIN_CODE_REQ:		hci_pin_code_request_evt(hdev, skb);		break;	case HCI_EV_LINK_KEY_REQ:		hci_link_key_request_evt(hdev, skb);		break;	case HCI_EV_LINK_KEY_NOTIFY:		hci_link_key_notify_evt(hdev, skb);		break;	case HCI_EV_CLOCK_OFFSET:		hci_clock_offset_evt(hdev, skb);		break;	case HCI_EV_PSCAN_REP_MODE:		hci_pscan_rep_mode_evt(hdev, skb);		break;	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:		hci_inquiry_result_with_rssi_evt(hdev, skb);		break;	case HCI_EV_REMOTE_EXT_FEATURES:		hci_remote_ext_features_evt(hdev, skb);		break;	case HCI_EV_SYNC_CONN_COMPLETE:		hci_sync_conn_complete_evt(hdev, skb);		break;	case HCI_EV_SYNC_CONN_CHANGED:		hci_sync_conn_changed_evt(hdev, skb);		break;	case HCI_EV_SNIFF_SUBRATE:		hci_sniff_subrate_evt(hdev, skb);		break;	case HCI_EV_EXTENDED_INQUIRY_RESULT:		hci_extended_inquiry_result_evt(hdev, skb);		break;	default:		BT_DBG("%s event 0x%x", hdev->name, event);		break;	}	kfree_skb(skb);	hdev->stat.evt_rx++;}/* Generate internal stack event */void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data){	struct hci_event_hdr *hdr;	struct hci_ev_stack_internal *ev;	struct sk_buff *skb;	skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);	if (!skb)		return;	hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);	hdr->evt  = HCI_EV_STACK_INTERNAL;	hdr->plen = sizeof(*ev) + dlen;	ev  = (void *) skb_put(skb, sizeof(*ev) + dlen);	ev->type = type;	memcpy(ev->data, data, dlen);	bt_cb(skb)->incoming = 1;	__net_timestamp(skb);	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;	skb->dev = (void *) hdev;	hci_send_to_sock(hdev, skb);	kfree_skb(skb);}

⌨️ 快捷键说明

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