Commit 5993e1ef authored by Dean Camera's avatar Dean Camera
Browse files

Added ability to search by Channel PSM to the GetChannelData() function in the BluetoothHost demo.

Added new HCI states to properly initialize the bluetooth dongle and retrieve the local BDADDR.

Factored out Bluetooth state information into a new state structure for easy reference in the user application.

Added new StackInitialized() Bluetooth stack callback function.
parent 8252b4fe
......@@ -36,6 +36,14 @@
#include "BluetoothHost.h"
/** Bluetooth configuration structure. This structure configures the bluetooth stack's user alterable settings. */
Bluetooth_Device_t Bluetooth_DeviceConfiguration =
{
Class: (DEVICE_CLASS_SERVICE_CAPTURING | DEVICE_CLASS_MAJOR_COMPUTER | DEVICE_CLASS_MINOR_COMPUTER_PALM),
PINCode: "0000",
Name: "LUFA Bluetooth Demo"
};
/** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence.
*/
......@@ -196,6 +204,16 @@ void Bluetooth_Host_Task(void)
}
}
/** Bluetooth stack callback event for when the Bluetooth stack has fully initialized using the attached
* Bluetooth dongle.
*/
void Bluetooth_StackInitialized(void)
{
printf_P(PSTR("Stack initialized with local address %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
Bluetooth_State.LocalBDADDR[5], Bluetooth_State.LocalBDADDR[4], Bluetooth_State.LocalBDADDR[3],
Bluetooth_State.LocalBDADDR[2], Bluetooth_State.LocalBDADDR[1], Bluetooth_State.LocalBDADDR[0]);
}
/** Bluetooth stack callback event for a Bluetooth connection request. When this callback fires, the
* user application must indicate if the connection is to be allowed or rejected.
*
......@@ -205,7 +223,7 @@ void Bluetooth_Host_Task(void)
*/
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress)
{
printf_P(PSTR("Connection Request from Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"),
printf_P(PSTR("Connection Request from Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
RemoteAddress[5], RemoteAddress[4], RemoteAddress[3], RemoteAddress[2],
RemoteAddress[1], RemoteAddress[0]);
......@@ -218,7 +236,7 @@ bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress)
*/
void Bluetooth_ConnectionComplete(void)
{
printf_P(PSTR("Connection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"),
printf_P(PSTR("Connection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4],
Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2],
Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]);
......@@ -231,7 +249,7 @@ void Bluetooth_ConnectionComplete(void)
*/
void Bluetooth_DisconnectionComplete(void)
{
printf_P(PSTR("Disconnection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"),
printf_P(PSTR("Disconnection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4],
Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2],
Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]);
......
......@@ -28,6 +28,12 @@
this software.
*/
/*
TODO: Make SendPacket respect receiver's MTU
TODO: Make ReceivePacket stitch together MTU fragments (?)
TODO: Add channel opened/closed callbacks
*/
#define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C
#include "BluetoothACLPackets.h"
......@@ -187,7 +193,8 @@ static void Bluetooth_ProcessIncommingACLPackets(void)
Pipe_ClearIN();
Pipe_Freeze();
Bluetooth_PacketReceived(PacketData, DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, false));
Bluetooth_PacketReceived(PacketData, DataHeader.PayloadLength,
Bluetooth_GetChannelData(DataHeader.DestinationChannel, CHANNEL_SEARCH_LOCALNUMBER));
}
}
......@@ -362,7 +369,7 @@ static inline void Bluetooth_Signal_ConnectionReq(const BT_Signal_Header_t* cons
BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
/* Try to retrieve the existing channel's information structure if it exists */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, true);
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
/* If an existing channel item with the correct remote channel number was not found, find a free channel entry */
if (ChannelData == NULL)
......@@ -447,7 +454,7 @@ static inline void Bluetooth_Signal_ConnectionResp(const BT_Signal_Header_t* con
BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
/* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.SourceChannel, false);
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.SourceChannel, CHANNEL_SEARCH_LOCALNUMBER);
/* Only progress if the referenced channel data was found */
if (ChannelData != NULL)
......@@ -478,7 +485,7 @@ static inline void Bluetooth_Signal_ConfigurationReq(const BT_Signal_Header_t* c
Pipe_Freeze();
/* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, CHANNEL_SEARCH_LOCALNUMBER);
BT_ACL_DEBUG(1, "<< L2CAP Configuration Request");
BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
......@@ -564,7 +571,7 @@ static inline void Bluetooth_Signal_ConfigurationResp(const BT_Signal_Header_t*
BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse.Result);
/* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, true);
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
/* Only update the channel's state if it was found in the channel list */
if (ChannelData != NULL)
......@@ -608,7 +615,7 @@ static inline void Bluetooth_Signal_DisconnectionReq(const BT_Signal_Header_t* c
Pipe_Freeze();
/* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
struct
{
......@@ -654,7 +661,7 @@ static inline void Bluetooth_Signal_DisconnectionResp(const BT_Signal_Header_t*
Pipe_Freeze();
/* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, true);
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
/* If the channel was found in the channel list, close it */
if (ChannelData != NULL)
......
......@@ -31,16 +31,9 @@
#define INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C
#include "BluetoothHCICommands.h"
/** Current processing state of the HCI portion of the Bluetooth stack. */
uint8_t Bluetooth_HCIProcessingState;
/** Next HCI state to enter once the last issued HCI command has completed. */
static uint8_t Bluetooth_HCINextState;
/** Temporary Bluetooth Device Address, for HCI responses which much include the detination address */
static uint8_t Bluetooth_TempDeviceAddress[6];
/** Bluetooth HCI processing task. This task should be called repeatedly the main Bluetooth
* stack task to manage the HCI processing state.
*/
......@@ -48,7 +41,7 @@ void Bluetooth_HCITask(void)
{
BT_HCICommand_Header_t HCICommandHeader;
switch (Bluetooth_HCIProcessingState)
switch (Bluetooth_State.CurrentHCIState)
{
case Bluetooth_ProcessEvents:
Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
......@@ -74,7 +67,19 @@ void Bluetooth_HCITask(void)
{
case EVENT_COMMAND_COMPLETE:
BT_HCI_DEBUG(1, "<< Command Complete");
Bluetooth_HCIProcessingState = Bluetooth_HCINextState;
/* Check which operation was completed in case we need to process the even parameters */
switch (((BT_HCIEvent_CommandComplete_t*)&EventParams)->Opcode)
{
case (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBDADDR):
/* A READ BDADDR command completed, copy over the local device's BDADDR from the response */
memcpy(Bluetooth_State.LocalBDADDR,
&((BT_HCIEvent_CommandComplete_t*)&EventParams)->ReturnParams[1],
sizeof(Bluetooth_State.LocalBDADDR));
break;
}
Bluetooth_State.CurrentHCIState = Bluetooth_State.NextHCIState;
break;
case EVENT_COMMAND_STATUS:
BT_HCI_DEBUG(1, "<< Command Status");
......@@ -82,7 +87,7 @@ void Bluetooth_HCITask(void)
/* If the execution of a command failed, reset the stack */
if (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status)
Bluetooth_HCIProcessingState = Bluetooth_Init;
Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break;
case EVENT_CONNECTION_REQUEST:
BT_HCI_DEBUG(1, "<< Connection Request");
......@@ -97,11 +102,11 @@ void Bluetooth_HCITask(void)
/* 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 */
Bluetooth_HCIProcessingState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) ||
!(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ?
Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;
Bluetooth_State.CurrentHCIState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) ||
!(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ?
Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;
BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_HCIProcessingState == Bluetooth_Conn_RejectConnection) ?
BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_State.CurrentHCIState == Bluetooth_Conn_RejectConnection) ?
PSTR("REJECTED") : PSTR("ACCEPTED"));
break;
......@@ -113,7 +118,7 @@ void Bluetooth_HCITask(void)
&((BT_HCIEvent_PinCodeReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode;
Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendPINCode;
break;
case EVENT_LINK_KEY_REQUEST:
BT_HCI_DEBUG(1, "<< Link Key Request");
......@@ -123,7 +128,7 @@ void Bluetooth_HCITask(void)
&((BT_HCIEvent_LinkKeyReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_HCIProcessingState = Bluetooth_Conn_SendLinkKeyNAK;
Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendLinkKeyNAK;
break;
case EVENT_CONNECTION_COMPLETE:
BT_HCI_DEBUG(1, "<< Connection Complete");
......@@ -148,7 +153,7 @@ void Bluetooth_HCITask(void)
Bluetooth_DisconnectionComplete();
Bluetooth_HCIProcessingState = Bluetooth_Init;
Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break;
}
}
......@@ -159,62 +164,94 @@ void Bluetooth_HCITask(void)
case Bluetooth_Init:
BT_HCI_DEBUG(1, "# Init");
Bluetooth_State.IsInitialized = false;
/* Reset the connection information structure to destroy any previous connection state */
memset(&Bluetooth_Connection, 0x00, sizeof(Bluetooth_Connection));
Bluetooth_HCIProcessingState = Bluetooth_Init_Reset;
Bluetooth_State.CurrentHCIState = Bluetooth_Init_Reset;
break;
case Bluetooth_Init_Reset:
BT_HCI_DEBUG(1, "# Reset");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET},
OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_RESET),
ParameterLength: 0,
};
/* Send the command to reset the bluetooth dongle controller */
Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);
Bluetooth_HCINextState = Bluetooth_Init_SetLocalName;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.NextHCIState = Bluetooth_Init_ReadBufferSize;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_ReadBufferSize:
BT_HCI_DEBUG(1, "# Read Buffer Size");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE),
ParameterLength: 0,
};
/* Send the command to read the bluetooth buffer size (mandatory before device sends any data) */
Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);
Bluetooth_State.NextHCIState = Bluetooth_Init_GetBDADDR;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_GetBDADDR:
BT_HCI_DEBUG(1, "# Get BDADDR");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBDADDR),
ParameterLength: 0,
};
/* Send the command to retrieve the BDADDR of the inserted bluetooth dongle */
Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);
Bluetooth_State.NextHCIState = Bluetooth_Init_SetLocalName;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_SetLocalName:
BT_HCI_DEBUG(1, "# Set Local Name");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME},
OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME),
ParameterLength: 248,
};
/* Send the command to set the bluetooth dongle's name for other devices to see */
Bluetooth_SendHCICommand(&HCICommandHeader, Bluetooth_DeviceConfiguration.Name, strlen(Bluetooth_DeviceConfiguration.Name));
Bluetooth_HCINextState = Bluetooth_Init_SetDeviceClass;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.NextHCIState = Bluetooth_Init_SetDeviceClass;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_SetDeviceClass:
BT_HCI_DEBUG(1, "# Set Device Class");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE},
OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE),
ParameterLength: 3,
};
/* Send the command to set the class of the device for other devices to see */
Bluetooth_SendHCICommand(&HCICommandHeader, &Bluetooth_DeviceConfiguration.Class, 3);
Bluetooth_HCINextState = Bluetooth_Init_WriteScanEnable;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.NextHCIState = Bluetooth_Init_WriteScanEnable;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_WriteScanEnable:
BT_HCI_DEBUG(1, "# Write Scan Enable");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE},
OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE),
ParameterLength: 1,
};
......@@ -223,15 +260,24 @@ void Bluetooth_HCITask(void)
/* Send the command to set the remote device scanning mode */
Bluetooth_SendHCICommand(&HCICommandHeader, &Interval, 1);
Bluetooth_HCINextState = Bluetooth_ProcessEvents;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.NextHCIState = Bluetooth_Init_FinalizeInit;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_FinalizeInit:
Bluetooth_State.IsInitialized = true;
/* Fire the user application callback to indicate that the stack is now fully initialized */
Bluetooth_StackInitialized();
Bluetooth_State.NextHCIState = Bluetooth_ProcessEvents;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_AcceptConnection:
BT_HCI_DEBUG(1, "# Accept Connection");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_AcceptConnectionReq_t),
};
......@@ -245,14 +291,14 @@ void Bluetooth_HCITask(void)
/* Send the command to accept the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &AcceptConnectionParams, sizeof(BT_HCICommand_AcceptConnectionReq_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_RejectConnection:
BT_HCI_DEBUG(1, "# Reject Connection");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST},
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_RejectConnectionReq_t),
};
......@@ -265,14 +311,14 @@ void Bluetooth_HCITask(void)
/* Send the command to reject the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &RejectConnectionParams, sizeof(BT_HCICommand_RejectConnectionReq_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_SendPINCode:
BT_HCI_DEBUG(1, "# Send Pin Code");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY},
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY),
ParameterLength: sizeof(BT_HCICommand_PinCodeResp_t),
};
......@@ -286,14 +332,14 @@ void Bluetooth_HCITask(void)
/* Send the command to transmit the device's local PIN number for authentication */
Bluetooth_SendHCICommand(&HCICommandHeader, &PINCodeRequestParams, sizeof(BT_HCICommand_PinCodeResp_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_SendLinkKeyNAK:
BT_HCI_DEBUG(1, "# Send Link Key NAK");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY},
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY),
ParameterLength: sizeof(BT_HCICommand_LinkKeyNAKResp_t),
};
......@@ -304,7 +350,7 @@ void Bluetooth_HCITask(void)
/* Send the command to transmit the link key NAK to the receiver */
Bluetooth_SendHCICommand(&HCICommandHeader, &LinkKeyNAKParams, sizeof(BT_HCICommand_LinkKeyNAKResp_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
}
}
......
......@@ -47,9 +47,9 @@
#define BT_HCI_DEBUG(l, s, ...) do { if (HCI_DEBUG_LEVEL >= l) printf_P(PSTR("(HCI) " s "\r\n"), ##__VA_ARGS__); } while (0)
#define HCI_DEBUG_LEVEL 0
#define OGF_LINK_CONTROL 0x01
#define OGF_CTRLR_BASEBAND 0x03
#define OGF_CTRLR_INFORMATIONAL 0x04
#define OGF_LINK_CONTROL (0x01 << 10)
#define OGF_CTRLR_BASEBAND (0x03 << 10)
#define OGF_CTRLR_INFORMATIONAL (0x04 << 10)
#define OCF_LINK_CONTROL_INQUIRY 0x0001
#define OCF_LINK_CONTROL_INQUIRY_CANCEL 0x0002
......@@ -75,7 +75,8 @@
#define OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE 0x0024
#define OCF_CTRLR_BASEBAND_WRITE_SIMPLE_PAIRING_MODE 0x0056
#define OCF_CTRLR_BASEBAND_WRITE_AUTHENTICATION_ENABLE 0x0020
#define OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005
#define OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005
#define OCF_CTRLR_INFORMATIONAL_READBDADDR 0x0009
#define EVENT_COMMAND_STATUS 0x0F
#define EVENT_COMMAND_COMPLETE 0x0E
......@@ -92,12 +93,7 @@
/* Type Defines: */
typedef struct
{
struct
{
int OCF : 10;
int OGF : 6;
} OpCode;
uint16_t OpCode;
uint8_t ParameterLength;
uint8_t Parameters[];
} BT_HCICommand_Header_t;
......@@ -110,19 +106,14 @@
typedef struct
{
uint8_t Status;
uint8_t Packets;
struct
{
int OCF : 10;
int OGF : 6;
} OpCode;
uint8_t Status;
uint8_t Packets;
uint16_t OpCode;
} BT_HCIEvent_CommandStatus_t;
typedef struct
{
uint8_t HCLPacketsAllowable;
uint8_t HCIPacketsAllowable;
uint16_t Opcode;
uint8_t ReturnParams[];
} BT_HCIEvent_CommandComplete_t;
......@@ -192,18 +183,18 @@
Bluetooth_ProcessEvents = 0,
Bluetooth_Init = 1,
Bluetooth_Init_Reset = 2,
Bluetooth_Init_SetLocalName = 3,
Bluetooth_Init_SetDeviceClass = 4,
Bluetooth_Init_WriteScanEnable = 5,
Bluetooth_Conn_AcceptConnection = 6,
Bluetooth_Conn_RejectConnection = 7,
Bluetooth_Conn_SendPINCode = 8,
Bluetooth_Conn_SendLinkKeyNAK = 9,
Bluetooth_Init_ReadBufferSize = 3,
Bluetooth_Init_GetBDADDR = 4,
Bluetooth_Init_SetLocalName = 5,
Bluetooth_Init_SetDeviceClass = 6,
Bluetooth_Init_WriteScanEnable = 7,
Bluetooth_Init_FinalizeInit = 8,
Bluetooth_Conn_AcceptConnection = 9,
Bluetooth_Conn_RejectConnection = 10,
Bluetooth_Conn_SendPINCode = 11,
Bluetooth_Conn_SendLinkKeyNAK = 12,
};
/* External Variables: */
extern uint8_t Bluetooth_HCIProcessingState;
/* Function Prototypes: */
void Bluetooth_HCITask(void);
......
......@@ -33,27 +33,25 @@
/** Bluetooth device connection information structure. Once connected to a remote device, this structure tracks the
* connection state of the individual L2CAP channels.
*/
Bluetooth_Connection_t Bluetooth_Connection = {IsConnected: false};
Bluetooth_Connection_t Bluetooth_Connection = { IsConnected: false };
/** Bluetooth configuration structure. This structure configures the bluetooth stack's user alterable settings. */
Bluetooth_Device_t Bluetooth_DeviceConfiguration =
{
Class: (DEVICE_CLASS_SERVICE_CAPTURING | DEVICE_CLASS_MAJOR_COMPUTER | DEVICE_CLASS_MINOR_COMPUTER_PALM),
PINCode: "0000",
Name: "LUFA Bluetooth Demo"
};
/** Bluetooth device state information structure. This structure contains details on the current Bluetooth stack
* state.
*/
Bluetooth_Stack_State_t Bluetooth_State = { IsInitialized: false };
/** Bluetooth stack initialization function. This function must be called once to initialize the Bluetooth stack,
* ready for connection to remote devices.
*
* \note This function only begins the initialization process; the stack is initialized as the main Bluetooth stack
* management task is repeatedly called. The initialization process ends when the \ref Bluetooth_HCIProcessingState
* global enters the Bluetooth_ProcessEvents state.
* management task is repeatedly called. The initialization process ends when the IsInitialized element of the
* \ref Bluetooth_State structure becomes true and the \ref Bluetooth_StackInitialized() callback fires.
*/
void Bluetooth_Stack_Init(void)
{
/* Reset the HCI state machine - this will eventually reset the adapter and stack when the Bluetooth stack task is called */
Bluetooth_HCIProcessingState = Bluetooth_Init;
Bluetooth_State.CurrentHCIState = Bluetooth_Init;
Bluetooth_State.NextHCIState = Bluetooth_Init;
}
/** Bluetooth stack management task. This task must be repeatedly called to maintain the Bluetooth stack and any connection
......@@ -67,22 +65,33 @@ void Bluetooth_Stack_USBTask(void)
/** Retrieves the channel information structure with the given local or remote channel number from the channel list.
*
* \param[in] ChannelNumber Channel number to search for in the channel list
* \param[in] SearchByRemoteChannel Indicated whether to search for a channel information structure by the given remote channel
* or local channel number
* \param[in] SearchValue Value to search for in the channel structure list
* \param[in] SearchKey Key to search within the channel structure, a CHANNEL_SEARCH_* mask
*
* \return Pointer to the matching channel information structure in the channel table if found, NULL otherwise
*/
Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t ChannelNumber, const bool SearchByRemoteChannel)
Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t SearchValue, const uint8_t SearchKey)
{
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
{
Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
/* Fetch the channel number that is to be matched against from the current channel information struct */
uint16_t SearchChannelNumber = (SearchByRemoteChannel) ? ChannelData->RemoteNumber : ChannelData->LocalNumber;
bool FoundMatch = false;
switch (SearchKey)
{
case CHANNEL_SEARCH_LOCALNUMBER:
FoundMatch = (SearchValue == ChannelData->LocalNumber);
break;
case CHANNEL_SEARCH_REMOTENUMBER:
FoundMatch = (SearchValue == ChannelData->RemoteNumber);
break;
case CHANNEL_SEARCH_PSM:
FoundMatch = (SearchValue == ChannelData->PSM);
break;
}
if (SearchChannelNumber == ChannelNumber)
if (FoundMatch)
return ChannelData;
}
......
......@@ -51,6 +51,10 @@
#define CHANNEL_PSM_UPNP 0x0010
#define CHANNEL_PSM_HIDP 0x0011
#define CHANNEL_SEARCH_LOCALNUMBER 0
#define CHANNEL_SEARCH_REMOTENUMBER 1
#define CHANNEL_SEARCH_PSM 2
#define MAXIMUM_CHANNEL_MTU 255
/* Enums: */
......@@ -115,6 +119,20 @@
char PINCode[16]; /**< Pin code required to send or receive in order to authenticate with a remote device. */
char Name[]; /**< Name of the local bluetooth device, up to 248 characters. */
} Bluetooth_Device_t;