diff options
7 files changed, 133 insertions, 23 deletions
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c index 03d0f2aca..df8dfc5c1 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c @@ -28,6 +28,13 @@ this software. */ +/** \file + * + * Bluetooth L2CAP layer management code. This module managed the creation, + * configuration and teardown of L2CAP channels, and manages packet reception + * and sending to and from other Bluetooth devices. + */ + /* TODO: Make SendPacket respect receiver's MTU TODO: Make ReceivePacket stitch together MTU fragments (?) diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c index 57b74e089..d71875212 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c @@ -28,6 +28,15 @@ this software. */ +/** \file + * + * Bluetooth HCI layer management code. This module manages the overall + * Bluetooth stack connection state to and from other devices, processes + * received events from the Bluetooth controller, and issues commands to + * modify the controller's configuration, such as the broadcast name of the + * device. + */ + /* TODO: Add local to remote device connections */ diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c index d78a9efa1..1a667987b 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c @@ -28,6 +28,12 @@ this software. */ +/** \file + * + * Main module for the Bluetooth stack. This module contains the overall Bluetooth + * stack state variables and the main Bluetooth stack management functions. + */ + #include "BluetoothStack.h" /** Bluetooth device connection information structure. Once connected to a remote device, this structure tracks the diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.c b/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.c index a441ae156..510160629 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.c @@ -28,6 +28,13 @@ this software.
*/
+/** \file
+ *
+ * RFCOMM layer module. This module manages the RFCOMM layer of the
+ * stack, providing virtual serial port channels on top of the lower
+ * L2CAP layer.
+ */
+
#define INCLUDE_FROM_RFCOMM_C
#include "RFCOMM.h"
@@ -62,10 +69,10 @@ void RFCOMM_Initialize(void) void RFCOMM_ProcessPacket(void* Data, Bluetooth_Channel_t* const Channel)
{
- RFCOMM_Header_t* FrameHeader = (RFCOMM_Header_t*)Data;
+ const RFCOMM_Header_t* FrameHeader = (const RFCOMM_Header_t*)Data;
/* Decode the RFCOMM frame type from the header */
- switch (FrameHeader->FrameType & ~FRAME_POLL_FINAL)
+ switch (FrameHeader->Control & ~FRAME_POLL_FINAL)
{
case RFCOMM_Frame_SABM:
RFCOMM_ProcessSABM(FrameHeader, Channel);
@@ -82,54 +89,94 @@ void RFCOMM_ProcessPacket(void* Data, Bluetooth_Channel_t* const Channel) case RFCOMM_Frame_UIH:
RFCOMM_ProcessUIH(FrameHeader, Channel);
break;
+ default:
+ BT_RFCOMM_DEBUG(1, "<< Unknown Frame Type");
+ break;
}
}
static void RFCOMM_ProcessSABM(const RFCOMM_Header_t* const FrameHeader, Bluetooth_Channel_t* const Channel)
{
- uint8_t* CurrBufferPos = ((uint8_t*)FrameHeader + sizeof(RFCOMM_Header_t));
- uint16_t DataLen = RFCOMM_GetFrameDataLength(&CurrBufferPos);
-
BT_RFCOMM_DEBUG(1, "<< SABM Received");
- BT_RFCOMM_DEBUG(2, "-- Data Length 0x%04X", DataLen);
+ BT_RFCOMM_DEBUG(2, "-- Address 0x%02X", FrameHeader->Address);
+
+ // TODO: Reset channel send/receive state here
+
+ struct
+ {
+ RFCOMM_Header_t FrameHeader;
+ uint8_t FrameLength;
+ uint8_t FCS;
+ } ResponsePacket;
+
+ /* Copy over the same frame header as the sent packet to copy the logical RFCOMM channel address */
+ ResponsePacket.FrameHeader.Address = FrameHeader->Address;
+
+ /* Set the frame type to an Unnumbered Acknowledgement to acknowledge the SABM request */
+ ResponsePacket.FrameHeader.Control = RFCOMM_Frame_UA;
+
+ /* Set the length to 0 (LSB indicates end of 8-bit length field) */
+ ResponsePacket.FrameLength = 0x01;
+
+ /* Calculate the frame checksum from all fields except the FCS field itself */
+ ResponsePacket.FCS = RFCOMM_GetFCSValue(&ResponsePacket, sizeof(ResponsePacket) - sizeof(ResponsePacket.FCS));
+
+ BT_RFCOMM_DEBUG(1, ">> UA Sent");
- for (uint16_t i = 0; i < DataLen; i++)
- printf("0x%02X ", CurrBufferPos[i]);
- printf("\r\n");
+ /* Send the completed response packet to the sender */
+ Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), Channel);
}
static void RFCOMM_ProcessUA(const RFCOMM_Header_t* const FrameHeader, Bluetooth_Channel_t* const Channel)
{
+ const uint8_t* CurrBufferPos = ((const uint8_t*)FrameHeader + sizeof(RFCOMM_Header_t));
+
BT_RFCOMM_DEBUG(1, "<< UA Received");
+ BT_RFCOMM_DEBUG(2, "-- Address 0x%02X", FrameHeader->Address);
}
static void RFCOMM_ProcessDM(const RFCOMM_Header_t* const FrameHeader, Bluetooth_Channel_t* const Channel)
{
+ const uint8_t* CurrBufferPos = ((const uint8_t*)FrameHeader + sizeof(RFCOMM_Header_t));
+
BT_RFCOMM_DEBUG(1, "<< DM Received");
+ BT_RFCOMM_DEBUG(2, "-- Address 0x%02X", FrameHeader->Address);
}
static void RFCOMM_ProcessDISC(const RFCOMM_Header_t* const FrameHeader, Bluetooth_Channel_t* const Channel)
{
+ const uint8_t* CurrBufferPos = ((const uint8_t*)FrameHeader + sizeof(RFCOMM_Header_t));
+
BT_RFCOMM_DEBUG(1, "<< DISC Received");
+ BT_RFCOMM_DEBUG(2, "-- Address 0x%02X", FrameHeader->Address);
}
static void RFCOMM_ProcessUIH(const RFCOMM_Header_t* const FrameHeader, Bluetooth_Channel_t* const Channel)
{
+ const uint8_t* CurrBufferPos = ((const uint8_t*)FrameHeader + sizeof(RFCOMM_Header_t));
+
BT_RFCOMM_DEBUG(1, "<< UIH Received");
+ BT_RFCOMM_DEBUG(2, "-- Address 0x%02X", FrameHeader->Address);
}
-static uint16_t RFCOMM_GetFrameDataLength(void** BufferPos)
+static uint8_t RFCOMM_GetFCSValue(const void* FrameStart, uint16_t Length)
{
- uint8_t FirstOctet = *((uint8_t*)*BufferPos);
- (*BufferPos)++;
+ const uint8_t* CurrPos = FrameStart;
+ uint8_t FCS = 0xFF;
+
+ while (Length--)
+ FCS = pgm_read_byte(CRC8_Table[FCS ^ *(CurrPos++)]);
+ return ~FCS;
+}
+
+static uint16_t RFCOMM_GetFrameDataLength(const uint8_t** BufferPos)
+{
+ uint8_t FirstOctet = *((*BufferPos)++);
uint8_t SecondOctet = 0;
if (!(FirstOctet & 0x01))
- {
- SecondOctet = *((uint8_t*)*BufferPos);
- (*BufferPos)++;
- }
+ SecondOctet = *((*BufferPos)++);
return (((uint16_t)SecondOctet << 7) | (FirstOctet >> 1));
}
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.h b/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.h index 45f29ac21..194551d03 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.h +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/RFCOMM.h @@ -52,7 +52,7 @@ #define BT_RFCOMM_DEBUG(l, s, ...) do { if (RFCOMM_DEBUG_LEVEL >= l) printf_P(PSTR("(RFCOMM) " s "\r\n"), ##__VA_ARGS__); } while (0)
#define RFCOMM_DEBUG_LEVEL 2
- #define FRAME_POLL_FINAL (1 << 5)
+ #define FRAME_POLL_FINAL (1 << 4)
/* Enums: */
/** Enum for the types of RFCOMM frames which can be exchanged on a Bluetooth channel. */
@@ -73,9 +73,9 @@ unsigned char LogicalChannel : 6;
unsigned char PollResponse : 1;
unsigned char LastAddressOctet : 1;
- } Header;
+ } Address;
- uint8_t FrameType;
+ uint8_t Control;
} RFCOMM_Header_t;
/* Function Prototypes: */
@@ -89,7 +89,8 @@ static void RFCOMM_ProcessDISC(const RFCOMM_Header_t* const FrameHeader, Bluetooth_Channel_t* const Channel);
static void RFCOMM_ProcessUIH(const RFCOMM_Header_t* const FrameHeader, Bluetooth_Channel_t* const Channel);
- static uint16_t RFCOMM_GetFrameDataLength(void** BufferPos);
+ static uint8_t RFCOMM_GetFCSValue(const void* FrameStart, uint16_t Length);
+ static uint16_t RFCOMM_GetFrameDataLength(const uint8_t** BufferPos);
#endif
#endif
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/SDPServices.c b/Demos/Host/Incomplete/BluetoothHost/Lib/SDPServices.c index ca47f9084..16317e787 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/SDPServices.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/SDPServices.c @@ -28,8 +28,19 @@ this software.
*/
+/** \file
+ *
+ * SDP Service Attribute definitions. This file contains the attributes
+ * and attribute tables of all the services the device supports, which can
+ * then be retrieved by a connected Bluetooth device via the SDP server.
+ */
+
#include "SDPServices.h"
+/** Serial Port Profile attribute, listing the unique service handle of the Serial Port service
+ * within the device. This handle can then be requested by the SDP client in future transactions
+ * in lieu of a search UUID list.
+ */
const struct
{
uint8_t Header;
@@ -40,6 +51,10 @@ const struct SWAPENDIAN_32(0x00010001),
};
+/** Serial Port Profile attribute, listing the implemented Service Class UUIDs of the Serial Port service
+ * within the device. This list indicates all the class UUIDs that apply to the Serial Port service, so that
+ * a SDP client can search by a generalized class rather than a specific UUID to determine supported services.
+ */
const struct
{
uint8_t Header;
@@ -54,6 +69,10 @@ const struct },
};
+/** Serial Port Profile attribute, listing the Protocols (and their attributes) of the Serial Port service
+ * within the device. This list indicates what protocols the service is layered on top of, as well as any
+ * configuration information for each layer.
+ */
const struct
{
uint8_t Header;
@@ -77,11 +96,15 @@ const struct (sizeof(ItemUUID_t) + sizeof(Item8Bit_t)),
{
{(SDP_DATATYPE_UUID | SDP_DATASIZE_128Bit), RFCOMM_UUID},
- {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_8Bit), 0x00},
+ {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_8Bit), 0x03},
},
},
};
+/** Serial Port Profile attribute, listing the Browse Group List UUIDs which this service is a member of.
+ * Browse Group UUIDs give a way to group together services within a device in a simple heirachy, so that
+ * a SDP client can progressively narrow down an general browse to a specific service which it requires.
+ */
const struct
{
uint8_t Header;
@@ -95,7 +118,10 @@ const struct {(SDP_DATATYPE_UUID | SDP_DATASIZE_128Bit), PUBLICBROWSEGROUP_CLASS_UUID},
},
};
-
+
+/** Serial Port Profile attribute, listing the languages (and their encodings) supported
+ * by the Serial Port service in its text string attributes.
+ */
const struct
{
uint8_t Header;
@@ -113,7 +139,8 @@ const struct },
},
};
-
+
+/** Serial Port Profile attribute, listing a human readable name of the service. */
const struct
{
uint8_t Header;
@@ -126,6 +153,7 @@ const struct "Wireless Serial Port",
};
+/** Serial Port Profile attribute, listing a human readable description of the service. */
const struct
{
uint8_t Header;
@@ -138,6 +166,9 @@ const struct "Wireless Serial Port Service",
};
+/** Service Attribute Table for the Serial Port service, linking each supported attribute ID to its data, so that
+ * the SDP server can retrieve it for transmission back to a SDP client upon request.
+ */
const ServiceAttributeTable_t PROGMEM SerialPort_Attribute_Table[] =
{
{.AttributeID = SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE, .Data = &SerialPort_Attribute_ServiceHandle },
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c b/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c index c07718e78..6d8f27036 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c @@ -28,6 +28,14 @@ this software. */ +/** \file + * + * SDP layer module. This module implements a simple Service Discovery + * Protocol server, which can broadcast the device's supported services + * to other Bluetooth devices upon request, so that they can determine + * what services are available. + */ + #define INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C #include "ServiceDiscoveryProtocol.h" @@ -62,6 +70,7 @@ void SDP_ProcessPacket(void* Data, Bluetooth_Channel_t* const Channel) BT_SDP_DEBUG(2, "-- PDU ID: 0x%02X", SDPHeader->PDU); BT_SDP_DEBUG(2, "-- Param Length: 0x%04X", SDPHeader->ParameterLength); + /* Dispatch to the correct processing routine for the given SDP packet type */ switch (SDPHeader->PDU) { case SDP_PDU_SERVICESEARCHREQUEST: |