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

📄 hci.c

📁 S3C2410平台下蓝牙编程与实验
💻 C
📖 第 1 页 / 共 3 页
字号:
}

/* Command Status OGF INFO_PARAM  */
void hci_cs_info_param(struct hci_dev *hdev,UINT16 ocf,UINT8 status)
{
	switch(ocf){
	default:
		hci_req_complete(hdev, status);
		#ifdef DEBUG
		printf("%s Command status: ogf INFO_PARAM ocf %x", hdev->hci_device_info.name, ocf);
		#endif
	}
}

/* Inquiry Complete */
void hci_inquiry_complete_evt(struct hci_dev *hdev)
{
	UINT8 status =(UINT8)(SDC_Get_Char(hdev->port));
	hci_req_complete(hdev,status);
	#ifdef DEBUG
	printf("%s status %d", hdev->hci_device_info.name, status);
	#endif
}

/* Inquiry Result */
void hci_inquiry_result_evt(struct hci_dev *hdev)
{
	int i;
	int num_rsp = (UINT8)(SDC_Get_Char(hdev->port));
	if(num_rsp !=1)
		return;
	for(i = 0;i<INQUIRY_INFO_SIZE;i++)
	{
		*((UINT8 *)(&(hdev->hci_inquiry_info))+i) = (UINT8)(SDC_Get_Char(hdev->port));
	}
  	//置标志位,已经接受一个蓝牙的inquiry信息
  	hdev->inqu_flags = 0x0;
}

/* Connect Request */
void hci_conn_request_evt(struct hci_dev *hdev)
{
	int i;
	evt_conn_request cr;
	accept_conn_req_cp ac;
	reject_conn_cp rc;
	int accept = 0;
	for(i=0;i<EVT_CONN_REQUEST_SIZE;i++)
	{
		*((UINT8 *)(&cr)+i) = (UINT8)(SDC_Get_Char(hdev->port));
	}
	
	//printf("%s Connection request: %s type 0x%x", hdev->name, &cr->bdaddr, cr->link_type);
	
	if (cr.link_type == ACL_LINK) {
		/* Notify upper protocols ACL link notify L2CAP */
		
		
	}else{
	/* SCO link (no notification) */
	accept = 1;
	
	}
	if (accept) {
		/* Connection accepted by upper layer */
		__bt_mem_cpy((void*)(ac.bdaddr),(void*)(cr.bdaddr),6);
		ac.role = 0x01; //remain slave
		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, (void*)&ac);
	}else{
		__bt_mem_cpy((void*)(rc.bdaddr),(void*)(cr.bdaddr),6);
		rc.reason = REJECT_REASON;
		hci_send_cmd(hdev,OGF_LINK_CTL,OCF_REJECT_CONN_REQ,REJECT_CONN_REQ_CP_SIZE,(void*)&rc);
	}
}

/* Connect Complete */
void hci_conn_complete_evt(struct hci_dev *hdev)
{
	int i;
	evt_conn_complete cc;
	for(i=0;i<EVT_CONN_COMPLETE_SIZE;i++)
	{
		*((UINT8 *)(&cc)+i) = (UINT8)(SDC_Get_Char(hdev->port));
	}
	if (!cc.status)
	{
		hci_conn_add(hdev,(UINT16)(cc.handle), cc.link_type, (char*)cc.bdaddr);
		hdev->link_flags=0;
		//for notify upper protocols.
		if (cc.link_type == ACL_LINK) {
	
	
		}else{
	
	
		}
	}
}

/* Disconnect Complete */

void hci_disconn_complete_evt(struct hci_dev *hdev)
{
	int i;
	UINT16 handle;
	evt_disconn_complete dc;
	for(i=0;i<EVT_DISCONN_COMPLETE_SIZE;i++)
	{
		*((char*)(&dc)+i) = (UINT8)(SDC_Get_Char(hdev->port));
	}
	handle = (UINT16)(dc.handle);
	
	if (!dc.status && (handle == hdev->hci_connection.hci_c_info.handle)) {
		// For Notify upper protocols 
		//if (conn->type == ACL_LINK) {
		
		
		//}else{
	
	
		//}
		hci_conn_del(hdev);
	}
}

/* Number of completed packets */
void hci_num_comp_pkts_evt(struct hci_dev *hdev)
{
	evt_num_comp_pkts nc;
	//UINT16 *ptr;
	int i;
	for(i=0;i<EVT_NUM_COMP_PKTS_SIZE;i++)
	{
		*((char*)(&nc)+i) = (UINT8)(SDC_Get_Char(hdev->port));
	}
	if(nc.num_hndl!=1)
	{
		//error,not a point to point bt device
		return;
	}
	if(nc.handle!=hdev->hci_connection.hci_c_info.handle)
	{
		//error,handle error,not matching
		return;
	}
	else{
		hdev->hci_connection.acl_conn_info.sent -=nc.num_of_complete_pkts;
	}
	hdev->acl_cnt +=nc.num_of_complete_pkts;
	
}

//hci event packet
void hci_event_packet(struct hci_dev *hdev)
{
	hci_event_hdr he;
	evt_cmd_status cs;
	evt_cmd_complete ec;
	UINT16 opcode,ocf,ogf;
	UINT8 indicator;
	int i;
	indicator=(UINT8)(SDC_Get_Char(hdev->port));
	if(indicator!=4)
	{
	//not a event packet,return;
		return;
	}
	for(i=0;i<HCI_EVENT_HDR_SIZE;i++)
	{
		*((char*)&he+i) = (UINT8)(SDC_Get_Char(hdev->port));
	}
	
	switch(he.evt){
	case EVT_NUM_COMP_PKTS:
			hci_num_comp_pkts_evt(hdev);
			break;
	case EVT_INQUIRY_COMPLETE:
			hci_inquiry_complete_evt(hdev);
			break;
	case EVT_INQUIRY_RESULT:
			hci_inquiry_result_evt(hdev);
			break;
	case EVT_CONN_REQUEST:
			hci_conn_request_evt(hdev);
			break;
	case EVT_CONN_COMPLETE:
			hci_conn_complete_evt(hdev);
			break;
	case EVT_DISCONN_COMPLETE:
			hci_disconn_complete_evt(hdev);
			break;
	case EVT_CMD_STATUS:
			for(i=0;i<EVT_CMD_STATUS_SIZE;i++)
			{
				*((char*)&cs+i)=(UINT8)(SDC_Get_Char(hdev->port));
			}
			opcode = (UINT16)(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:
					//command status
					#ifdef DEBUG
					printf("%s Command Status OGF %x", hdev->hci_device_info.name, ogf);
					#endif
					break;
			}
			break;
	case EVT_CMD_COMPLETE:
			//ec = (evt_cmd_complete *)((UINT8 *)cb->Head+HCI_EVENT_HDR_SIZE);
			for(i=0;i<EVT_CMD_COMPLETE_SIZE;i++)
			{
				*((char*)&ec+i)=(UINT8)(SDC_Get_Char(hdev->port));
			}
			opcode = /*(UINT16)*/(ec.opcode);
			ogf = cmd_opcode_ogf(opcode);
			ocf = cmd_opcode_ocf(opcode);
			switch(ogf){
			case OGF_INFO_PARAM:
					hci_cc_info_param(hdev, ocf);
					break;
			case OGF_HOST_CTL:
					hci_cc_host_ctl(hdev, ocf);
					break;
			case OGF_LINK_CTL:
					hci_cc_link_ctl(hdev, ocf);
					break;
			case OGF_LINK_POLICY:
					hci_cc_link_policy(hdev, ocf);
					break;
			default:
					//command status
					#ifdef DEBUG
					printf("%s Command Completed OGF %x", hdev->hci_device_info.name, ogf);
					#endif
					break;
			}
	}
	
	//to add addix code here.
	
}


//The following is the user function interfaces
void hci_init_req1(struct hci_dev *hdev)
{
	write_class_of_dev_cp wcd;
	UINT8 name_len;
	//reset
	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
	__bt_print_to_sdc(hdev);
	__delay(1);
	//Mandatory initialization
	//Read BD Address and 
	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
	__bt_print_to_sdc(hdev);
	__delay(2);
	//Read Local Supported Features 
	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
	__bt_print_to_sdc(hdev);
	__delay(1);
	//Read local version information
	hci_send_cmd( hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION, 0, NULL);
	__bt_print_to_sdc(hdev);
	__delay(1);
	//Read Buffer Size (ACL mtu, max pkt, etc.)
	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
	__bt_print_to_sdc(hdev);
	__delay(1);

	while((hdev->port->rx_buffer_status==SDC_BUFFER_DATA)||(hdev->port->rx_buffer_status==SDC_BUFFER_FULL))
	{
		hci_event_packet(hdev);
	}
	//write class of device cmd
	__bt_mem_cpy((void*) (&wcd), (void * )(hdev->hci_device_info.class_device),3);
	hci_send_cmd( (void*)hdev, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, WRITE_CLASS_OF_DEV_CP_SIZE,(void*)(&wcd));
	__bt_print_to_sdc(hdev);
	__delay(1);
	//write device name cmd
	for(name_len=0;*((char*)(hdev->hci_device_info.name)+name_len)!='\0';name_len++)
	{
	}
	hci_send_cmd( (void*)hdev, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, name_len, (void*)(hdev->hci_device_info.name));
	__bt_print_to_sdc(hdev);
	__delay(1);
	while((hdev->port->rx_buffer_status==SDC_BUFFER_DATA)||(hdev->port->rx_buffer_status==SDC_BUFFER_FULL))
	{
		hci_event_packet(hdev);
	}
}
void hci_init_req2(struct hci_dev *hdev)
{
	set_event_flt_cp ec;
	/* Optional initialization */
	//Clear Event Filters
	ec.flt_type  = FLT_CLEAR_ALL;
	hci_send_cmd((void*)hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, (void*)(&ec));
	__bt_print_to_sdc(hdev);
	__delay(1);
	//write scan enable
	hci_scan_req(hdev);
	__bt_print_to_sdc(hdev);
	__delay(1);
	//write authen disable
	hci_auth_req(hdev);
	__bt_print_to_sdc(hdev);
	__delay(1);
	//write voice setting
	hci_send_cmd((void*)hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING, 2, (void*)(&(hdev->voice_setting)));
	__bt_print_to_sdc(hdev);
	__delay(1);
	//set event filter,set auto accept
	ec.flt_type = FLT_CONN_SETUP;
	ec.cond_type = CONN_SETUP_ALLOW_ALL;
	ec.condition = CONN_SETUP_AUTO_ON;
	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 3, (void*)(&ec)); 
	__bt_print_to_sdc(hdev);
	__delay(1);
	//Connection accept timeout ~20 secs
	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_CA_TIMEOUT, 2, (void*)(&(hdev->conn_accept_timeout)));
	__bt_print_to_sdc(hdev);
	__delay(1);
	//Page timeout secs
	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, (void*)(&(hdev->page_timeout)));
	__bt_print_to_sdc(hdev);
	__delay(1);
	while((hdev->port->rx_buffer_status==SDC_BUFFER_DATA)||(hdev->port->rx_buffer_status==SDC_BUFFER_FULL))
	{
		hci_event_packet(hdev);
	}

}

void HCI_master_create_acl_conn(struct hci_dev *hdev)
{
	hci_inq_req(hdev);
	__bt_print_to_sdc(hdev);
	__delay(10);
	while(hdev->inqu_flags)
	{
		while((hdev->port->rx_buffer_status==SDC_BUFFER_DATA)||(hdev->port->rx_buffer_status==SDC_BUFFER_FULL))
		{
			hci_event_packet(hdev);;
		}
	}
	hci_create_connect( hdev, (char*)(hdev->hci_inquiry_info.bdaddr));
	__bt_print_to_sdc(hdev);
	__delay(5);
	while(hdev->link_flags)
	{
		while((hdev->port->rx_buffer_status==SDC_BUFFER_DATA)||(hdev->port->rx_buffer_status==SDC_BUFFER_FULL))
		{
			hci_event_packet(hdev);;
		}
	}
}
unsigned char acl_demo_data[15]={0x02,0x01,0x20,0x0A,0x00,0x06,0x00,0x01,0x00,0x48,0x45,0x4C,0x4C,0x4F,0x00};
void HCI_Send_acl_demo(struct hci_dev *hdev)
{
	int i;
	for(i=0;i<15;i++)
	{
		HCI_Put_char(hdev, *(acl_demo_data+i));
	}
	__bt_print_to_sdc(hdev);

}

void HCI_SCO_conn(struct hci_dev *hdev)
{
	hdev->link_flags=1;
	hci_add_sco_conn(hdev);
	while(!(hdev->link_flags))
	{
		while((hdev->port->rx_buffer_status==SDC_BUFFER_DATA)||(hdev->port->rx_buffer_status==SDC_BUFFER_FULL))
		{
			hci_event_packet(hdev);;
		}
	}
}

⌨️ 快捷键说明

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