Add bidirectional channel configuration -- remote device is not ACKing sent Configuration Requests, needs further debugging. Implement Bluetooth spec's channel states.

Use abbreviations for the structure and function names where possible to try to cut down on the code verbosity.
pull/1469/head
Dean Camera 15 years ago
parent b9c7d19615
commit c77f136661

@ -247,11 +247,12 @@ void Bluetooth_DisconnectionComplete(void)
void Bluetooth_PacketReceived(uint16_t* PacketLength, Bluetooth_Channel_t* Channel) void Bluetooth_PacketReceived(uint16_t* PacketLength, Bluetooth_Channel_t* Channel)
{ {
uint8_t DataPayload[*PacketLength]; uint8_t DataPayload[*PacketLength];
Pipe_Read_Stream_LE(&DataPayload, *PacketLength); Pipe_Read_Stream_LE(&DataPayload, *PacketLength);
*PacketLength = 0; *PacketLength = 0;
BT_ACL_DEBUG("-- Data Payload: ", NULL); printf_P(PSTR("L2CAP Packet Recetion on channel %02X:\r\n"), Channel->LocalNumber);
for (uint16_t B = 0; B < sizeof(DataPayload); B++) for (uint16_t Byte = 0; Byte < *PacketLength; Byte++)
printf("0x%02X ", DataPayload[B]); printf_P(PSTR("0x%02X "), DataPayload[Byte]);
printf("\r\n"); puts_P(PSTR("\r\n"));
} }

@ -31,10 +31,78 @@
#define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C #define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C
#include "BluetoothACLPackets.h" #include "BluetoothACLPackets.h"
void Bluetooth_ProcessACLPackets(void) void Bluetooth_ACLTask(void)
{ {
Bluetooth_ACL_Header_t ACLPacketHeader; Bluetooth_ProcessACLPackets();
Bluetooth_DataPacket_Header_t DataHeader;
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
{
Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
bool MustSendConfigReq = true;
switch (ChannelData->State)
{
case Channel_Config_WaitConfig:
ChannelData->State = Channel_Config_WaitReqResp;
break;
case Channel_Config_WaitSendConfig:
ChannelData->State = Channel_Config_WaitResp;
break;
default:
MustSendConfigReq = false;
break;
}
if (MustSendConfigReq)
{
BT_ACL_Header_t ACLPacketHeader;
BT_DataPacket_Header_t DataHeader;
BT_Signal_Header_t SignalCommandHeader;
BT_Signal_ConfigurationReq_t ConfigurationRequest;
ACLPacketHeader.ConnectionHandle = Bluetooth_Connection.ConnectionHandle;
ACLPacketHeader.DataLength = sizeof(DataHeader) + sizeof(SignalCommandHeader) + sizeof(ConfigurationRequest);
DataHeader.PayloadLength = sizeof(SignalCommandHeader) + sizeof(ConfigurationRequest);
DataHeader.DestinationChannel = BT_CHANNEL_SIGNALING;
SignalCommandHeader.Code = BT_SIGNAL_CONFIGURATION_REQUEST;
SignalCommandHeader.Identifier = ++Bluetooth_Connection.SignallingIdentifier;
SignalCommandHeader.Length = sizeof(ConfigurationRequest);
ConfigurationRequest.DestinationChannel = ChannelData->RemoteNumber;
ConfigurationRequest.Flags = 0;
Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
Pipe_Unfreeze();
Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
Pipe_Write_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader));
Pipe_Write_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
Pipe_Freeze();
#if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("Packet Sent", NULL);
BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader.PayloadLength);
#endif
#if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG(">> L2CAP Configuration Request", NULL);
#endif
#if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
#endif
}
}
}
static void Bluetooth_ProcessACLPackets(void)
{
BT_ACL_Header_t ACLPacketHeader;
BT_DataPacket_Header_t DataHeader;
Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE); Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
Pipe_Unfreeze(); Pipe_Unfreeze();
@ -48,35 +116,35 @@ void Bluetooth_ProcessACLPackets(void)
Pipe_Read_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader)); Pipe_Read_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
Pipe_Read_Stream_LE(&DataHeader, sizeof(DataHeader)); Pipe_Read_Stream_LE(&DataHeader, sizeof(DataHeader));
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("Packet Received", NULL); BT_ACL_DEBUG("Packet Received", NULL);
BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF)); BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader.DataLength); BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader.DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader.PayloadLength); BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader.PayloadLength);
#endif #endif
if (DataHeader.DestinationChannel == BT_CHANNEL_SIGNALING) if (DataHeader.DestinationChannel == BT_CHANNEL_SIGNALING)
{ {
Bluetooth_SignalCommand_Header_t SignalCommandHeader; BT_Signal_Header_t SignalCommandHeader;
Pipe_Read_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader)); Pipe_Read_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader));
switch (SignalCommandHeader.Code) switch (SignalCommandHeader.Code)
{ {
case BT_SIGNAL_CONNECTION_REQUEST: case BT_SIGNAL_CONNECTION_REQUEST:
Bluetooth_SignalPacket_ConnectionRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader); Bluetooth_Signal_ConnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
break; break;
case BT_SIGNAL_CONFIGURATION_REQUEST: case BT_SIGNAL_CONFIGURATION_REQUEST:
Bluetooth_SignalPacket_ConfigurationRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader); Bluetooth_Signal_ConfigurationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
break; break;
case BT_SIGNAL_DISCONNECTION_REQUEST: case BT_SIGNAL_DISCONNECTION_REQUEST:
Bluetooth_SignalPacket_DisconnectionRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader); Bluetooth_Signal_DisconnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
break; break;
case BT_SIGNAL_ECHO_REQUEST: case BT_SIGNAL_ECHO_REQUEST:
Bluetooth_SignalPacket_EchoRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader); Bluetooth_Signal_EchoReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
break; break;
case BT_SIGNAL_INFORMATION_REQUEST: case BT_SIGNAL_INFORMATION_REQUEST:
Bluetooth_SignalPacket_InformationRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader); Bluetooth_Signal_InformationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
break; break;
default: default:
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
@ -100,15 +168,21 @@ void Bluetooth_ProcessACLPackets(void)
} }
} }
void Bluetooth_SendPacket(uint8_t* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel) uint8_t Bluetooth_SendPacket(uint8_t* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel)
{ {
Bluetooth_ACL_Header_t ACLPacketHeader; BT_ACL_Header_t ACLPacketHeader;
Bluetooth_DataPacket_Header_t DataHeader; BT_DataPacket_Header_t DataHeader;
if (Bluetooth_Connection.IsConnected)
return BT_SENDPACKET_NotConnected;
if (Channel->State != Channel_Open)
return BT_SENDPACKET_ChannelNotOpen;
ACLPacketHeader.ConnectionHandle = Bluetooth_Connection.ConnectionHandle; ACLPacketHeader.ConnectionHandle = Bluetooth_Connection.ConnectionHandle;
ACLPacketHeader.DataLength = sizeof(DataHeader) + DataLen; ACLPacketHeader.DataLength = sizeof(DataHeader) + DataLen;
DataHeader.PayloadLength = DataLen;
DataHeader.DestinationChannel = Channel->RemoteNumber; DataHeader.DestinationChannel = Channel->RemoteNumber;
DataHeader.PayloadLength = DataLen;
Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE); Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
Pipe_Unfreeze(); Pipe_Unfreeze();
@ -118,30 +192,32 @@ void Bluetooth_SendPacket(uint8_t* Data, uint16_t DataLen, Bluetooth_Channel_t*
Pipe_Write_Stream_LE(Data, DataLen); Pipe_Write_Stream_LE(Data, DataLen);
Pipe_Freeze(); Pipe_Freeze();
return BT_SENDPACKET_NoError;
} }
static inline void Bluetooth_SignalPacket_ConnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t* ACLPacketHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_SignalCommand_Header_t* SignalCommandHeader) BT_Signal_Header_t* SignalCommandHeader)
{ {
Bluetooth_SignalCommand_ConnectionRequest_t ConnectionRequest; BT_Signal_ConnectionReq_t ConnectionRequest;
Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest)); Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG("<< L2CAP Connection Request", NULL); BT_ACL_DEBUG("<< L2CAP Connection Request", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- PSM: 0x%04X", ConnectionRequest.PSM); BT_ACL_DEBUG("-- PSM: 0x%04X", ConnectionRequest.PSM);
BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel); BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
#endif #endif
Pipe_ClearIN(); Pipe_ClearIN();
Pipe_Freeze(); Pipe_Freeze();
Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE); Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
Pipe_Unfreeze(); Pipe_Unfreeze();
Bluetooth_SignalCommand_ConnectionResponse_t ConnectionResponse; BT_Signal_ConnectionResp_t ConnectionResponse;
ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse); ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse); DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
@ -164,44 +240,45 @@ static inline void Bluetooth_SignalPacket_ConnectionRequest(Bluetooth_ACL_Header
Pipe_ClearOUT(); Pipe_ClearOUT();
Pipe_Freeze(); Pipe_Freeze();
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("Packet Sent", NULL); BT_ACL_DEBUG("Packet Sent", NULL);
BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF)); BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength); BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength); BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
#endif #endif
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG(">> L2CAP Connection Response", NULL); BT_ACL_DEBUG(">> L2CAP Connection Response", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel); BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
#endif #endif
} }
static inline void Bluetooth_SignalPacket_ConfigurationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t* ACLPacketHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_SignalCommand_Header_t* SignalCommandHeader) BT_Signal_Header_t* SignalCommandHeader)
{ {
Bluetooth_SignalCommand_ConfigurationRequest_t ConfigurationRequest; BT_Signal_ConfigurationReq_t ConfigurationRequest;
Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest)); Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
// TODO: Process/Discard configuration options here // TODO: Process/Discard configuration options here
Pipe_Discard_Stream(DataHeader->PayloadLength - sizeof(*SignalCommandHeader));
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG("<< L2CAP Configuration Request", NULL); BT_ACL_DEBUG("<< L2CAP Configuration Request", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
#endif #endif
Pipe_ClearIN(); Pipe_ClearIN();
Pipe_Freeze(); Pipe_Freeze();
Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE); Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
Pipe_Unfreeze(); Pipe_Unfreeze();
Bluetooth_SignalCommand_ConfigurationResponse_t ConfigurationResponse; BT_Signal_ConfigurationResp_t ConfigurationResponse;
ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse); ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse); DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
@ -212,7 +289,20 @@ static inline void Bluetooth_SignalPacket_ConfigurationRequest(Bluetooth_ACL_Hea
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false); Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
if (ChannelData != NULL) if (ChannelData != NULL)
ChannelData->State = Channel_Open; {
switch (ChannelData->State)
{
case Channel_Config_WaitConfig:
ChannelData->State = Channel_Config_WaitSendConfig;
break;
case Channel_Config_WaitReqResp:
ChannelData->State = Channel_Config_WaitResp;
break;
case Channel_Config_WaitReq:
ChannelData->State = Channel_Open;
break;
}
}
// TODO: Add channel config data to the tail of ConfigurationResponse // TODO: Add channel config data to the tail of ConfigurationResponse
@ -228,43 +318,43 @@ static inline void Bluetooth_SignalPacket_ConfigurationRequest(Bluetooth_ACL_Hea
Pipe_ClearOUT(); Pipe_ClearOUT();
Pipe_Freeze(); Pipe_Freeze();
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("Packet Sent", NULL); BT_ACL_DEBUG("Packet Sent", NULL);
BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF)); BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength); BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength); BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
#endif #endif
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG(">> L2CAP Configuration Response", NULL); BT_ACL_DEBUG(">> L2CAP Configuration Response", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Result: 0x%02X", ConfigurationResponse.Result); BT_ACL_DEBUG("-- Result: 0x%02X", ConfigurationResponse.Result);
#endif #endif
} }
static inline void Bluetooth_SignalPacket_DisconnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t* ACLPacketHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_SignalCommand_Header_t* SignalCommandHeader) BT_Signal_Header_t* SignalCommandHeader)
{ {
Bluetooth_SignalCommand_DisconnectionRequest_t DisconnectionRequest; BT_Signal_DisconnectionReq_t DisconnectionRequest;
Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest)); Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest));
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG("<< L2CAP Disconnection Request", NULL); BT_ACL_DEBUG("<< L2CAP Disconnection Request", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel);
BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel); BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel);
#endif #endif
Pipe_ClearIN(); Pipe_ClearIN();
Pipe_Freeze(); Pipe_Freeze();
Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE); Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
Pipe_Unfreeze(); Pipe_Unfreeze();
Bluetooth_SignalCommand_DisconnectionResponse_t DisconnectionResponse; BT_Signal_DisconnectionResp_t DisconnectionResponse;
ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse); ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse); DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
@ -288,29 +378,29 @@ static inline void Bluetooth_SignalPacket_DisconnectionRequest(Bluetooth_ACL_Hea
Pipe_ClearOUT(); Pipe_ClearOUT();
Pipe_Freeze(); Pipe_Freeze();
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("Packet Sent", NULL); BT_ACL_DEBUG("Packet Sent", NULL);
BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF)); BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength); BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength); BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
#endif #endif
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG(">> L2CAP Disconnection Response", NULL); BT_ACL_DEBUG(">> L2CAP Disconnection Response", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel); BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel);
#endif #endif
} }
static inline void Bluetooth_SignalPacket_EchoRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_SignalCommand_Header_t* SignalCommandHeader) BT_Signal_Header_t* SignalCommandHeader)
{ {
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG("<< L2CAP Echo Request", NULL); BT_ACL_DEBUG("<< L2CAP Echo Request", NULL);
#endif #endif
Pipe_ClearIN(); Pipe_ClearIN();
Pipe_Freeze(); Pipe_Freeze();
@ -330,39 +420,39 @@ static inline void Bluetooth_SignalPacket_EchoRequest(Bluetooth_ACL_Header_t* AC
Pipe_ClearOUT(); Pipe_ClearOUT();
Pipe_Freeze(); Pipe_Freeze();
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("Packet Sent", NULL); BT_ACL_DEBUG("Packet Sent", NULL);
BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF)); BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength); BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength); BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
#endif #endif
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG(">> L2CAP Echo Response", NULL); BT_ACL_DEBUG(">> L2CAP Echo Response", NULL);
#endif #endif
} }
static inline void Bluetooth_SignalPacket_InformationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t* ACLPacketHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_SignalCommand_Header_t* SignalCommandHeader) BT_Signal_Header_t* SignalCommandHeader)
{ {
Bluetooth_SignalCommand_InformationRequest_t InformationRequest; BT_Signal_InformationReq_t InformationRequest;
Pipe_Read_Stream_LE(&InformationRequest, sizeof(InformationRequest)); Pipe_Read_Stream_LE(&InformationRequest, sizeof(InformationRequest));
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG("<< Information Request", NULL); BT_ACL_DEBUG("<< Information Request", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Info Type: 0x%04X", InformationRequest.InfoType); BT_ACL_DEBUG("-- Info Type: 0x%04X", InformationRequest.InfoType);
#endif #endif
Pipe_ClearIN(); Pipe_ClearIN();
Pipe_Freeze(); Pipe_Freeze();
Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE); Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
Pipe_Unfreeze(); Pipe_Unfreeze();
Bluetooth_SignalCommand_InformationResponse_t InformationResponse; BT_Signal_InformationResp_t InformationResponse;
uint8_t ResponseData[4]; uint8_t ResponseData[4];
uint8_t ResponseLen; uint8_t ResponseLen;
@ -402,17 +492,17 @@ static inline void Bluetooth_SignalPacket_InformationRequest(Bluetooth_ACL_Heade
Pipe_ClearOUT(); Pipe_ClearOUT();
Pipe_Freeze(); Pipe_Freeze();
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("Packet Sent", NULL); BT_ACL_DEBUG("Packet Sent", NULL);
BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF)); BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength); BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel); BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength); BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
#endif #endif
#if (ACL_DEBUG_LEVEL > 0) #if (ACL_DEBUG_LEVEL > 0)
BT_ACL_DEBUG(">> L2CAP Information Response", NULL); BT_ACL_DEBUG(">> L2CAP Information Response", NULL);
#endif #endif
#if (ACL_DEBUG_LEVEL > 1) #if (ACL_DEBUG_LEVEL > 1)
BT_ACL_DEBUG("-- Result: 0x%02X", InformationResponse.Result); BT_ACL_DEBUG("-- Result: 0x%02X", InformationResponse.Result);
#endif #endif
} }

@ -42,7 +42,7 @@
/* Macros: */ /* Macros: */
#define BT_ACL_DEBUG(s, ...) printf_P(PSTR("(ACL) " s "\r\n"), __VA_ARGS__) #define BT_ACL_DEBUG(s, ...) printf_P(PSTR("(ACL) " s "\r\n"), __VA_ARGS__)
#define ACL_DEBUG_LEVEL 2 #define ACL_DEBUG_LEVEL 1
#define BT_CHANNEL_SIGNALING 0x0001 #define BT_CHANNEL_SIGNALING 0x0001
#define BT_CHANNEL_CONNECTIONLESS 0x0002 #define BT_CHANNEL_CONNECTIONLESS 0x0002
@ -76,26 +76,26 @@
{ {
uint16_t ConnectionHandle; uint16_t ConnectionHandle;
uint16_t DataLength; uint16_t DataLength;
} Bluetooth_ACL_Header_t; } BT_ACL_Header_t;
typedef struct typedef struct
{ {
uint16_t PayloadLength; uint16_t PayloadLength;
uint16_t DestinationChannel; uint16_t DestinationChannel;
} Bluetooth_DataPacket_Header_t; } BT_DataPacket_Header_t;
typedef struct typedef struct
{ {
uint8_t Code; uint8_t Code;
uint8_t Identifier; uint8_t Identifier;
uint16_t Length; uint16_t Length;
} Bluetooth_SignalCommand_Header_t; } BT_Signal_Header_t;
typedef struct typedef struct
{ {
uint16_t PSM; uint16_t PSM;
uint16_t SourceChannel; uint16_t SourceChannel;
} Bluetooth_SignalCommand_ConnectionRequest_t; } BT_Signal_ConnectionReq_t;
typedef struct typedef struct
{ {
@ -103,64 +103,66 @@
uint16_t SourceChannel; uint16_t SourceChannel;
uint16_t Result; uint16_t Result;
uint16_t Status; uint16_t Status;
} Bluetooth_SignalCommand_ConnectionResponse_t; } BT_Signal_ConnectionResp_t;
typedef struct typedef struct
{ {
uint16_t DestinationChannel; uint16_t DestinationChannel;
uint16_t SourceChannel; uint16_t SourceChannel;
} Bluetooth_SignalCommand_DisconnectionRequest_t; } BT_Signal_DisconnectionReq_t;
typedef struct typedef struct
{ {
uint16_t DestinationChannel; uint16_t DestinationChannel;
uint16_t SourceChannel; uint16_t SourceChannel;
} Bluetooth_SignalCommand_DisconnectionResponse_t; } BT_Signal_DisconnectionResp_t;
typedef struct typedef struct
{ {
uint16_t DestinationChannel; uint16_t DestinationChannel;
uint16_t Flags; uint16_t Flags;
} Bluetooth_SignalCommand_ConfigurationRequest_t; } BT_Signal_ConfigurationReq_t;
typedef struct typedef struct
{ {
uint16_t SourceChannel; uint16_t SourceChannel;
uint16_t Flags; uint16_t Flags;
uint16_t Result; uint16_t Result;
} Bluetooth_SignalCommand_ConfigurationResponse_t; } BT_Signal_ConfigurationResp_t;
typedef struct typedef struct
{ {
uint16_t InfoType; uint16_t InfoType;
} Bluetooth_SignalCommand_InformationRequest_t; } BT_Signal_InformationReq_t;
typedef struct typedef struct
{ {
uint16_t InfoType; uint16_t InfoType;
uint16_t Result; uint16_t Result;
} Bluetooth_SignalCommand_InformationResponse_t; } BT_Signal_InformationResp_t;
/* Function Prototypes: */ /* Function Prototypes: */
void Bluetooth_ProcessACLPackets(void); void Bluetooth_ACLTask(void);
void Bluetooth_SendPacket(uint8_t* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel); uint8_t Bluetooth_SendPacket(uint8_t* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel);
#if defined(INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C) #if defined(INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C)
static inline void Bluetooth_SignalPacket_ConnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, static void Bluetooth_ProcessACLPackets(void);
Bluetooth_DataPacket_Header_t* DataHeader,
Bluetooth_SignalCommand_Header_t* SignalCommandHeader); static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t* ACLPacketHeader,
static inline void Bluetooth_SignalPacket_EchoRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_Signal_Header_t* SignalCommandHeader);
Bluetooth_SignalCommand_Header_t* SignalCommandHeader); static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
static inline void Bluetooth_SignalPacket_ConfigurationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_Signal_Header_t* SignalCommandHeader);
Bluetooth_SignalCommand_Header_t* SignalCommandHeader); static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t* ACLPacketHeader,
static inline void Bluetooth_SignalPacket_DisconnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_Signal_Header_t* SignalCommandHeader);
Bluetooth_SignalCommand_Header_t* SignalCommandHeader); static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t* ACLPacketHeader,
static inline void Bluetooth_SignalPacket_InformationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader, BT_DataPacket_Header_t* DataHeader,
Bluetooth_DataPacket_Header_t* DataHeader, BT_Signal_Header_t* SignalCommandHeader);
Bluetooth_SignalCommand_Header_t* SignalCommandHeader); static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t* ACLPacketHeader,
BT_DataPacket_Header_t* DataHeader,
BT_Signal_Header_t* SignalCommandHeader);
#endif #endif
#endif #endif

@ -28,43 +28,16 @@
this software. this software.
*/ */
#define INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C
#include "BluetoothHCICommands.h" #include "BluetoothHCICommands.h"
static Bluetooth_HCICommand_Header_t HCICommandHeader; static BT_HCICommand_Header_t HCICommandHeader;
uint8_t Bluetooth_HCIProcessingState; uint8_t Bluetooth_HCIProcessingState;
static uint8_t Bluetooth_HCINextState; static uint8_t Bluetooth_HCINextState;
static uint8_t Bluetooth_TempDeviceAddress[6]; static uint8_t Bluetooth_TempDeviceAddress[6];
static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint16_t ParameterLength) void Bluetooth_HCITask(void)
{
/* Need to reserve the amount of bytes given in the header for the complete payload */
uint8_t CommandBuffer[sizeof(HCICommandHeader) + HCICommandHeader.ParameterLength];
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_DEVICE),
.bRequest = 0,
.wValue = 0,
.wIndex = 0,
.wLength = sizeof(CommandBuffer)
};
/* Copy over the HCI command header to the allocated buffer */
memcpy(CommandBuffer, &HCICommandHeader, sizeof(HCICommandHeader));
/* Zero out the parameter section of the response to ensure that any padding bytes do not expose private RAM contents */
memset(&CommandBuffer[sizeof(HCICommandHeader)], 0x00, HCICommandHeader.ParameterLength);
/* Copy over the command parameters (if any) to the command buffer - note, the number of actual source parameter bytes
may differ to those in the header; any difference in length is filled with 0x00 padding bytes */
memcpy(&CommandBuffer[sizeof(HCICommandHeader)], Parameters, ParameterLength);
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(CommandBuffer);
}
void Bluetooth_ProcessHCICommands(void)
{ {
switch (Bluetooth_HCIProcessingState) switch (Bluetooth_HCIProcessingState)
{ {
@ -74,7 +47,7 @@ void Bluetooth_ProcessHCICommands(void)
if (Pipe_IsReadWriteAllowed()) if (Pipe_IsReadWriteAllowed())
{ {
Bluetooth_HCIEvent_Header_t HCIEventHeader; BT_HCIEvent_Header_t HCIEventHeader;
/* Read in the event header to fetch the event code and payload length */ /* Read in the event header to fetch the event code and payload length */
Pipe_Read_Stream_LE(&HCIEventHeader, sizeof(HCIEventHeader)); Pipe_Read_Stream_LE(&HCIEventHeader, sizeof(HCIEventHeader));
@ -93,16 +66,16 @@ void Bluetooth_ProcessHCICommands(void)
break; break;
case EVENT_COMMAND_STATUS: case EVENT_COMMAND_STATUS:
/* If the execution of a command failed, reset the stack */ /* If the execution of a command failed, reset the stack */
if (((Bluetooth_HCIEvent_CommandStatus_t*)&EventParams)->Status) if (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status)
Bluetooth_HCIProcessingState = Bluetooth_Init; Bluetooth_HCIProcessingState = Bluetooth_Init;
break; break;
case EVENT_CONNECTION_REQUEST: case EVENT_CONNECTION_REQUEST:
/* Need to store the remote device's BT address in a temporary buffer for later use */ /* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress, memcpy(Bluetooth_TempDeviceAddress,
&((Bluetooth_HCIEvent_ConnectionRequest_t*)&EventParams)->RemoteAddress, &((BT_HCIEvent_ConnectionRequest_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress)); sizeof(Bluetooth_TempDeviceAddress));
bool IsACLConnection = (((Bluetooth_HCIEvent_ConnectionRequest_t*)&EventParams)->LinkType == 0x01); bool IsACLConnection = (((BT_HCIEvent_ConnectionRequest_t*)&EventParams)->LinkType == 0x01);
/* Only accept the connection if it is a ACL (data) connection, a device is not already connected /* Only accept the connection if it is a ACL (data) connection, a device is not already connected
and the user application has indicated that the connection should be allowed */ and the user application has indicated that the connection should be allowed */
@ -113,7 +86,7 @@ void Bluetooth_ProcessHCICommands(void)
case EVENT_PIN_CODE_REQUEST: case EVENT_PIN_CODE_REQUEST:
/* Need to store the remote device's BT address in a temporary buffer for later use */ /* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress, memcpy(Bluetooth_TempDeviceAddress,
&((Bluetooth_HCIEvent_PinCodeRequest_t*)&EventParams)->RemoteAddress, &((BT_HCIEvent_PinCodeReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress)); sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode; Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode;
@ -121,11 +94,11 @@ void Bluetooth_ProcessHCICommands(void)
case EVENT_CONNECTION_COMPLETE: case EVENT_CONNECTION_COMPLETE:
/* Need to store the remote device's BT address in a temporary buffer for later use */ /* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_Connection.RemoteAddress, memcpy(Bluetooth_Connection.RemoteAddress,
&((Bluetooth_HCIEvent_ConnectionComplete_t*)&EventParams)->RemoteAddress, &((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress)); sizeof(Bluetooth_TempDeviceAddress));
/* Store the created connection handle and indicate that the connection has been established */ /* Store the created connection handle and indicate that the connection has been established */
Bluetooth_Connection.ConnectionHandle = ((Bluetooth_HCIEvent_ConnectionComplete_t*)&EventParams)->ConnectionHandle; Bluetooth_Connection.ConnectionHandle = ((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->ConnectionHandle;
Bluetooth_Connection.IsConnected = true; Bluetooth_Connection.IsConnected = true;
Bluetooth_ConnectionComplete(); Bluetooth_ConnectionComplete();
@ -151,7 +124,7 @@ void Bluetooth_ProcessHCICommands(void)
Bluetooth_HCIProcessingState = Bluetooth_Init_Reset; Bluetooth_HCIProcessingState = Bluetooth_Init_Reset;
break; break;
case Bluetooth_Init_Reset: case Bluetooth_Init_Reset:
HCICommandHeader = (Bluetooth_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET}, OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET},
ParameterLength: 0, ParameterLength: 0,
@ -164,7 +137,7 @@ void Bluetooth_ProcessHCICommands(void)
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Init_SetLocalName: case Bluetooth_Init_SetLocalName:
HCICommandHeader = (Bluetooth_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME}, OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME},
ParameterLength: 248, ParameterLength: 248,
@ -177,7 +150,7 @@ void Bluetooth_ProcessHCICommands(void)
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Init_SetDeviceClass: case Bluetooth_Init_SetDeviceClass:
HCICommandHeader = (Bluetooth_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE}, OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE},
ParameterLength: 3, ParameterLength: 3,
@ -190,7 +163,7 @@ void Bluetooth_ProcessHCICommands(void)
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Init_WriteScanEnable: case Bluetooth_Init_WriteScanEnable:
HCICommandHeader = (Bluetooth_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE}, OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE},
ParameterLength: 1, ParameterLength: 1,
@ -205,60 +178,88 @@ void Bluetooth_ProcessHCICommands(void)
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Conn_AcceptConnection: case Bluetooth_Conn_AcceptConnection:
HCICommandHeader = (Bluetooth_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST}, OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},
ParameterLength: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_t), ParameterLength: sizeof(BT_HCICommand_AcceptConnectionReq_t),
}; };
/* Copy over the temporary BT device address saved from the Connection Request event, indicate slave /* Copy over the temporary BT device address saved from the Connection Request event, indicate slave
connection role */ connection role */
Bluetooth_HCICommand_AcceptConnectionRequest_t AcceptConnectionParams; BT_HCICommand_AcceptConnectionReq_t AcceptConnectionParams;
memcpy(AcceptConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress, memcpy(AcceptConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress,
sizeof(AcceptConnectionParams.RemoteAddress)); sizeof(AcceptConnectionParams.RemoteAddress));
AcceptConnectionParams.SlaveRole = true; AcceptConnectionParams.SlaveRole = true;
/* Send the command to accept the remote connection request */ /* Send the command to accept the remote connection request */
Bluetooth_SendHCICommand(&AcceptConnectionParams, sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_t)); Bluetooth_SendHCICommand(&AcceptConnectionParams, sizeof(BT_HCICommand_AcceptConnectionReq_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Conn_RejectConnection: case Bluetooth_Conn_RejectConnection:
HCICommandHeader = (Bluetooth_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST}, OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST},
ParameterLength: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_t), ParameterLength: sizeof(BT_HCICommand_RejectConnectionReq_t),
}; };
/* Copy over the temporary BT device address saved from the Connection Request event, indicate failure /* Copy over the temporary BT device address saved from the Connection Request event, indicate failure
to accept the connection due to limited device resources or incorrect device address */ to accept the connection due to limited device resources or incorrect device address */
Bluetooth_HCICommand_RejectConnectionRequest_t RejectConnectionParams; BT_HCICommand_RejectConnectionReq_t RejectConnectionParams;
memcpy(RejectConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(RejectConnectionParams.RemoteAddress)); memcpy(RejectConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(RejectConnectionParams.RemoteAddress));
RejectConnectionParams.Reason = Bluetooth_Connection.IsConnected ? ERROR_LIMITED_RESOURCES : ERROR_UNACCEPTABLE_BDADDR; RejectConnectionParams.Reason = Bluetooth_Connection.IsConnected ? ERROR_LIMITED_RESOURCES : ERROR_UNACCEPTABLE_BDADDR;
/* Send the command to reject the remote connection request */ /* Send the command to reject the remote connection request */
Bluetooth_SendHCICommand(&RejectConnectionParams, sizeof(Bluetooth_HCICommand_RejectConnectionRequest_t)); Bluetooth_SendHCICommand(&RejectConnectionParams, sizeof(BT_HCICommand_RejectConnectionReq_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Conn_SendPINCode: case Bluetooth_Conn_SendPINCode:
HCICommandHeader = (Bluetooth_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY}, OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY},
ParameterLength: sizeof(Bluetooth_HCICommand_PinCodeResponse_t), ParameterLength: sizeof(BT_HCICommand_PinCodeResp_t),
}; };
/* Copy over the temporary BT device address saved from the PIN Code Request event, copy over the /* Copy over the temporary BT device address saved from the PIN Code Request event, copy over the
local PIN authentication code to the response */ local PIN authentication code to the response */
Bluetooth_HCICommand_PinCodeResponse_t PINCodeRequestParams; BT_HCICommand_PinCodeResp_t PINCodeRequestParams;
memcpy(PINCodeRequestParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(PINCodeRequestParams.RemoteAddress)); memcpy(PINCodeRequestParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(PINCodeRequestParams.RemoteAddress));
PINCodeRequestParams.PINCodeLength = strlen(Bluetooth_DeviceConfiguration.PINCode); PINCodeRequestParams.PINCodeLength = strlen(Bluetooth_DeviceConfiguration.PINCode);
memcpy(PINCodeRequestParams.PINCode, Bluetooth_DeviceConfiguration.PINCode, sizeof(PINCodeRequestParams.PINCode)); memcpy(PINCodeRequestParams.PINCode, Bluetooth_DeviceConfiguration.PINCode, sizeof(PINCodeRequestParams.PINCode));
/* Send the command to transmit the device's local PIN number for authentication */ /* Send the command to transmit the device's local PIN number for authentication */
Bluetooth_SendHCICommand(&PINCodeRequestParams, sizeof(Bluetooth_HCICommand_PinCodeResponse_t)); Bluetooth_SendHCICommand(&PINCodeRequestParams, sizeof(BT_HCICommand_PinCodeResp_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
break; break;
} }
} }
static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint16_t ParameterLength)
{
/* Need to reserve the amount of bytes given in the header for the complete payload */
uint8_t CommandBuffer[sizeof(HCICommandHeader) + HCICommandHeader.ParameterLength];
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_DEVICE),
.bRequest = 0,
.wValue = 0,
.wIndex = 0,
.wLength = sizeof(CommandBuffer)
};
/* Copy over the HCI command header to the allocated buffer */
memcpy(CommandBuffer, &HCICommandHeader, sizeof(HCICommandHeader));
/* Zero out the parameter section of the response to ensure that any padding bytes do not expose private RAM contents */
memset(&CommandBuffer[sizeof(HCICommandHeader)], 0x00, HCICommandHeader.ParameterLength);
/* Copy over the command parameters (if any) to the command buffer - note, the number of actual source parameter bytes
may differ to those in the header; any difference in length is filled with 0x00 padding bytes */
memcpy(&CommandBuffer[sizeof(HCICommandHeader)], Parameters, ParameterLength);
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(CommandBuffer);
}

@ -94,13 +94,13 @@
uint8_t ParameterLength; uint8_t ParameterLength;
uint8_t Parameters[]; uint8_t Parameters[];
} Bluetooth_HCICommand_Header_t; } BT_HCICommand_Header_t;
typedef struct typedef struct
{ {
uint8_t EventCode; uint8_t EventCode;
uint8_t ParameterLength; uint8_t ParameterLength;
} Bluetooth_HCIEvent_Header_t; } BT_HCIEvent_Header_t;
typedef struct typedef struct
{ {
@ -112,14 +112,14 @@
int OCF : 10; int OCF : 10;
int OGF : 6; int OGF : 6;
} OpCode; } OpCode;
} Bluetooth_HCIEvent_CommandStatus_t; } BT_HCIEvent_CommandStatus_t;
typedef struct typedef struct
{ {
uint8_t HCLPacketsAllowable; uint8_t HCLPacketsAllowable;
uint16_t Opcode; uint16_t Opcode;
uint8_t ReturnParams[]; uint8_t ReturnParams[];
} Bluetooth_HCIEvent_CommandComplete_t; } BT_HCIEvent_CommandComplete_t;
typedef struct typedef struct
{ {
@ -127,7 +127,7 @@
uint8_t ClassOfDevice_Service; uint8_t ClassOfDevice_Service;
uint16_t ClassOfDevice_MajorMinor; uint16_t ClassOfDevice_MajorMinor;
uint8_t LinkType; uint8_t LinkType;
} Bluetooth_HCIEvent_ConnectionRequest_t; } BT_HCIEvent_ConnectionRequest_t;
typedef struct typedef struct
{ {
@ -136,34 +136,34 @@
uint8_t RemoteAddress[6]; uint8_t RemoteAddress[6];
uint8_t LinkType; uint8_t LinkType;
uint8_t EncryptionEnabled; uint8_t EncryptionEnabled;
} Bluetooth_HCIEvent_ConnectionComplete_t; } BT_HCIEvent_ConnectionComplete_t;
typedef struct typedef struct
{ {
uint8_t RemoteAddress[6]; uint8_t RemoteAddress[6];
} Bluetooth_HCIEvent_PinCodeRequest_t; } BT_HCIEvent_PinCodeReq_t;
typedef struct typedef struct
{ {
uint8_t RemoteAddress[6]; uint8_t RemoteAddress[6];
uint8_t SlaveRole; uint8_t SlaveRole;
} Bluetooth_HCICommand_AcceptConnectionRequest_t; } BT_HCICommand_AcceptConnectionReq_t;
typedef struct typedef struct
{ {
uint8_t RemoteAddress[6]; uint8_t RemoteAddress[6];
uint8_t Reason; uint8_t Reason;
} Bluetooth_HCICommand_RejectConnectionRequest_t; } BT_HCICommand_RejectConnectionReq_t;
typedef struct typedef struct
{ {
uint8_t RemoteAddress[6]; uint8_t RemoteAddress[6];
uint8_t PINCodeLength; uint8_t PINCodeLength;
char PINCode[16]; char PINCode[16];
} Bluetooth_HCICommand_PinCodeResponse_t; } BT_HCICommand_PinCodeResp_t;
/* Enums: */ /* Enums: */
enum Bluetooth_ScanEnable_Modes_t enum BT_ScanEnable_Modes_t
{ {
BT_SCANMODE_NoScansEnabled = 0, BT_SCANMODE_NoScansEnabled = 0,
BT_SCANMODE_InquiryScanOnly = 1, BT_SCANMODE_InquiryScanOnly = 1,
@ -171,7 +171,7 @@
BT_SCANMODE_InquiryAndPageScans = 3, BT_SCANMODE_InquiryAndPageScans = 3,
}; };
enum BluetoothStack_States_t enum BT_HCIStates_t
{ {
Bluetooth_ProcessEvents = 0, Bluetooth_ProcessEvents = 0,
Bluetooth_Init = 1, Bluetooth_Init = 1,
@ -188,8 +188,7 @@
extern uint8_t Bluetooth_HCIProcessingState; extern uint8_t Bluetooth_HCIProcessingState;
/* Function Prototypes: */ /* Function Prototypes: */
void Bluetooth_ProcessHCICommands(void); void Bluetooth_HCITask(void);
void Bluetooth_ProcessHCIEvents(void);
#if defined(INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C) #if defined(INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C)
static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint16_t ParameterLength); static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint16_t ParameterLength);

@ -50,21 +50,20 @@ void Bluetooth_Stack_Init(void)
void Bluetooth_Stack_USBTask(void) void Bluetooth_Stack_USBTask(void)
{ {
Bluetooth_ProcessHCICommands(); Bluetooth_HCITask();
Bluetooth_ProcessACLPackets(); Bluetooth_ACLTask();
} }
Bluetooth_Channel_t* Bluetooth_GetChannelData(uint16_t ChannelNumber, bool SearchBySource) Bluetooth_Channel_t* Bluetooth_GetChannelData(uint16_t ChannelNumber, bool SearchBySource)
{ {
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++) for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
{ {
Bluetooth_Channel_t* CurrentChannelStructure = &Bluetooth_Connection.Channels[i]; Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
uint16_t CurrentChannelNumber = (SearchBySource) ? CurrentChannelStructure->RemoteNumber : uint16_t CurrentChannelNumber = (SearchBySource) ? ChannelData->RemoteNumber : ChannelData->LocalNumber;
CurrentChannelStructure->LocalNumber;
if (CurrentChannelNumber == ChannelNumber) if (CurrentChannelNumber == ChannelNumber)
return CurrentChannelStructure; return ChannelData;
} }
return NULL; return NULL;
@ -74,16 +73,16 @@ Bluetooth_Channel_t* Bluetooth_InitChannelData(uint16_t RemoteChannelNumber, uin
{ {
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++) for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
{ {
Bluetooth_Channel_t* CurrentChannelStructure = &Bluetooth_Connection.Channels[i]; Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
if (CurrentChannelStructure->State == Channel_Closed) if (ChannelData->State == Channel_Closed)
{ {
CurrentChannelStructure->RemoteNumber = RemoteChannelNumber; ChannelData->RemoteNumber = RemoteChannelNumber;
CurrentChannelStructure->LocalNumber = (BLUETOOTH_CHANNELNUMBER_BASEOFFSET + i); ChannelData->LocalNumber = (BLUETOOTH_CHANNELNUMBER_BASEOFFSET + i);
CurrentChannelStructure->PSM = PSM; ChannelData->PSM = PSM;
CurrentChannelStructure->State = Channel_Config; ChannelData->State = Channel_Config_WaitConfig;
return CurrentChannelStructure; return ChannelData;
} }
} }

@ -48,14 +48,25 @@
#define CHANNEL_PSM_RFCOMM 0x0003 #define CHANNEL_PSM_RFCOMM 0x0003
/* Enums: */ /* Enums: */
enum Bluetooth_Channel_State_t enum BT_ChannelStates_t
{ {
Channel_Closed = 0, Channel_Closed = 0,
Channel_WaitConnect = 1, Channel_WaitConnect = 1,
Channel_WaitConnectRsp = 2, Channel_WaitConnectRsp = 2,
Channel_Config = 3, Channel_Config_WaitConfig = 3,
Channel_Open = 4, Channel_Config_WaitSendConfig = 4,
Channel_WaitDisconnect = 5, Channel_Config_WaitReqResp = 5,
Channel_Config_WaitResp = 6,
Channel_Config_WaitReq = 7,
Channel_Open = 8,
Channel_WaitDisconnect = 9,
};
enum Endpoint_ControlStream_RW_ErrorCodes_t
{
BT_SENDPACKET_NoError = 0,
BT_SENDPACKET_NotConnected = 1,
BT_SENDPACKET_ChannelNotOpen = 2,
}; };
/* Type Defines: */ /* Type Defines: */
@ -65,7 +76,7 @@
uint16_t LocalNumber; uint16_t LocalNumber;
uint16_t RemoteNumber; uint16_t RemoteNumber;
uint16_t PSM; uint16_t PSM;
uint16_t MTU; uint16_t RemoteMTU;
} Bluetooth_Channel_t; } Bluetooth_Channel_t;
typedef struct typedef struct
@ -74,6 +85,7 @@
uint16_t ConnectionHandle; uint16_t ConnectionHandle;
uint8_t RemoteAddress[6]; uint8_t RemoteAddress[6];
Bluetooth_Channel_t Channels[BLUETOOTH_MAX_OPEN_CHANNELS]; Bluetooth_Channel_t Channels[BLUETOOTH_MAX_OPEN_CHANNELS];
uint8_t SignallingIdentifier;
} Bluetooth_Connection_t; } Bluetooth_Connection_t;
typedef struct typedef struct

@ -5,11 +5,16 @@
|___|___|_||_n_| Framework for AVRs |___|___|_||_n_| Framework for AVRs
========================================= =========================================
Written by Dean Camera Written by Dean Camera
dean [at] fourwalledcubicle [dot] com
http://www.fourwalledcubicle.com/LUFA.php http://www.fourwalledcubicle.com/LUFA.php
========================================= =========================================
LUFA IS DONATION SUPPORTED. TO SUPPORT LUFA, LUFA IS DONATION SUPPORTED. To support LUFA,
PLEASE DONATE AT FOURWALLEDCUBICLE.COM. please donate at http://www.fourwalledcubicle.com.
For Commercial Licensing information, see
http://fourwalledcubicle.com/PurchaseLUFA.php
This package contains the complete LUFA library, demos, user-submitted projects This package contains the complete LUFA library, demos, user-submitted projects

Loading…
Cancel
Save