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

📄 hci_event.c

📁 蓝牙的各种编程接口和各种按理介绍,还有一些例子和说明
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (; num_rsp; num_rsp--)		inquiry_cache_update(hdev, info++);	hci_dev_unlock(hdev);}/* Connect Request */static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb){	evt_conn_request *cr = (evt_conn_request *) skb->data;	int mask = hdev->link_mode;	BT_DBG("%s Connection request: %s type 0x%x", hdev->name,			batostr(&cr->bdaddr), cr->link_type);	mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);	if (mask & HCI_LM_ACCEPT) {		/* Connection accepted */		struct hci_conn *conn;		accept_conn_req_cp ac;		hci_dev_lock(hdev);		conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);		if (!conn) {			if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {				BT_ERR("No memmory for new connection");				hci_dev_unlock(hdev);				return;			}		}		conn->state = BT_CONNECT;		hci_dev_unlock(hdev);		bacpy(&ac.bdaddr, &cr->bdaddr);			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))			ac.role = 0x00; /* Become master */		else			ac.role = 0x01; /* Remain slave */		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, 				ACCEPT_CONN_REQ_CP_SIZE, &ac);	} else {		/* Connection rejected */		reject_conn_req_cp rc;		bacpy(&rc.bdaddr, &cr->bdaddr);		rc.reason = 0x0f;		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,				REJECT_CONN_REQ_CP_SIZE, &rc);	}}/* Connect Complete */static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	evt_conn_complete *cc = (evt_conn_complete *) skb->data;	struct hci_conn *conn = NULL;	BT_DBG("%s", hdev->name);	hci_dev_lock(hdev);		conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);	if (!conn) {		hci_dev_unlock(hdev);		return;	}	if (!cc->status) {		conn->handle = __le16_to_cpu(cc->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;		/* Set link policy */		if (conn->type == ACL_LINK && hdev->link_policy) {			write_link_policy_cp lp;			lp.handle = cc->handle;			lp.policy = __cpu_to_le16(hdev->link_policy);			hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,				WRITE_LINK_POLICY_CP_SIZE, &lp);		}		/* Set packet type for incomming connection */		if (!conn->out) {			change_conn_ptype_cp cp;			cp.handle = cc->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, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,				CHANGE_CONN_PTYPE_CP_SIZE, &cp);		}	} else		conn->state = BT_CLOSED;	if (conn->type == ACL_LINK) {		struct hci_conn *sco = conn->link;		if (sco) {			if (!cc->status)				hci_add_sco(sco, conn->handle);			else {				hci_proto_connect_cfm(sco, cc->status);				hci_conn_del(sco);			}		}	}	hci_proto_connect_cfm(conn, cc->status);	if (cc->status)		hci_conn_del(conn);	hci_dev_unlock(hdev);}/* Disconnect Complete */static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;	struct hci_conn *conn = NULL;	__u16 handle = __le16_to_cpu(dc->handle);	BT_DBG("%s status %d", hdev->name, dc->status);	if (dc->status)		return;	hci_dev_lock(hdev);		conn = conn_hash_lookup_handle(hdev, handle);	if (conn) {		conn->state = BT_CLOSED;		hci_proto_disconn_ind(conn, dc->reason);		hci_conn_del(conn);	}	hci_dev_unlock(hdev);}/* Number of completed packets */static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb){	evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;	__u16 *ptr;	int i;	skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);	BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);	if (skb->len < nc->num_hndl * 4) {		BT_DBG("%s bad parameters", hdev->name);		return;	}	tasklet_disable(&hdev->tx_task);	for (i = 0, ptr = (__u16 *) skb->data; i < nc->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 = conn_hash_lookup_handle(hdev, handle);		if (conn) {			conn->sent -= count;			if (conn->type == SCO_LINK) {				if ((hdev->sco_cnt += count) > hdev->sco_pkts)					hdev->sco_cnt = hdev->sco_pkts;			} else {				if ((hdev->acl_cnt += count) > hdev->acl_pkts)					hdev->acl_cnt = hdev->acl_pkts;			}		}	}	hci_sched_tx(hdev);	tasklet_enable(&hdev->tx_task);}/* Role Change */static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb){	evt_role_change *rc = (evt_role_change *) skb->data;	struct hci_conn *conn = NULL;	BT_DBG("%s status %d", hdev->name, rc->status);	if (rc->status)		return;	hci_dev_lock(hdev);		conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);	if (conn) {		if (rc->role)			conn->link_mode &= ~HCI_LM_MASTER;		else 			conn->link_mode |= HCI_LM_MASTER;	}	hci_dev_unlock(hdev);}/* Authentication Complete */static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb){	evt_auth_complete *ac = (evt_auth_complete *) skb->data;	struct hci_conn *conn = NULL;	__u16 handle = __le16_to_cpu(ac->handle);	BT_DBG("%s status %d", hdev->name, ac->status);	hci_dev_lock(hdev);		conn = conn_hash_lookup_handle(hdev, handle);	if (conn) {		if (!ac->status)			conn->link_mode |= HCI_LM_AUTH;		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);		hci_proto_auth_cfm(conn, ac->status);				if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {			if (!ac->status) {				set_conn_encrypt_cp ce;				ce.handle  = __cpu_to_le16(conn->handle);				ce.encrypt = 1;				hci_send_cmd(conn->hdev, OGF_LINK_CTL,						OCF_SET_CONN_ENCRYPT,						SET_CONN_ENCRYPT_CP_SIZE, &ce);			} else {				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);				hci_proto_encrypt_cfm(conn, ac->status);			}		}	}	hci_dev_unlock(hdev);}/* Encryption Change */static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb){	evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;	struct hci_conn *conn = NULL;	__u16 handle = __le16_to_cpu(ec->handle);	BT_DBG("%s status %d", hdev->name, ec->status);	hci_dev_lock(hdev);		conn = conn_hash_lookup_handle(hdev, handle);	if (conn) {		if (!ec->status) {		       	if (ec->encrypt)				conn->link_mode |= HCI_LM_ENCRYPT;			else				conn->link_mode &= ~HCI_LM_ENCRYPT;		}		clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);				hci_proto_encrypt_cfm(conn, ec->status);	}	hci_dev_unlock(hdev);}void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb){	hci_event_hdr *he = (hci_event_hdr *) skb->data;	evt_cmd_status *cs;	evt_cmd_complete *ec;	__u16 opcode, ocf, ogf;	skb_pull(skb, HCI_EVENT_HDR_SIZE);	BT_DBG("%s evt 0x%x", hdev->name, he->evt);	switch (he->evt) {	case EVT_NUM_COMP_PKTS:		hci_num_comp_pkts_evt(hdev, skb);		break;	case EVT_INQUIRY_COMPLETE:		hci_inquiry_complete_evt(hdev, skb);		break;	case EVT_INQUIRY_RESULT:		hci_inquiry_result_evt(hdev, skb);		break;	case EVT_CONN_REQUEST:		hci_conn_request_evt(hdev, skb);		break;	case EVT_CONN_COMPLETE:		hci_conn_complete_evt(hdev, skb);		break;	case EVT_DISCONN_COMPLETE:		hci_disconn_complete_evt(hdev, skb);		break;	case EVT_ROLE_CHANGE:		hci_role_change_evt(hdev, skb);		break;	case EVT_AUTH_COMPLETE:		hci_auth_complete_evt(hdev, skb);		break;	case EVT_ENCRYPT_CHANGE:		hci_encrypt_change_evt(hdev, skb);		break;	case EVT_CMD_STATUS:		cs = (evt_cmd_status *) skb->data;		skb_pull(skb, EVT_CMD_STATUS_SIZE);						opcode = __le16_to_cpu(cs->opcode);		ogf = cmd_opcode_ogf(opcode);		ocf = cmd_opcode_ocf(opcode);		switch (ogf) {		case OGF_INFO_PARAM:			hci_cs_info_param(hdev, ocf, cs->status);			break;		case OGF_HOST_CTL:			hci_cs_host_ctl(hdev, ocf, cs->status);			break;		case OGF_LINK_CTL:			hci_cs_link_ctl(hdev, ocf, cs->status);			break;		case OGF_LINK_POLICY:			hci_cs_link_policy(hdev, ocf, cs->status);			break;		default:			BT_DBG("%s Command Status OGF %x", hdev->name, ogf);			break;		};		if (cs->ncmd) {			atomic_set(&hdev->cmd_cnt, 1);			if (!skb_queue_empty(&hdev->cmd_q))				hci_sched_cmd(hdev);		}		break;	case EVT_CMD_COMPLETE:		ec = (evt_cmd_complete *) skb->data;		skb_pull(skb, EVT_CMD_COMPLETE_SIZE);		opcode = __le16_to_cpu(ec->opcode);		ogf = cmd_opcode_ogf(opcode);		ocf = cmd_opcode_ocf(opcode);		switch (ogf) {		case OGF_INFO_PARAM:			hci_cc_info_param(hdev, ocf, skb);			break;		case OGF_HOST_CTL:			hci_cc_host_ctl(hdev, ocf, skb);			break;		case OGF_LINK_CTL:			hci_cc_link_ctl(hdev, ocf, skb);			break;		case OGF_LINK_POLICY:			hci_cc_link_policy(hdev, ocf, skb);			break;		default:			BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);			break;		};		if (ec->ncmd) {			atomic_set(&hdev->cmd_cnt, 1);			if (!skb_queue_empty(&hdev->cmd_q))				hci_sched_cmd(hdev);		}		break;	};	kfree_skb(skb);	hdev->stat.evt_rx++;}/* General internal stack event */void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data){	hci_event_hdr *eh;	evt_stack_internal *si;	struct sk_buff *skb;	int size;	void *ptr;	size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;	skb  = bluez_skb_alloc(size, GFP_ATOMIC);	if (!skb)		return;	ptr = skb_put(skb, size);	eh = ptr;       	eh->evt  = EVT_STACK_INTERNAL;	eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;	ptr += HCI_EVENT_HDR_SIZE;	si = ptr;	si->type = type;	memcpy(si->data, data, dlen);		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 + -