www.pudn.com > fbt-a3-20041206.zip > hcilocal.cpp, change:2004-03-08,size:19933b
// Copyright (c) 2004, Antony C. Roberts
// Use of this file is subject to the terms
// described in the LICENSE.TXT file that
// accompanies this file.
//
// Your use of this file indicates your
// acceptance of the terms described in
// LICENSE.TXT.
//
// http://www.freebt.net
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <winioctl.h>
#include <tchar.h>
#include "fbtutil.h"
#include "fbtHciLocal.h"
CHciLocal::CHciLocal() : CHci()
{
fbtLog(fbtLog_Enter, _T("CHciLocal::CHciLocal: Enter"));
InitializeCriticalSection(&m_QueueCriticalSection);
for (int i=0; i<MAX_QUEUED_COMMANDS; i++)
{
memset(&(m_QueuedCommands[i]), 0, sizeof(QueuedCommand));
m_QueuedCommands[i].hEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
}
fbtLog(fbtLog_Exit, _T("CHciLocal::CHciLocal: Exit"));
}
CHciLocal::~CHciLocal()
{
FBT_TRY
for (int i=0; i<MAX_QUEUED_COMMANDS; i++)
CloseHandle(m_QueuedCommands[i].hEvent);
FBT_CATCH_NORETURN
}
// Find a free slot for the command and queue it
int CHciLocal::QueueCommand(USHORT nCommand, BYTE *pResultBuffer, DWORD dwBufferSize)
{
FBT_TRY
// Stop any other threads from trampling over our
// slot allocation
EnterCriticalSection(&m_QueueCriticalSection);
BOOL bFoundSlot=FALSE;
int i=0;
while (i<MAX_QUEUED_COMMANDS && !bFoundSlot)
{
if (m_QueuedCommands[i].nCommand==0)
{
m_QueuedCommands[i].nCommand=nCommand;
bFoundSlot=TRUE;
}
else
i++;
}
LeaveCriticalSection(&m_QueueCriticalSection);
if (i==MAX_QUEUED_COMMANDS)
return -1;
ResetEvent(m_QueuedCommands[i].hEvent);
m_QueuedCommands[i].pResultBuffer=pResultBuffer;
m_QueuedCommands[i].dwBufferSize=dwBufferSize;
fbtLog(fbtLog_Verbose, "CHciLocal::QueueCommand: Queue OGF=0x%02x OCF=0x%02x at slot %d", FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand), i);
return i;
FBT_CATCH_RETURN(-1)
}
int CHciLocal::QueueCommandStatus(USHORT nCommand)
{
FBT_TRY
PFBT_HCI_COMMAND_STATUS pCommandStatus=(PFBT_HCI_COMMAND_STATUS)malloc(sizeof(FBT_HCI_COMMAND_STATUS));
memset(pCommandStatus, 0, sizeof(FBT_HCI_COMMAND_STATUS));
return QueueCommand(nCommand, (BYTE*)pCommandStatus, sizeof(FBT_HCI_COMMAND_STATUS));
FBT_CATCH_RETURN(-1)
}
void CHciLocal::DeQueueCommand(int nSlot)
{
FBT_TRY
m_QueuedCommands[nSlot].nCommand=0;
m_QueuedCommands[nSlot].pResultBuffer=NULL;
m_QueuedCommands[nSlot].dwBufferSize=0;
FBT_CATCH_NORETURN
}
PQueuedCommand CHciLocal::GetQueuedCommand(int nSlot)
{
FBT_TRY
if (nSlot>MAX_QUEUED_COMMANDS)
return NULL;
return &(m_QueuedCommands[nSlot]);
FBT_CATCH_RETURN(NULL)
}
DWORD CHciLocal::ClearQueue()
{
FBT_TRY
return ERROR_SUCCESS;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::WaitForCommandComplete(int nSlot)
{
FBT_TRY
PQueuedCommand pQueuedCommand=&(m_QueuedCommands[nSlot]);
fbtLog(fbtLog_Notice, _T("CHciLocal::WaitForCommandComplete: Waiting for completion of command OGF=0x%02x OCF=0x%02x"), FBT_HCI_OGF_FROM_COMMAND(pQueuedCommand->nCommand), FBT_HCI_OCF_FROM_COMMAND(pQueuedCommand->nCommand));
DWORD dwResult=WaitForSingleObject(pQueuedCommand->hEvent, INFINITE);
if (dwResult!=WAIT_OBJECT_0)
{
DWORD dwLastError=GetLastError();
fbtLog(fbtLog_Failure, _T("CHciLocal::WaitForCommandComplete: WaitForSingleObject failed, error %d"), dwLastError);
return dwLastError;
}
return ERROR_SUCCESS;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::WaitForCommandStatus(int nSlot, BYTE &nStatus)
{
FBT_TRY
PQueuedCommand pQueuedCommand=&(m_QueuedCommands[nSlot]);
fbtLog(fbtLog_Notice, _T("CHciLocal::WaitForCommandStatus: Waiting for command status of command OGF=0x%02x OCF=0x%02x, at slot %d"), FBT_HCI_OGF_FROM_COMMAND(pQueuedCommand->nCommand), FBT_HCI_OCF_FROM_COMMAND(pQueuedCommand->nCommand), nSlot);
DWORD dwResult=WaitForSingleObject(pQueuedCommand->hEvent, INFINITE);
if (dwResult!=WAIT_OBJECT_0)
{
DWORD dwLastError=GetLastError();
fbtLog(fbtLog_Failure, _T("CHciLocal::WaitForCommandStatus: WaitForSingleObject failed, error %d"), dwLastError);
return dwLastError;
}
PFBT_HCI_COMMAND_STATUS pCommandStatus=(PFBT_HCI_COMMAND_STATUS)pQueuedCommand->pResultBuffer;
nStatus=pCommandStatus->Status;
free(pCommandStatus);
return ERROR_SUCCESS;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendSetEventFilter(BYTE FilterType, BYTE FilterConditionType, BYTE Condition[FBT_HCI_MAX_CONDITION_SIZE], BYTE ConditionBytes)
{
FBT_TRY
fbtLog(fbtLog_Enter, _T("Entered CHciLocal::SendEventFilter"));
BYTE Status=0;
int nSlot=QueueCommand(FBT_HCI_CMD_SET_EVENT_FILTER, &Status, sizeof(Status));
DWORD dwResult=CHci::SendSetEventFilter(FilterType, FilterConditionType, Condition, ConditionBytes);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendSetEventFilter: CHci::SendSetEventFilter Failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
dwResult=WaitForCommandComplete(nSlot);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendSetEventFilter: WaitForCommandComplete failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendSetEventFilter: Complete, Status %x (%s)"), Status, GetStatusText(Status));
DeQueueCommand(nSlot);
return Status;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendInquiry(ULONG LAP, BYTE InquiryLength, BYTE NumResponses)
{
FBT_TRY
int nSlot=QueueCommandStatus(FBT_HCI_CMD_INQUIRY);
DWORD dwResult=CHci::SendInquiry(LAP, InquiryLength, NumResponses);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendInquiry: CHci::SendInquiry Failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
BYTE nStatus=0;
dwResult=WaitForCommandStatus(nSlot, nStatus);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendInquiry: WaitForCommandStatus failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Failure, _T("CHciLocal::SendInquiry: Command completed with status %s (0x%x)"), GetStatusText(nStatus), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendInquiryCancel()
{
FBT_TRY
BYTE nStatus=0;
int nSlot=QueueCommand(FBT_HCI_CMD_INQUIRY_CANCEL, &nStatus, sizeof(nStatus));
DWORD dwResult=CHci::SendInquiryCancel();
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendInquiryCancel: CHci::SendInquiryCancel Failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
dwResult=WaitForCommandComplete(nSlot);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendInquiryCancel: WaitForCommandComplete failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendInquiryCancel: Complete, Status %d"), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendCreateConnection(BYTE BD_ADDR[FBT_HCI_BDADDR_SIZE], USHORT nPacketType, BYTE nPageScanRepetitionMode, BYTE nPageScanMode, USHORT nClockOffset, BYTE nAllowRoleSwitch)
{
FBT_TRY
fbtLog(fbtLog_Enter, _T("CHciLocal::SendCreateConnection: Enter"));
int nSlot=QueueCommandStatus(FBT_HCI_CMD_CREATE_CONNECTION);
DWORD dwResult=CHci::SendCreateConnection(BD_ADDR, nPacketType, nPageScanRepetitionMode, nPageScanMode, nClockOffset, nAllowRoleSwitch);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendCreateConnection: CHci::SendCreateConnection: Failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
BYTE nStatus=0;
dwResult=WaitForCommandStatus(nSlot, nStatus);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendCreateConnection: WaitForCmmandStatus failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendCreateConnection: Complete, %s (0x%02x)"), GetStatusText(nStatus), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendDisconnect(USHORT nConnectionHandle, BYTE nReason)
{
FBT_TRY
fbtLog(fbtLog_Enter, _T("CHciLocal::SendDisconnect: Enter"));
int nSlot=QueueCommandStatus(FBT_HCI_CMD_DISCONNECT);
DWORD dwResult=CHci::SendDisconnect(nConnectionHandle, nReason);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendDisconnect: CHci::SendDisconnect: Failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
BYTE nStatus=0;
dwResult=WaitForCommandStatus(nSlot, nStatus);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendDisconnect: WaitForCmmandStatus failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendDisconnect: Complete, %s (0x%02x)"), GetStatusText(nStatus), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendSwitchRole(BYTE BD_ADDR[FBT_HCI_BDADDR_SIZE], BYTE nRole)
{
FBT_TRY
fbtLog(fbtLog_Enter, _T("CHciLocal::SendSwitchRole: Enter"));
int nSlot=QueueCommandStatus(FBT_HCI_CMD_SWITCH_ROLE);
DWORD dwResult=CHci::SendSwitchRole(BD_ADDR, nRole);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendSwitchRole: CHci::SendSwitchRole: Failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
BYTE nStatus=0;
dwResult=WaitForCommandStatus(nSlot, nStatus);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendSwitchRole: WaitForCmmandStatus failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendSwitchRole: Complete, %s (0x%02x)"), GetStatusText(nStatus), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendRemoteNameRequest(BYTE BD_ADDR[FBT_HCI_BDADDR_SIZE], BYTE nPageScanRepetitionMode, BYTE nPageScanMode, USHORT nClockOffset)
{
FBT_TRY
int nSlot=QueueCommandStatus(FBT_HCI_CMD_REMOTE_NAME_REQUEST);
DWORD dwResult=CHci::SendRemoteNameRequest(BD_ADDR, nPageScanRepetitionMode, nPageScanMode, nClockOffset);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendRemoteNameRequest: CHci::SendRemoteNameRequest Failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
BYTE nStatus=0;
dwResult=WaitForCommandStatus(nSlot, nStatus);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendRemoteNameRequest: WaitForCommandStatus failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Failure, _T("CHciLocal::SendRemoteNameRequest: Command complete, %s (0x%x)"), GetStatusText(nStatus), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendReset()
{
FBT_TRY
BYTE nStatus=0;
int nSlot=QueueCommand(FBT_HCI_CMD_RESET, &nStatus, sizeof(nStatus));
DWORD dwResult=CHci::SendReset();
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendReset: CHci::SendReset failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
dwResult=WaitForCommandComplete(nSlot);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendReset: WaitForCommandComplete failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendReset: Complete, %s (0x%02x)"), GetStatusText(nStatus), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendWriteClassOfDevice(BYTE ClassOfDevice[FBT_HCI_DEVICE_CLASS_SIZE])
{
FBT_TRY
BYTE nStatus=0;
int nSlot=QueueCommand(FBT_HCI_CMD_WRITE_CLASS_OF_DEVICE, &nStatus, sizeof(nStatus));
DWORD dwResult=CHci::SendWriteClassOfDevice(ClassOfDevice);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendWriteClassOfDevice: CHci::SendWriteClassOfDevice failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
dwResult=WaitForCommandComplete(nSlot);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendWriteClassOfDevice: WaitForCommandComplete failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendWriteClassOfDevice: Complete, %s (0x%02x)"), GetStatusText(nStatus), nStatus);
DeQueueCommand(nSlot);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::SendReadLocalVersionInformation(FBT_HCI_READ_LOCAL_VERSION_INFORMATION_COMPLETE &CommandComplete)
{
FBT_TRY
int nSlot=QueueCommand(FBT_HCI_CMD_READ_LOCAL_VERSION_INFORMATION, (LPBYTE)&CommandComplete, sizeof(CommandComplete));
DWORD dwResult=CHci::SendReadLocalVersionInformation();
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendReadLocalVersionInformation: CHci::SendWriteClassOfDevice failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
dwResult=WaitForCommandComplete(nSlot);
if (dwResult!=ERROR_SUCCESS)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::SendReadLocalVersionInformation: WaitForCommandComplete failed, error %d"), dwResult);
DeQueueCommand(nSlot);
return dwResult;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::SendReadLocalVersionInformation: Complete, %s (0x%02x)"), GetStatusText(CommandComplete.Status), CommandComplete.Status);
DeQueueCommand(nSlot);
return CommandComplete.Status;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
// Override superclass in order to provide CommandComplete and CommandStatus wrappers
DWORD CHciLocal::OnEvent(PFBT_HCI_EVENT_HEADER pEvent, DWORD Length)
{
FBT_TRY
switch (pEvent->EventCode)
{
case FBT_HCI_EVENT_COMMAND_COMPLETE:
CommandCompleteHandler(
((PFBT_HCI_COMMAND_COMPLETE)pEvent)->OpCode,
((PFBT_HCI_COMMAND_COMPLETE)pEvent)->Parameters,
((PFBT_HCI_COMMAND_COMPLETE)pEvent)->EventHeader.ParameterLength - (sizeof(FBT_HCI_COMMAND_COMPLETE) - sizeof(FBT_HCI_EVENT_HEADER) - 1));
return ERROR_SUCCESS;
case FBT_HCI_EVENT_COMMAND_STATUS:
CommandStatusHandler(
((PFBT_HCI_COMMAND_STATUS)pEvent)->Status,
((PFBT_HCI_COMMAND_STATUS)pEvent)->OpCode);
return ERROR_SUCCESS;
}
CHci::OnEvent(pEvent, Length);
return ERROR_SUCCESS;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
int CHciLocal::FindCommandSlot(USHORT nCommand)
{
FBT_TRY
for (int i=0; i<MAX_QUEUED_COMMANDS; i++)
{
if (m_QueuedCommands[i].nCommand==nCommand)
{
return i;
}
}
return -1;
FBT_CATCH_RETURN(-1)
}
// Called in the context of the event thread
// Find and complete the corresponding event
DWORD CHciLocal::CommandCompleteHandler(USHORT nCommand, BYTE *pParameters, DWORD dwParameterLength)
{
FBT_TRY
int nSlot=FindCommandSlot(nCommand);
if (nSlot==-1)
{
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandCompleteHandler: Command OGF=0x%02x, OGF=0x%02x, not queued"), FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand));
return ERROR_SUCCESS;
}
PQueuedCommand pQueuedCommand=&(m_QueuedCommands[nSlot]);
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandCompleteHandler: Handling CommandComplete for command OGF=0x%02x, OGF=0x%02x, ParameterLength=%d"), FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand), dwParameterLength);
if (dwParameterLength>pQueuedCommand->dwBufferSize)
{
fbtLog(fbtLog_Failure, _T("CHciLocal::CommandCompleteHandler: Command OGF=0x%02x, OGF=0x%02x complete with %d bytes of parameters, only a %d byte parameter buffer was supplied"), FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand), dwParameterLength, pQueuedCommand->dwBufferSize);
return ERROR_INTERNAL_ERROR;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandCompleteHandler: ParameterLength=%d"), dwParameterLength);
if (dwParameterLength>0)
{
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandCompleteHandler: Status=%02x"), *pParameters);
if (fbtLogGetLevel()>=fbtLog_Verbose)
{
char szLog[1024]={0};
char szBuf[10]={0};
for (UINT i=0; i<dwParameterLength; i++)
{
sprintf(szBuf, "%02x ", pParameters[i]);
strcat(szLog, szBuf);
}
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandCompleteHandler: Parameters: %s"), szLog);
}
CopyMemory(pQueuedCommand->pResultBuffer, pParameters, dwParameterLength);
pQueuedCommand->dwBufferSize=dwParameterLength;
}
SetEvent(pQueuedCommand->hEvent);
return ERROR_SUCCESS;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}
DWORD CHciLocal::CommandStatusHandler(BYTE nStatus, USHORT nCommand)
{
FBT_TRY
int nSlot=FindCommandSlot(nCommand);
if (nSlot==-1)
{
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandStatusHandler: Command OGF=0x%02x, OGF=0x%02x, not queued"), FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand));
return ERROR_SUCCESS;
}
PQueuedCommand pQueuedCommand=&(m_QueuedCommands[nSlot]);
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandStatusHandler: Handling CommandStatus for command OGF=0x%02x, OGF=0x%02x"), FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand));
if (pQueuedCommand->dwBufferSize<sizeof(FBT_HCI_COMMAND_STATUS))
{
fbtLog(fbtLog_Failure, _T("CHciLocal::CommandStatusHandler: Command OGF=0x%02x, OGF=0x%02x, not enough buffer provided (%d)"), FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand), pQueuedCommand->dwBufferSize);
return ERROR_INTERNAL_ERROR;
}
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandStatusHandler: Writing status into buffer at %08x"), pQueuedCommand->pResultBuffer);
PFBT_HCI_COMMAND_STATUS pCommandStatus=(PFBT_HCI_COMMAND_STATUS)pQueuedCommand->pResultBuffer;
pCommandStatus->Status=nStatus;
pQueuedCommand->dwBufferSize=sizeof(FBT_HCI_COMMAND_STATUS);
fbtLog(fbtLog_Notice, _T("CHciLocal::CommandStatusHandler: Command OGF=0x%02x, OGF=0x%02x, status %s on slot %d"), FBT_HCI_OGF_FROM_COMMAND(nCommand), FBT_HCI_OCF_FROM_COMMAND(nCommand), GetStatusText(nStatus), nSlot);
SetEvent(pQueuedCommand->hEvent);
return nStatus;
FBT_CATCH_RETURN(ERROR_INTERNAL_ERROR)
}