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.
\r
#include "BluetoothHost.h"\r
\r
+/** Bluetooth configuration structure. This structure configures the bluetooth stack's user alterable settings. */\r
+Bluetooth_Device_t Bluetooth_DeviceConfiguration =\r
+ {\r
+ Class: (DEVICE_CLASS_SERVICE_CAPTURING | DEVICE_CLASS_MAJOR_COMPUTER | DEVICE_CLASS_MINOR_COMPUTER_PALM),\r
+ PINCode: "0000",\r
+ Name: "LUFA Bluetooth Demo"\r
+ };\r
+\r
/** Main program entry point. This routine configures the hardware required by the application, then\r
* enters a loop to run the application tasks in sequence.\r
*/\r
}\r
}\r
\r
+/** Bluetooth stack callback event for when the Bluetooth stack has fully initialized using the attached\r
+ * Bluetooth dongle.\r
+ */\r
+void Bluetooth_StackInitialized(void)\r
+{\r
+ printf_P(PSTR("Stack initialized with local address %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),\r
+ Bluetooth_State.LocalBDADDR[5], Bluetooth_State.LocalBDADDR[4], Bluetooth_State.LocalBDADDR[3],\r
+ Bluetooth_State.LocalBDADDR[2], Bluetooth_State.LocalBDADDR[1], Bluetooth_State.LocalBDADDR[0]);\r
+}\r
+\r
/** Bluetooth stack callback event for a Bluetooth connection request. When this callback fires, the\r
* user application must indicate if the connection is to be allowed or rejected.\r
*\r
*/\r
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress)\r
{\r
- printf_P(PSTR("Connection Request from Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"),\r
+ printf_P(PSTR("Connection Request from Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),\r
RemoteAddress[5], RemoteAddress[4], RemoteAddress[3], RemoteAddress[2],\r
RemoteAddress[1], RemoteAddress[0]);\r
\r
*/\r
void Bluetooth_ConnectionComplete(void)\r
{\r
- printf_P(PSTR("Connection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"), \r
+ printf_P(PSTR("Connection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"), \r
Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4],\r
Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2],\r
Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]);\r
*/\r
void Bluetooth_DisconnectionComplete(void)\r
{\r
- printf_P(PSTR("Disconnection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"), \r
+ printf_P(PSTR("Disconnection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"), \r
Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4],\r
Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2],\r
Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]);\r
this software.\r
*/\r
\r
+/*\r
+ TODO: Make SendPacket respect receiver's MTU\r
+ TODO: Make ReceivePacket stitch together MTU fragments (?)\r
+ TODO: Add channel opened/closed callbacks\r
+ */\r
+\r
#define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C\r
#include "BluetoothACLPackets.h"\r
\r
Pipe_ClearIN();\r
Pipe_Freeze();\r
\r
- Bluetooth_PacketReceived(PacketData, DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, false));\r
+ Bluetooth_PacketReceived(PacketData, DataHeader.PayloadLength,\r
+ Bluetooth_GetChannelData(DataHeader.DestinationChannel, CHANNEL_SEARCH_LOCALNUMBER));\r
}\r
}\r
\r
BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);\r
\r
/* Try to retrieve the existing channel's information structure if it exists */\r
- Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, true);\r
+ Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);\r
\r
/* If an existing channel item with the correct remote channel number was not found, find a free channel entry */\r
if (ChannelData == NULL)\r
BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel); \r
\r
/* Search for the referenced channel in the channel information list */\r
- Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.SourceChannel, false);\r
+ Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.SourceChannel, CHANNEL_SEARCH_LOCALNUMBER);\r
\r
/* Only progress if the referenced channel data was found */\r
if (ChannelData != NULL)\r
Pipe_Freeze();\r
\r
/* Search for the referenced channel in the channel information list */\r
- Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);\r
+ Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, CHANNEL_SEARCH_LOCALNUMBER);\r
\r
BT_ACL_DEBUG(1, "<< L2CAP Configuration Request");\r
BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);\r
BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse.Result);\r
\r
/* Search for the referenced channel in the channel information list */\r
- Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, true);\r
+ Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);\r
\r
/* Only update the channel's state if it was found in the channel list */\r
if (ChannelData != NULL)\r
Pipe_Freeze();\r
\r
/* Search for the referenced channel in the channel information list */\r
- Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);\r
+ Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);\r
\r
struct\r
{\r
Pipe_Freeze();\r
\r
/* Search for the referenced channel in the channel information list */\r
- Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, true);\r
+ Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);\r
\r
/* If the channel was found in the channel list, close it */ \r
if (ChannelData != NULL)\r
#define INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C\r
#include "BluetoothHCICommands.h"\r
\r
-/** Current processing state of the HCI portion of the Bluetooth stack. */\r
-uint8_t Bluetooth_HCIProcessingState;\r
-\r
-/** Next HCI state to enter once the last issued HCI command has completed. */\r
-static uint8_t Bluetooth_HCINextState;\r
-\r
/** Temporary Bluetooth Device Address, for HCI responses which much include the detination address */\r
static uint8_t Bluetooth_TempDeviceAddress[6];\r
\r
-\r
/** Bluetooth HCI processing task. This task should be called repeatedly the main Bluetooth\r
* stack task to manage the HCI processing state.\r
*/\r
{\r
BT_HCICommand_Header_t HCICommandHeader;\r
\r
- switch (Bluetooth_HCIProcessingState)\r
+ switch (Bluetooth_State.CurrentHCIState)\r
{\r
case Bluetooth_ProcessEvents:\r
Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);\r
{\r
case EVENT_COMMAND_COMPLETE:\r
BT_HCI_DEBUG(1, "<< Command Complete");\r
- Bluetooth_HCIProcessingState = Bluetooth_HCINextState;\r
+ \r
+ /* Check which operation was completed in case we need to process the even parameters */\r
+ switch (((BT_HCIEvent_CommandComplete_t*)&EventParams)->Opcode)\r
+ {\r
+ case (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBDADDR):\r
+ /* A READ BDADDR command completed, copy over the local device's BDADDR from the response */\r
+ memcpy(Bluetooth_State.LocalBDADDR,\r
+ &((BT_HCIEvent_CommandComplete_t*)&EventParams)->ReturnParams[1],\r
+ sizeof(Bluetooth_State.LocalBDADDR));\r
+ break;\r
+ }\r
+ \r
+ Bluetooth_State.CurrentHCIState = Bluetooth_State.NextHCIState;\r
break;\r
case EVENT_COMMAND_STATUS:\r
BT_HCI_DEBUG(1, "<< Command Status");\r
\r
/* If the execution of a command failed, reset the stack */\r
if (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status)\r
- Bluetooth_HCIProcessingState = Bluetooth_Init;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_Init;\r
break;\r
case EVENT_CONNECTION_REQUEST:\r
BT_HCI_DEBUG(1, "<< Connection Request");\r
\r
/* Only accept the connection if it is a ACL (data) connection, a device is not already connected\r
and the user application has indicated that the connection should be allowed */\r
- Bluetooth_HCIProcessingState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) ||\r
- !(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ?\r
- Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;\r
+ Bluetooth_State.CurrentHCIState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) ||\r
+ !(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ?\r
+ Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;\r
\r
- BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_HCIProcessingState == Bluetooth_Conn_RejectConnection) ?\r
+ BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_State.CurrentHCIState == Bluetooth_Conn_RejectConnection) ?\r
PSTR("REJECTED") : PSTR("ACCEPTED"));\r
\r
break;\r
&((BT_HCIEvent_PinCodeReq_t*)&EventParams)->RemoteAddress,\r
sizeof(Bluetooth_TempDeviceAddress));\r
\r
- Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendPINCode;\r
break;\r
case EVENT_LINK_KEY_REQUEST:\r
BT_HCI_DEBUG(1, "<< Link Key Request");\r
&((BT_HCIEvent_LinkKeyReq_t*)&EventParams)->RemoteAddress,\r
sizeof(Bluetooth_TempDeviceAddress)); \r
\r
- Bluetooth_HCIProcessingState = Bluetooth_Conn_SendLinkKeyNAK;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendLinkKeyNAK;\r
break;\r
case EVENT_CONNECTION_COMPLETE:\r
BT_HCI_DEBUG(1, "<< Connection Complete");\r
\r
Bluetooth_DisconnectionComplete();\r
\r
- Bluetooth_HCIProcessingState = Bluetooth_Init;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_Init;\r
break;\r
}\r
}\r
case Bluetooth_Init:\r
BT_HCI_DEBUG(1, "# Init");\r
\r
+ Bluetooth_State.IsInitialized = false;\r
+\r
/* Reset the connection information structure to destroy any previous connection state */\r
memset(&Bluetooth_Connection, 0x00, sizeof(Bluetooth_Connection));\r
\r
- Bluetooth_HCIProcessingState = Bluetooth_Init_Reset; \r
+ Bluetooth_State.CurrentHCIState = Bluetooth_Init_Reset; \r
break;\r
case Bluetooth_Init_Reset:\r
BT_HCI_DEBUG(1, "# Reset");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET},\r
+ OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_RESET),\r
ParameterLength: 0,\r
};\r
\r
/* Send the command to reset the bluetooth dongle controller */\r
Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);\r
\r
- Bluetooth_HCINextState = Bluetooth_Init_SetLocalName;\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.NextHCIState = Bluetooth_Init_ReadBufferSize;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
+ break;\r
+ case Bluetooth_Init_ReadBufferSize:\r
+ BT_HCI_DEBUG(1, "# Read Buffer Size");\r
+ \r
+ HCICommandHeader = (BT_HCICommand_Header_t)\r
+ {\r
+ OpCode: (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE),\r
+ ParameterLength: 0,\r
+ };\r
+\r
+ /* Send the command to read the bluetooth buffer size (mandatory before device sends any data) */\r
+ Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);\r
+\r
+ Bluetooth_State.NextHCIState = Bluetooth_Init_GetBDADDR;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
+ break;\r
+ case Bluetooth_Init_GetBDADDR:\r
+ BT_HCI_DEBUG(1, "# Get BDADDR");\r
+ \r
+ HCICommandHeader = (BT_HCICommand_Header_t)\r
+ {\r
+ OpCode: (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBDADDR),\r
+ ParameterLength: 0,\r
+ };\r
+\r
+ /* Send the command to retrieve the BDADDR of the inserted bluetooth dongle */\r
+ Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);\r
+\r
+ Bluetooth_State.NextHCIState = Bluetooth_Init_SetLocalName;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
case Bluetooth_Init_SetLocalName:\r
BT_HCI_DEBUG(1, "# Set Local Name");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME},\r
+ OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME),\r
ParameterLength: 248,\r
};\r
\r
/* Send the command to set the bluetooth dongle's name for other devices to see */\r
Bluetooth_SendHCICommand(&HCICommandHeader, Bluetooth_DeviceConfiguration.Name, strlen(Bluetooth_DeviceConfiguration.Name));\r
\r
- Bluetooth_HCINextState = Bluetooth_Init_SetDeviceClass;\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.NextHCIState = Bluetooth_Init_SetDeviceClass;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
case Bluetooth_Init_SetDeviceClass:\r
BT_HCI_DEBUG(1, "# Set Device Class");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE},\r
+ OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE),\r
ParameterLength: 3,\r
};\r
\r
/* Send the command to set the class of the device for other devices to see */\r
Bluetooth_SendHCICommand(&HCICommandHeader, &Bluetooth_DeviceConfiguration.Class, 3);\r
\r
- Bluetooth_HCINextState = Bluetooth_Init_WriteScanEnable;\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.NextHCIState = Bluetooth_Init_WriteScanEnable;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
case Bluetooth_Init_WriteScanEnable:\r
BT_HCI_DEBUG(1, "# Write Scan Enable");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE},\r
+ OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE),\r
ParameterLength: 1,\r
};\r
\r
/* Send the command to set the remote device scanning mode */\r
Bluetooth_SendHCICommand(&HCICommandHeader, &Interval, 1);\r
\r
- Bluetooth_HCINextState = Bluetooth_ProcessEvents;\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.NextHCIState = Bluetooth_Init_FinalizeInit;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
+ break;\r
+ case Bluetooth_Init_FinalizeInit:\r
+ Bluetooth_State.IsInitialized = true;\r
+\r
+ /* Fire the user application callback to indicate that the stack is now fully initialized */\r
+ Bluetooth_StackInitialized();\r
+\r
+ Bluetooth_State.NextHCIState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
case Bluetooth_Conn_AcceptConnection:\r
BT_HCI_DEBUG(1, "# Accept Connection");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},\r
+ OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST),\r
ParameterLength: sizeof(BT_HCICommand_AcceptConnectionReq_t),\r
};\r
\r
/* Send the command to accept the remote connection request */\r
Bluetooth_SendHCICommand(&HCICommandHeader, &AcceptConnectionParams, sizeof(BT_HCICommand_AcceptConnectionReq_t));\r
\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
case Bluetooth_Conn_RejectConnection:\r
BT_HCI_DEBUG(1, "# Reject Connection");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST},\r
+ OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST),\r
ParameterLength: sizeof(BT_HCICommand_RejectConnectionReq_t),\r
};\r
\r
/* Send the command to reject the remote connection request */\r
Bluetooth_SendHCICommand(&HCICommandHeader, &RejectConnectionParams, sizeof(BT_HCICommand_RejectConnectionReq_t));\r
\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
case Bluetooth_Conn_SendPINCode:\r
BT_HCI_DEBUG(1, "# Send Pin Code");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY},\r
+ OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY),\r
ParameterLength: sizeof(BT_HCICommand_PinCodeResp_t),\r
};\r
\r
/* Send the command to transmit the device's local PIN number for authentication */\r
Bluetooth_SendHCICommand(&HCICommandHeader, &PINCodeRequestParams, sizeof(BT_HCICommand_PinCodeResp_t));\r
\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
case Bluetooth_Conn_SendLinkKeyNAK:\r
BT_HCI_DEBUG(1, "# Send Link Key NAK");\r
\r
HCICommandHeader = (BT_HCICommand_Header_t)\r
{\r
- OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY},\r
+ OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY),\r
ParameterLength: sizeof(BT_HCICommand_LinkKeyNAKResp_t),\r
};\r
\r
/* Send the command to transmit the link key NAK to the receiver */\r
Bluetooth_SendHCICommand(&HCICommandHeader, &LinkKeyNAKParams, sizeof(BT_HCICommand_LinkKeyNAKResp_t));\r
\r
- Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;\r
break;\r
}\r
}\r
#define BT_HCI_DEBUG(l, s, ...) do { if (HCI_DEBUG_LEVEL >= l) printf_P(PSTR("(HCI) " s "\r\n"), ##__VA_ARGS__); } while (0)\r
#define HCI_DEBUG_LEVEL 0\r
\r
- #define OGF_LINK_CONTROL 0x01\r
- #define OGF_CTRLR_BASEBAND 0x03\r
- #define OGF_CTRLR_INFORMATIONAL 0x04\r
+ #define OGF_LINK_CONTROL (0x01 << 10)\r
+ #define OGF_CTRLR_BASEBAND (0x03 << 10)\r
+ #define OGF_CTRLR_INFORMATIONAL (0x04 << 10)\r
\r
#define OCF_LINK_CONTROL_INQUIRY 0x0001\r
#define OCF_LINK_CONTROL_INQUIRY_CANCEL 0x0002\r
#define OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE 0x0024\r
#define OCF_CTRLR_BASEBAND_WRITE_SIMPLE_PAIRING_MODE 0x0056\r
#define OCF_CTRLR_BASEBAND_WRITE_AUTHENTICATION_ENABLE 0x0020\r
- #define OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005\r
+ #define OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005\r
+ #define OCF_CTRLR_INFORMATIONAL_READBDADDR 0x0009\r
\r
#define EVENT_COMMAND_STATUS 0x0F\r
#define EVENT_COMMAND_COMPLETE 0x0E\r
/* Type Defines: */\r
typedef struct\r
{\r
- struct\r
- {\r
- int OCF : 10;\r
- int OGF : 6;\r
- } OpCode;\r
-\r
+ uint16_t OpCode;\r
uint8_t ParameterLength;\r
uint8_t Parameters[];\r
} BT_HCICommand_Header_t;\r
\r
typedef struct\r
{\r
- uint8_t Status;\r
- uint8_t Packets;\r
-\r
- struct\r
- {\r
- int OCF : 10;\r
- int OGF : 6;\r
- } OpCode;\r
+ uint8_t Status;\r
+ uint8_t Packets;\r
+ uint16_t OpCode;\r
} BT_HCIEvent_CommandStatus_t;\r
\r
typedef struct\r
{\r
- uint8_t HCLPacketsAllowable;\r
+ uint8_t HCIPacketsAllowable;\r
uint16_t Opcode;\r
uint8_t ReturnParams[];\r
} BT_HCIEvent_CommandComplete_t;\r
Bluetooth_ProcessEvents = 0,\r
Bluetooth_Init = 1,\r
Bluetooth_Init_Reset = 2,\r
- Bluetooth_Init_SetLocalName = 3,\r
- Bluetooth_Init_SetDeviceClass = 4,\r
- Bluetooth_Init_WriteScanEnable = 5,\r
- Bluetooth_Conn_AcceptConnection = 6,\r
- Bluetooth_Conn_RejectConnection = 7,\r
- Bluetooth_Conn_SendPINCode = 8,\r
- Bluetooth_Conn_SendLinkKeyNAK = 9,\r
+ Bluetooth_Init_ReadBufferSize = 3,\r
+ Bluetooth_Init_GetBDADDR = 4,\r
+ Bluetooth_Init_SetLocalName = 5,\r
+ Bluetooth_Init_SetDeviceClass = 6,\r
+ Bluetooth_Init_WriteScanEnable = 7,\r
+ Bluetooth_Init_FinalizeInit = 8,\r
+ Bluetooth_Conn_AcceptConnection = 9,\r
+ Bluetooth_Conn_RejectConnection = 10,\r
+ Bluetooth_Conn_SendPINCode = 11,\r
+ Bluetooth_Conn_SendLinkKeyNAK = 12,\r
};\r
\r
- /* External Variables: */\r
- extern uint8_t Bluetooth_HCIProcessingState;\r
-\r
/* Function Prototypes: */\r
void Bluetooth_HCITask(void);\r
\r
/** Bluetooth device connection information structure. Once connected to a remote device, this structure tracks the\r
* connection state of the individual L2CAP channels.\r
*/\r
-Bluetooth_Connection_t Bluetooth_Connection = {IsConnected: false};\r
+Bluetooth_Connection_t Bluetooth_Connection = { IsConnected: false };\r
\r
-/** Bluetooth configuration structure. This structure configures the bluetooth stack's user alterable settings. */\r
-Bluetooth_Device_t Bluetooth_DeviceConfiguration =\r
- {\r
- Class: (DEVICE_CLASS_SERVICE_CAPTURING | DEVICE_CLASS_MAJOR_COMPUTER | DEVICE_CLASS_MINOR_COMPUTER_PALM),\r
- PINCode: "0000",\r
- Name: "LUFA Bluetooth Demo"\r
- };\r
+/** Bluetooth device state information structure. This structure contains details on the current Bluetooth stack\r
+ * state.\r
+ */\r
+Bluetooth_Stack_State_t Bluetooth_State = { IsInitialized: false };\r
\r
/** Bluetooth stack initialization function. This function must be called once to initialize the Bluetooth stack,\r
* ready for connection to remote devices.\r
*\r
* \note This function only begins the initialization process; the stack is initialized as the main Bluetooth stack\r
- * management task is repeatedly called. The initialization process ends when the \ref Bluetooth_HCIProcessingState\r
- * global enters the Bluetooth_ProcessEvents state.\r
+ * management task is repeatedly called. The initialization process ends when the IsInitialized element of the\r
+ * \ref Bluetooth_State structure becomes true and the \ref Bluetooth_StackInitialized() callback fires.\r
*/\r
void Bluetooth_Stack_Init(void)\r
{\r
/* Reset the HCI state machine - this will eventually reset the adapter and stack when the Bluetooth stack task is called */\r
- Bluetooth_HCIProcessingState = Bluetooth_Init;\r
+ Bluetooth_State.CurrentHCIState = Bluetooth_Init;\r
+ Bluetooth_State.NextHCIState = Bluetooth_Init;\r
}\r
\r
/** Bluetooth stack management task. This task must be repeatedly called to maintain the Bluetooth stack and any connection\r
\r
/** Retrieves the channel information structure with the given local or remote channel number from the channel list.\r
*\r
- * \param[in] ChannelNumber Channel number to search for in the channel list\r
- * \param[in] SearchByRemoteChannel Indicated whether to search for a channel information structure by the given remote channel\r
- * or local channel number\r
+ * \param[in] SearchValue Value to search for in the channel structure list\r
+ * \param[in] SearchKey Key to search within the channel structure, a CHANNEL_SEARCH_* mask\r
*\r
* \return Pointer to the matching channel information structure in the channel table if found, NULL otherwise\r
*/\r
-Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t ChannelNumber, const bool SearchByRemoteChannel)\r
+Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t SearchValue, const uint8_t SearchKey)\r
{\r
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)\r
{\r
Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];\r
\r
- /* Fetch the channel number that is to be matched against from the current channel information struct */\r
- uint16_t SearchChannelNumber = (SearchByRemoteChannel) ? ChannelData->RemoteNumber : ChannelData->LocalNumber;\r
+ bool FoundMatch = false;\r
+ \r
+ switch (SearchKey)\r
+ {\r
+ case CHANNEL_SEARCH_LOCALNUMBER:\r
+ FoundMatch = (SearchValue == ChannelData->LocalNumber);\r
+ break;\r
+ case CHANNEL_SEARCH_REMOTENUMBER:\r
+ FoundMatch = (SearchValue == ChannelData->RemoteNumber);\r
+ break;\r
+ case CHANNEL_SEARCH_PSM:\r
+ FoundMatch = (SearchValue == ChannelData->PSM);\r
+ break;\r
+ }\r
\r
- if (SearchChannelNumber == ChannelNumber)\r
+ if (FoundMatch)\r
return ChannelData;\r
}\r
\r
#define CHANNEL_PSM_UPNP 0x0010\r
#define CHANNEL_PSM_HIDP 0x0011\r
\r
+ #define CHANNEL_SEARCH_LOCALNUMBER 0\r
+ #define CHANNEL_SEARCH_REMOTENUMBER 1\r
+ #define CHANNEL_SEARCH_PSM 2\r
+ \r
#define MAXIMUM_CHANNEL_MTU 255\r
\r
/* Enums: */\r
char PINCode[16]; /**< Pin code required to send or receive in order to authenticate with a remote device. */\r
char Name[]; /**< Name of the local bluetooth device, up to 248 characters. */\r
} Bluetooth_Device_t;\r
+ \r
+ /** Bluetooth stack state information structure, for the containment of the Bluetooth stack state. The values in\r
+ * this structure are set by the Bluetooth stack internally, and should all be treated as read only by the user\r
+ * application.\r
+ */\r
+ typedef struct\r
+ {\r
+ uint8_t CurrentHCIState; /**< Current HCI state machine state. */\r
+ uint8_t NextHCIState; /**< Next HCI state machine state to progress to once the currently issued command completes. */\r
+ bool IsInitialized; /**< Indicates if the Bluetooth stack is currently initialized and ready for connections\r
+ * to or from a remote Bluetooth device.\r
+ */\r
+ uint8_t LocalBDADDR[6]; /**< Local bluetooth adapter's BDADDR, valid when the stack is fully initialized. */\r
+ } Bluetooth_Stack_State_t;\r
\r
/* Includes: */\r
#include "BluetoothHCICommands.h"\r
void Bluetooth_Stack_Init(void);\r
void Bluetooth_Stack_USBTask(void);\r
\r
+ void Bluetooth_StackInitialized(void);\r
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress);\r
void Bluetooth_ConnectionComplete(void);\r
void Bluetooth_DisconnectionComplete(void);\r
bool Bluetooth_ChannelConnectionRequest(const uint16_t PSM);\r
void Bluetooth_PacketReceived(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);\r
- Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t ChannelNumber, const bool SearchByRemoteChannel);\r
+ Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t SearchValue, const uint8_t SearchKey);\r
Bluetooth_Channel_t* Bluetooth_OpenChannel(const uint16_t PSM);\r
void Bluetooth_CloseChannel(Bluetooth_Channel_t* const Channel);\r
uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);\r
\r
/* External Variables: */\r
- extern Bluetooth_Device_t Bluetooth_DeviceConfiguration;\r
- extern Bluetooth_Connection_t Bluetooth_Connection;\r
+ extern Bluetooth_Device_t Bluetooth_DeviceConfiguration;\r
+ extern Bluetooth_Connection_t Bluetooth_Connection;\r
+ extern Bluetooth_Stack_State_t Bluetooth_State;\r
\r
#endif\r
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &SDP_Attribute_Name},\r
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &SDP_Attribute_Description},\r
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &SDP_Attribute_Availability},\r
- {.AttributeData = NULL}\r
+ SERVICE_ATTRIBUTE_TABLE_TERMINATOR\r
};\r
\r
SERVICE_ATTRIBUTE_TEXT(RFCOMM_Attribute_Name, "RFCOMM");\r
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &RFCOMM_Attribute_Name},\r
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &RFCOMM_Attribute_Description},\r
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &RFCOMM_Attribute_Availability},\r
- {.AttributeData = NULL}\r
+ SERVICE_ATTRIBUTE_TABLE_TERMINATOR\r
};\r
\r
const ServiceTable_t SDP_Services_Table[] =\r
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}\r
#define SERVICE_ATTRIBUTE_32BIT_LEN(name, type, size, ...) const ServiceAttributeData32Bit_t name PROGMEM = \\r
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}\r
- \r
+ #define SERVICE_ATTRIBUTE_TABLE_TERMINATOR {.AttributeData = NULL}\r
+\r
/* Type Defines: */\r
typedef struct\r
{\r
* - Added incomplete MIDIToneGenerator project\r
* - Added new Relay Controller Board project (thanks to OBinou)\r
* - Added board hardware driver support for the Teensy, USBTINY MKII, Benito and JM-DB-U2 lines of third party USB AVR boards\r
- * - Added new ATTR_NO_INIT variable attribute\r
+ * - Added new ATTR_NO_INIT variable attribute for global variables that should not be automatically cleared on startup\r
*\r
* <b>Changed:</b>\r
* - AVRISP programmer project now has a more robust timeout system, allowing for an increase of the software USART speed\r
* It supports a large number of USB AVR models and boards (see \ref Page_DeviceSupport). It is designed to provide an easy to use,\r
* feature rich framework for the development of USB peripherals and hosts.\r
*\r
- * LUFA focuses on the microcontroller side of USB development only; it includes no host USB driver development facilities. While\r
- * custom USB devices can be made with LUFA, the included demos all use the inbuilt OS drivers for each USB class for simplicity.\r
+ * LUFA focuses on the microcontroller side of USB development only; it includes no PC host USB driver development facilities - other projects\r
+ * such as the Windows Driver Development Kit, Windows USB Device Mode Framework and libusb may be of interest for developing custom OS drivers.\r
+ * While custom USB devices can be made with LUFA using such tools, the included demos all use the inbuilt OS drivers for each USB class for\r
+ * simplicity.\r
*\r
* The library is currently in a stable release, suitable for download and incorporation into user projects for\r
* both host and device modes. For information about the project progression, see the blog link at \ref Page_Resources.\r
\r
{ .ParamID = PARAM_STATUS_TGT_CONN,\r
.ParamPrivileges = PARAM_PRIV_READ,\r
- .ParamValue = 0x00 },\r
+ .ParamValue = STATUS_ISP_READY },\r
\r
{ .ParamID = PARAM_DISCHARGEDELAY,\r
.ParamPrivileges = PARAM_PRIV_WRITE,\r