📄 bt_hci.cpp
字号:
#include "StdAfx.h"
#include ".\bt_hci.h"
CBT_HCI::CBT_HCI(void)
{
m_dwDeviceMode = BT_DEVICE_RS232;
m_HCI_LAP[0] = 0x33;
m_HCI_LAP[1] = 0x8B;
m_HCI_LAP[2] = 0x9E;
}
/*
struct SA
{
char aa[10];
char ab[10];
}sa;
queue<SA> qa;
void fa(void)
{
SA sb;
sb.aa[0] = 1;
sb.ab[1] = 2;
sa = sb;
qa.push(sa);
}
*/
CBT_HCI::~CBT_HCI(void)
{
}
// Response from HCI_EVT_COMAND_COMMPLETE
// Status Num_Current_IAC IAC_LAP (Response)
// 1 Byte 1 Byte 3 Bytes
DWORD CBT_HCI::cmd_HCI_Read_Current_IAC_LAP()
{
BYTE bParameter[HCI_CMD_READ_CURRENT_ICA_LAP];
BYTE bCmdGroup,bEvtCode,bEventLen;
BYTE bEvent[256];
DWORD dwResult = HCI_COMMANDERROR_OK;
SendCommand(HCI_COMMAND_GROUPING,
HCI_CMD_READ_CURRENT_ICA_LAP,HCI_CMD_READ_CURRENT_ICA_LAP_LEN,
bParameter);
do
{
dwResult = GetResponse(bCmdGroup,bEvtCode,bEventLen,bEvent,500);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
dwResult = evt_HCI_Event_Grouping(HCI_CMD_READ_CURRENT_ICA_LAP,bEvtCode,bEvent);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
}while (HCI_EVT_COMMAND_COMPLETE != bEvtCode );
return dwResult;
}
// LAP Inquiry_Len Num_Response
// 3 Byte 1 Byte 1 Byte
DWORD CBT_HCI::cmd_HCI_Inquiry()
{
BYTE bParameter[HCI_CMD_INQUIRY] = {0x33,0x8B,0x9E,0x0A,0x40};
BYTE bCmdGroup,bEvtCode,bEventLen;
BYTE bEvent[256];
DWORD dwResult = HCI_COMMANDERROR_OK;
m_vBT_Slaver_Device.clear();
dwResult = cmd_HCI_Read_Current_IAC_LAP();
if (HCI_COMMANDERROR_OK == dwResult)
{
memcpy(bParameter,m_HCI_LAP,HCI_LAP_LEN);
SendCommand(HCI_COMMAND_GROUPING,HCI_CMD_INQUIRY,HCI_CMD_INQUIRY_LEN,bParameter);
do
{
dwResult = GetResponse(bCmdGroup,bEvtCode,bEventLen,bEvent,0x0A*1280);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
dwResult = evt_HCI_Event_Grouping(HCI_CMD_INQUIRY,bEvtCode,bEvent);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
}while (HCI_EVT_INQUIRY_COMPLETE != bEvtCode );
}
return dwResult;
}
// BD_ADDR Packet_Type Page_Scan_Repetition_Mode PS_Mode Clock_Offset Allow_Role_Switch
// 6 Byte 2 Byte 1 Byte 1 Byte 2 Byte 1 Byte
DWORD CBT_HCI::cmd_HCI_Create_Connection(BYTE bDeviceIndex)
{
BYTE bParameter[HCI_CMD_CREATE_CONNECTION_LEN] = {0};
BYTE bCmdGroup,bEvtCode,bEventLen;
BYTE bEvent[256];
DWORD dwResult = HCI_COMMANDERROR_OK;
BT_SLAVER_DEVICE SDevice;
if (bDeviceIndex>=0 && bDeviceIndex<m_vBT_Slaver_Device.size())
{
SDevice = m_vBT_Slaver_Device[bDeviceIndex];
memcpy(bParameter+00,SDevice.s_BD_ADDR,BT_BD_ADDR_LEN);
memcpy(bParameter+10,SDevice.s_bClosck_Offset,2);
bParameter[ 8] = SDevice.s_bPage_Scan_Repetition;
bParameter[ 9] = SDevice.s_bPage_Scan_Mode;
bParameter[ 6] = 0x18;
bParameter[ 7] = 0xCC;
bParameter[12] = 0x00;
SendCommand(HCI_COMMAND_GROUPING,HCI_CMD_CREATE_CONNECTION,HCI_CMD_CREATE_CONNECTION_LEN,bParameter);
do
{
dwResult = GetResponse(bCmdGroup,bEvtCode,bEventLen,bEvent,5000);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
dwResult = evt_HCI_Event_Grouping(HCI_CMD_CREATE_CONNECTION,bEvtCode,bEvent,bDeviceIndex);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
}while (HCI_EVT_CONNECTION_COMPLETE_EVENT != bEvtCode );
}
else
{
dwResult = ERROR_INDEX;
}
return dwResult;
}
// Connnection_Handle Reason
// 2 Byte 1 Byte
DWORD CBT_HCI::cmd_HCI_Disconnection(BYTE bDeviceIndex)
{
BYTE bParameter[HCI_CMD_CREATE_CONNECTION_LEN] = {0};
BYTE bCmdGroup,bEvtCode,bEventLen;
BYTE bEvent[256];
DWORD dwResult = HCI_COMMANDERROR_OK;
BT_SLAVER_DEVICE SDevice;
if (bDeviceIndex>=0 && bDeviceIndex<m_vBT_Slaver_Device.size())
{
SDevice = m_vBT_Slaver_Device[bDeviceIndex];
memcpy(bParameter+00,SDevice.s_bConnection_Handle,2);
bParameter[2] = 0x13;
SendCommand(HCI_COMMAND_GROUPING,HCI_CMD_DISCONNECT,HCI_CMD_DISCONNECT_LEN,bParameter);
do
{
dwResult = GetResponse(bCmdGroup,bEvtCode,bEventLen,bEvent,5000);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
dwResult = evt_HCI_Event_Grouping(HCI_CMD_DISCONNECT,bEvtCode,bEvent,bDeviceIndex);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
}while (HCI_EVT_DISCONNECTION_COMPLETE_EVENT != bEvtCode );
}
else
{
dwResult = ERROR_INDEX;
}
return dwResult;
}
// BD_ADDR Page_Scan_Repetition_Mode PS_Mode Clock_Offset
// 6 Byte 1 Byte 1 Byte 2 Byte
DWORD CBT_HCI::cmd_HCI_Remote_Name_Request(BYTE bDeviceIndex)
{
BYTE bParameter[HCI_CMD_REMOTE_NAME_REQUEST_LEN] = {0};
BYTE bCmdGroup,bEvtCode,bEventLen;
BYTE bEvent[256];
DWORD dwResult = HCI_COMMANDERROR_OK;
BT_SLAVER_DEVICE SDevice;
if (bDeviceIndex>=0 && bDeviceIndex<m_vBT_Slaver_Device.size())
{
SDevice = m_vBT_Slaver_Device[bDeviceIndex];
memcpy(bParameter+0,SDevice.s_BD_ADDR,BT_BD_ADDR_LEN);
memcpy(bParameter+8,SDevice.s_bClosck_Offset,2);
bParameter[ 6] = SDevice.s_bPage_Scan_Repetition;
bParameter[ 7] = SDevice.s_bPage_Scan_Mode;
SendCommand(HCI_COMMAND_GROUPING,HCI_CMD_REMOTE_NAME_REQUEST,HCI_CMD_REMOTE_NAME_REQUEST_LEN,bParameter);
do
{
dwResult = GetResponse(bCmdGroup,bEvtCode,bEventLen,bEvent,5000);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
dwResult = evt_HCI_Event_Grouping(HCI_CMD_REMOTE_NAME_REQUEST,bEvtCode,bEvent,bDeviceIndex);
if (HCI_COMMANDERROR_OK != dwResult )
{
break;
}
}while (HCI_EVT_REMOTE_NAME_REQUEST_COMPLETE_EVENT != bEvtCode);
}
else
{
dwResult = ERROR_INDEX;
}
return dwResult;
}
// HCI_COMMAND
// Command OpCode Lenght
// 2 Byte 1 Byte
DWORD CBT_HCI::SendCommand(BYTE bCmdGroup,WORD wOpCode,BYTE bCmdLen,BYTE* pCmd)
{
UINT uExternLen = 0;
BYTE* pBuffer = new BYTE[256];
if (BT_DEVICE_RS232 == m_dwDeviceMode || BT_DEVICE_UART == m_dwDeviceMode) // RS232 OR UART
{
uExternLen = 4;
pBuffer[0] = bCmdGroup;
pBuffer[1] = wOpCode & 0xFF;
pBuffer[2] = (wOpCode >> 8) & 0xFF;
pBuffer[3] = bCmdLen;
}
else if (BT_DEVICE_USB == m_dwDeviceMode) // USB
{
uExternLen = 3;
pBuffer[0] = wOpCode & 0xFF;
pBuffer[1] = (wOpCode >> 8) & 0xFF;
pBuffer[2] = bCmdLen;
}
memcpy(pBuffer+uExternLen,pCmd,bCmdLen);
Send(pBuffer,uExternLen+bCmdLen);
delete []pBuffer;
return 0;
}
// HCI EVENT
// EVENT Code Length
// 1 Byte 1 Byte
DWORD CBT_HCI::GetResponse(BYTE& bCmdGroup,BYTE& bEventCode,BYTE& bEventLen, BYTE* pEvent,DWORD dwMillisecond)
{
BYTE* pBuffer = NULL;
BYTE bTemp[3];
UINT uReceiveLen(0);
DWORD dwResult = HCI_COMMANDERROR_OK;
if (BT_DEVICE_RS232 == m_dwDeviceMode || BT_DEVICE_UART == m_dwDeviceMode) // RS232 OR UART
{
uReceiveLen = 3;
}
else if (BT_DEVICE_USB == m_dwDeviceMode) // USB
{
uReceiveLen = 2;
}
dwResult = Receive(bTemp,uReceiveLen,dwMillisecond);
if (TRUE == dwResult)
{
if (BT_DEVICE_RS232 == m_dwDeviceMode || BT_DEVICE_UART == m_dwDeviceMode) // RS232 OR UART
{
bCmdGroup = bTemp[0];
bEventCode = bTemp[1];
uReceiveLen = bEventLen = bTemp[2];
}
else if (BT_DEVICE_USB == m_dwDeviceMode) // USB
{
bEventCode = bTemp[0];
uReceiveLen = bEventLen = bTemp[1];
}
dwResult = Receive(pEvent,uReceiveLen,100 * bEventLen);
if (FALSE == dwResult)
{
dwResult = HCI_COMMANDERROR_TIMEOUTS;
}
else
{
dwResult = HCI_COMMANDERROR_OK;
}
}
else
{
dwResult = HCI_COMMANDERROR_TIMEOUTS;
}
return dwResult;
}
DWORD CBT_HCI::evt_HCI_Event_Grouping(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
DWORD dwResult = HCI_COMMANDERROR_OK;
switch(bEvtCode)
{
case HCI_EVT_INQUIRY_COMPLETE:
evt_HCI_Inquiry_Complete(wOpCode,bEvtCode,pEvent,bIndex);
break;
case HCI_EVT_INQUIRY_RESULT_EVENT:
evt_HCI_Inquiry_Result_Event(wOpCode,bEvtCode,pEvent,bIndex);
break;
case HCI_EVT_CONNECTION_COMPLETE_EVENT:
evt_HCI_Connection_Complete_Event(wOpCode,bEvtCode,pEvent,bIndex);
break;
case HCI_EVT_CONNECTION_REQUEST_EVENT:
break;
case HCI_EVT_DISCONNECTION_COMPLETE_EVENT:
evt_HCI_Disconnection_Complete_Event(wOpCode,bEvtCode,pEvent,bIndex);
break;
case HCI_EVT_AUTHENTICATION_COMPLETE_EVENT:
break;
case HCI_EVT_REMOTE_NAME_REQUEST_COMPLETE_EVENT:
evt_HCI_Remote_Name_Request_Complete_Event(wOpCode,bEvtCode,pEvent,bIndex);
break;
case HCI_EVT_ENCRYPTION_CHANGE_EVENT:
break;
case HCI_EVT_CHANGE_CONNECTION_LINK_COMPLETE:
break;
case HCI_EVT_MASTER_LINK_KEY_COMPLETE_EVENT:
break;
case HCI_EVT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT:
break;
case HCI_EVT_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT:
break;
case HCI_EVT_QOS_SETUP_COMPLETE_EVENT:
break;
case HCI_EVT_COMMAND_COMPLETE:
evt_HCI_Command_Complete(wOpCode,bEvtCode,pEvent,bIndex);
break;
case HCI_EVT_COMMAND_STATUS_EVENT:
evt_HCI_Command_Status_Event(wOpCode,bEvtCode,pEvent,bIndex);
break;
default:
break;
}
return dwResult;
}
// Status
// 1 Byte
DWORD CBT_HCI::evt_HCI_Inquiry_Complete(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
// DWORD dwResult = HCI_COMMANDERROR_OK;
return pEvent[0];//dwResult;
}
// Num_Responses BD_ADDR Page_Scan_Repetition_Mode PS_Period_Mode PS_Mode Class_Of_Device Clock_Offset
// 1 Byte 6 Byte 1 Byte 1 Byte 1 Byte 3 Byte 2 Byte
DWORD CBT_HCI::evt_HCI_Inquiry_Result_Event(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
DWORD dwResult = HCI_COMMANDERROR_OK;
BT_SLAVER_DEVICE SDevice;
memset(&SDevice,0,sizeof(BT_SLAVER_DEVICE));
memcpy(SDevice.s_BD_ADDR, pEvent+1 ,BT_BD_ADDR_LEN);
memcpy(SDevice.s_bClosck_Offset,pEvent+13,2);
SDevice.s_bPage_Scan_Repetition = *(pEvent+7);
SDevice.s_bPage_Scan_Period_Mode = *(pEvent+8);
SDevice.s_bPage_Scan_Mode = *(pEvent+9);
m_vBT_Slaver_Device.push_back(SDevice);
return dwResult;
}
// Status Connection_Handle BD_ADDR Link_Type Encrypton_mode
// 1 Byte 2 Byte(12 bits) 6 Byte 1 Byte 1 Byte
DWORD CBT_HCI::evt_HCI_Connection_Complete_Event(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
DWORD dwResult = HCI_COMMANDERROR_OK;
BT_SLAVER_DEVICE* pSDevice;
if (bIndex >= 0 && bIndex < m_vBT_Slaver_Device.size())
{
pSDevice = &(m_vBT_Slaver_Device[bIndex]);
if (memcmp(pSDevice->s_BD_ADDR,pEvent+3,BT_BD_ADDR_LEN) == 0)
{
if (HCI_COMMANDERROR_OK == pEvent[0] || HCI_COMMANDERROR_ACL_CONNECTION_ALREADY_EXISTS == pEvent[0])
{
memcpy(pSDevice->s_bConnection_Handle, pEvent+1 ,2);
pSDevice->s_bLink_Type = *(pEvent+9);
pSDevice->s_fConnection = TRUE;
}
else
{
dwResult = pEvent[0];
}
}
else
{
dwResult = HCI_COMMANDERROR_NOT_MATCH_ADDRESS;
}
}
else
{
dwResult = ERROR_INDEX;
}
return dwResult;
}
// Status Connection_Handle Reason
// 1 Byte 2 Byte(12 bits) 1 Byte
DWORD CBT_HCI::evt_HCI_Disconnection_Complete_Event(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
DWORD dwResult = HCI_COMMANDERROR_OK;
BT_SLAVER_DEVICE* pSDevice;
if (bIndex >= 0 && bIndex < m_vBT_Slaver_Device.size())
{
pSDevice = &(m_vBT_Slaver_Device[bIndex]);
if (memcmp(pSDevice->s_bConnection_Handle,pEvent+1,2) == 0)
{
if (HCI_COMMANDERROR_OK == pEvent[0])
{
pSDevice->s_fConnection = FALSE;
}
else
{
dwResult = pEvent[3] << 8 || pEvent[0];
}
}
else
{
dwResult = HCI_COMMANDERROR_NOT_MATCH_CONNECTION_HANDLE;
}
}
else
{
dwResult = ERROR_INDEX;
}
return dwResult;
}
// Num_HCI_Command_Packets Command_OpCode Return_Parameter
// 1 Byte 2 Byte ... ...
DWORD CBT_HCI::evt_HCI_Command_Complete(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
DWORD dwResult = HCI_COMMANDERROR_OK;
if (wOpCode == (pEvent[1] | (pEvent[2] << 8)))
{
switch(wOpCode)
{
case HCI_CMD_READ_CURRENT_ICA_LAP:
if (HCI_COMMANDERROR_OK == pEvent[3])
{
memcpy(m_HCI_LAP,pEvent+5,HCI_LAP_LEN);
}
else
{
dwResult = pEvent[3];
}
break;
default:
break;
}
}
else //don't match command
{
dwResult = HCI_COMMANDERROR_NOT_MATCH;
}
return dwResult;
}
// Status BD_ADDR Remote_Name
// 1 Byte 6 Byte 248 Byte
DWORD CBT_HCI::evt_HCI_Remote_Name_Request_Complete_Event(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
DWORD dwResult = HCI_COMMANDERROR_OK;
BT_SLAVER_DEVICE* pSDevice;
if (bIndex >= 0 && bIndex < m_vBT_Slaver_Device.size())
{
pSDevice = &(m_vBT_Slaver_Device[bIndex]);
if (memcmp(pSDevice->s_BD_ADDR,pEvent+1,BT_BD_ADDR_LEN) == 0)
{
if (HCI_COMMANDERROR_OK == pEvent[0])
{
memcpy(pSDevice->s_bRemote_Name, pEvent+7 ,REMOTE_NAME_LEN);
}
else
{
dwResult = pEvent[0];
}
}
else
{
dwResult = HCI_COMMANDERROR_NOT_MATCH_ADDRESS;
}
}
else
{
dwResult = ERROR_INDEX;
}
return dwResult;
}
// Status Num_Responses Command_OpCode
// 1 Byte 1 Byte 2 Byte
DWORD CBT_HCI::evt_HCI_Command_Status_Event(WORD wOpCode,BYTE bEvtCode,BYTE* pEvent,BYTE bIndex)
{
DWORD dwResult = HCI_COMMANDERROR_OK;
if (wOpCode == (pEvent[2] | (pEvent[3] << 8)))
{
switch(wOpCode)
{
case HCI_CMD_CREATE_CONNECTION:
dwResult = pEvent[0];
break;
default:
break;
}
}
else //don't match command
{
dwResult = HCI_COMMANDERROR_NOT_MATCH;
}
return dwResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -