?? hci.c
字號:
/*
********************************************************************************
*
* 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 + -