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

📄 hci.c

📁 S3C2410平台下蓝牙编程与实验
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
********************************************************************************
*                                               
*                       Embedded Systems Building Blocks                                 
*                    Complete and Ready-to-use Modules in C
*                                                         
*                                 HCI DRIVERS  	                                   
*                                                                                                    
*                  (c) Copyright 2004,chenna,watertek Shenzhen                              
*                             All Rights Reserved                                           
*
*Filename   : hci.c
*Programmer : chenna
********************************************************************************
*                                 DESCRIPTION
* 
********************************************************************************
*/

/*
********************************************************************************
*                                INCLUDE FILES
********************************************************************************
*/

#include "HCI.H"
#include "sd_extr.h"
/*
********************************************************************************
*                               LOCAL CONSTANTS
********************************************************************************
*/


/*
********************************************************************************
*                               GLOBAL VARIABLES
********************************************************************************
*/


/*
********************************************************************************
*                          LOCAL FUNCTIONS PROTOTYPES
********************************************************************************
*/


/*
********************************************************************************
*                         GLOBAL FUNCTIONS PROTOTYPES
********************************************************************************
*/


/*
********************************************************************************
*    					   
*
*Description :
*Arguments   :
*Retruns     :
********************************************************************************
*/
/*
********************************************************************************
*										把指定长度的数据从源地址拷贝到目的地址
* 功	能:把指定长度的数据从源地址拷贝到目的地址
********************************************************************************
*/

int __bt_mem_cpy(void * dst,void *src,int len)
{
	int i;
	for(i=0;i<len;i++)
	{
		*((char*)dst+i) = *((char*)src+i);
	}
	return 0;

}

/*
********************************************************************************
*										地址的比较
* 功	能:比较两断内存的地址是否相等,如果相等就返回0,否则返回-1;
********************************************************************************
*/

int __bt_mem_cmp(void* buff1,void* buff2,int length)
{
	int i;
	for(i=0;i<length;i++)
	{
		if(!(*((char*)buff1+i) == (*((char*)buff2+i))))
			return -1;
	}
	return 0;
}


/*
********************************************************************************
*										将某块内存设置成指定的数据
* 功	能:将以buff为起始的count个字节设置为数据ch
********************************************************************************
*/

void __bt_mem_set(void *buff,char ch,unsigned count)
{
	int i;
	for(i =0;i<count;i++)
	{
		*((char *)(buff)+i) =(char) ch;
	}
	
}


/*
********************************************************************************
*										大小模式的转换
* 功	能:实现半字的高低两byte数据的交换,即实现大小模式的转换
********************************************************************************
*/

UINT16 __host_to_hci_16(UINT16 i)
{
	//This function is used when the host and hci communications a 2 bytes logic block.this function can covert the byte order to the correct
	/*
	int temp;
	temp = (i&0xff)<<8;
	i =temp| (i>>8);*/
	return i;
}

/*
********************************************************************************
*										大小模式的转换
* 功	能:实现半字的高低两byte数据的交换,即实现大小模式的转换
********************************************************************************
*/

UINT16 __hci_to_host_16(UINT16 i)
{
	i =__host_to_hci_16(i);
	return i;
}


/*
********************************************************************************
*										输出
* 功	能:将HCI_Tx_buff[1024]里面的内容输出出来,通过AXD的semihosting功能,输出在AXD的console控制台里面
********************************************************************************
*/
__inline int HCI_Put_char(struct hci_dev *hdev,char ch)
{
	int new_write;
	new_write=hdev->HCI_tx_buffer_write+1;
	if(new_write>=256)
	{
		new_write = 0;
	}
	if(new_write==hdev->HCI_tx_buffer_read)
	{
		hdev->HCI_tx_buffer_status=HCI_TX_BUFF_FULL;
		return HCI_TX_BUFF_FULL;
	}
	hdev->HCI_tx_buffer[hdev->HCI_tx_buffer_write]=ch;
	hdev->HCI_tx_buffer_write=new_write;
	return HCI_TX_BUFF_DATA;	
}
__inline unsigned char HCI_Get_char(struct hci_dev *hdev)
{
	
	unsigned char data;
	if(hdev->HCI_tx_buffer_read != hdev->HCI_tx_buffer_write)
	{
		data = hdev->HCI_tx_buffer[hdev->HCI_tx_buffer_read++];
		if(hdev->HCI_tx_buffer_read==256)
		{
			hdev->HCI_tx_buffer_read=0;
		}
		if(hdev->HCI_tx_buffer_read==hdev->HCI_tx_buffer_write)
		{
			hdev->HCI_tx_buffer_status = HCI_TX_BUFF_EMPTY;
		}else
		{
			hdev->HCI_tx_buffer_status = HCI_TX_BUFF_DATA;
		}
	}
	return data;
}
__inline void __bt_print_to_sdc(struct hci_dev *hdev)
{
	unsigned char ch;
	while(hdev->HCI_tx_buffer_read != hdev->HCI_tx_buffer_write)
	{
		ch = HCI_Get_char(hdev);
	#ifdef DEBUG
		printf("%x ",ch);
	#else
		SDC_Put_Char(ch, hdev->port);
	#endif
	//	hdev->HCI_tx_buffer_read++;
	}
	
}

/*
********************************************************************************
*										延时
* 功	能:延时
********************************************************************************
*/
void __delay(int counter)
{
	int i;
	for(i=0;i<5000*counter;i++)
	{}
}
/*
__inline void hci_req_complete(struct hci_dev *hdev, int result)
{
	if (hdev->req_status == HCI_REQ_PEND) {
		hdev->req_result = result;
		hdev->req_status = HCI_REQ_DONE;
	}

}

*/
/*
********************************************************************************
    							HCI Commands
********************************************************************************
*/

/*
***********************************************************************************************************
*										发送命令
* 功	能:蓝牙发送命令是以小模式来发送的,按照byte为单位,从lsb开始发送,msb发送在最后。
*			这个函数把要发送的命令及其参数按照小模式的格式发再HCI_Tx_buff里面,等待发送。
***********************************************************************************************************
*/

void hci_send_cmd(struct hci_dev *hdev,UINT16 ogf,UINT8 ocf,UINT32 plen,void *param)
{
	int i;
	hci_command_hdr hc;
	//int len = 1 + HCI_COMMAND_HDR_SIZE + plen;//add the pkt indicator
	hc.opcode = cmd_opcode_pack(ogf,ocf);	/* remember to invert the order*/
	hc.plen = plen;
	//tx the packet indicator
	HCI_Put_char(hdev,(unsigned char)HCI_COMMAND_PKT);
	//tx the command hdr 
	for(i=0;i<HCI_COMMAND_HDR_SIZE;i++)
		HCI_Put_char(hdev,*((unsigned char*)&hc+i));
	//put the parameter
	for(i=0;i<plen;i++)
		HCI_Put_char(hdev,*((char*)param+i));
}
/*
***********************************************************************************************************
*										hci_inquiry
* 功	能:发送inquiry命令,查询周围的蓝牙设备
***********************************************************************************************************
*/

void hci_inq_req(struct hci_dev *hdev)
{
 	inquiry_cp *ic;
  	/* Start Inquiry */
  	//hdev->req_status = HCI_REQ_PEND;
	ic = &(hdev->ic);
  	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, (void*)ic);
}
/*
***********************************************************************************************************
*										hci_conn_add
* 功	能:将与指定的蓝牙地址的蓝牙设备的连接信息添加到hci_conn_array[4]里面
***********************************************************************************************************
*/

void hci_conn_add(struct hci_dev *hdev,UINT16 handle,UINT8 type,char *dst)
{
	
	int i;
	if(hdev->hci_connection.hci_c_info.handle==handle||hdev->hci_connection.hci_c_info.handle==NULL)
	{
		hdev->hci_connection.hci_c_info.handle=handle;
		__bt_mem_cpy((void*)hdev->hci_connection.hci_c_info.dst,(void*)dst,6);
		if(type)//acl link
		{
			hdev->hci_connection.acl_conn_info.link_type = type;
			hdev->hci_connection.acl_conn_info.acl_link_flags = 1;
			hdev->hci_connection.sco_conn_info[0].sco_link_flags = 0;
			hdev->hci_connection.sco_conn_info[1].sco_link_flags = 0;
		}
		else{
			for(i=0;i<2;i++)
				if(!(hdev->hci_connection.sco_conn_info[i].sco_link_flags))
				{
					hdev->hci_connection.sco_conn_info[i].link_type = type;
					hdev->hci_connection.sco_conn_info[i].sco_link_flags = 1;
					return;
				}
		}
	}
}

void hci_conn_del(struct hci_dev *hdev)
{
	hdev->hci_connection.hci_c_info.handle=NULL;
	hdev->hci_connection.sco_conn_info[0].sco_link_flags = 0;
	hdev->hci_connection.sco_conn_info[1].sco_link_flags = 0;
}

/*
***********************************************************************************************************
*										hci create connection
* 功	能:发送创建连接命令命令,与指定蓝牙地址的蓝牙设备建立连接
***********************************************************************************************************
*/

//hci command:hci create connection
int hci_create_connect(struct hci_dev *hdev,char *bdaddr)
{
	create_conn_cp cc;
	UINT16 clock_offset;
	cc.pscan_rep_mode = hdev->hci_inquiry_info.pscan_rep_mode;
	cc.pscan_mode = hdev->hci_inquiry_info.pscan_mode;
	clock_offset = (hdev->hci_inquiry_info.clock_offset) & 0x8000;
	__bt_mem_cpy((void*)&cc.bdaddr,(void*)bdaddr,6);
	cc.pkt_type = hdev->hci_device_info.pkt_type;
	cc.clock_offset = clock_offset;
	cc.role_switch = (hdev->hci_device_info.features[0] & LMP_RSWITCH) ? 0x01:0x00;
	hci_send_cmd(hdev,OGF_LINK_CTL,OCF_CREATE_CONN,CREATE_CONN_CP_SIZE,(void*)&cc);
	return 0;
}

/*
***********************************************************************************************************
*										hci disconnect
* 功	能:发送断开连接命令命令,并给出断开连接的原因
***********************************************************************************************************
*/

int hci_disconnect(struct hci_dev *hdev,UINT8 reason)
{
	disconnect_cp dc;
	dc.handle = (UINT16)(hdev->hci_connection.hci_c_info.handle);
	dc.reason = reason;
	hci_send_cmd(hdev,OGF_LINK_CTL,OCF_DISCONNECT,DISCONNECT_CP_SIZE,(void*)&dc);
	return 0;
}


/*
***********************************************************************************************************
*										add sco connection
* 功	能:发送添加sco连接命令,创建sco连接
***********************************************************************************************************
*/

int hci_add_sco_conn(struct hci_dev *hdev)
{
	add_sco_con_cp asc;
	asc.handle = (UINT16)(hdev->hci_connection.hci_c_info.handle);
	asc.pkt_type = hdev->hci_device_info.pkt_type;
	hci_send_cmd(hdev,OGF_LINK_CTL,OCF_ADD_SCO_CONN,ADD_SCO_CONN_SIZE,(void*)&asc);
	return 0;
}

/*
***********************************************************************************************************
*										hci accept connnection requst
* 功	能:发送接收远方蓝牙设备建立连接命令
***********************************************************************************************************
*/

int hci_accept_conn_req(struct hci_dev *hdev)
{
	accept_conn_req_cp acr;
	hdev->req_status = HCI_REQ_PEND;
	__bt_mem_cpy((void*)(acr.bdaddr),(void*)(hdev->hci_inquiry_info.bdaddr),6);//
	acr.role = (hdev->hci_device_info.features[0] & LMP_RSWITCH) ? 0x01:0x00;
	hci_send_cmd(hdev,OGF_LINK_CTL,OCF_ACCEPT_CONN_REQ,ACCEPT_CONN_REQ_CP_SIZE,(void*)&acr);
	return 0;
}

/*
***********************************************************************************************************
*										拒绝建立连接请求
* 功	能:发送拒绝建立连接请求命令

⌨️ 快捷键说明

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