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