Commit efbedcfa authored by Dean Camera's avatar Dean Camera
Browse files

Document Bluetooth files with overall file Doxygen comments. Add more initial...

Document Bluetooth files with overall file Doxygen comments. Add more initial RFCOMM layer code to receive and respond to SABM packets.
parent be09f648
......@@ -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 (?)
......
......@@ -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
*/
......
......@@ -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
......
......@@ -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));
}
......
......@@ -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
......@@ -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 },
......
......@@ -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:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment