Add svn:eol-style property to source files, so that the line endings are correctly converted to the target system's native end of line style.

This commit is contained in:
Dean Camera 2010-05-08 03:12:14 +00:00
parent e331b531c6
commit 071e02c6b6
839 changed files with 274562 additions and 274562 deletions

View file

@ -1,297 +1,297 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the BluetoothHost demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration.
*/
#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.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "Bluetooth Host Demo running.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei();
for (;;)
{
Bluetooth_Stack_USBTask();
Bluetooth_Host_Task();
USB_USBTask();
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
SerialStream_Init(9600, false);
LEDs_Init();
USB_Init();
}
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_Host_DeviceAttached(void)
{
puts_P(PSTR(ESC_FG_GREEN "Device Attached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
* stops the library USB task management process.
*/
void EVENT_USB_Host_DeviceUnattached(void)
{
puts_P(PSTR(ESC_FG_GREEN "\r\nDevice Unattached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
* enumerated by the host and is now ready to be used by the application.
*/
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
USB_ShutDown();
printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
for(;;);
}
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
* enumerating an attached USB device.
*/
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
{
printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
" -- Error Code %d\r\n"
" -- Sub Error Code %d\r\n"
" -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Task to set the configuration of the attached device after it has been enumerated. */
void Bluetooth_Host_Task(void)
{
uint8_t ErrorCode;
switch (USB_HostState)
{
case HOST_STATE_Addressed:
puts_P(PSTR("Getting Device Data.\r\n"));
/* Get and process the configuration descriptor data */
if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead)
{
if (ErrorCode == DevControlError)
puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n"));
else
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Bluetooth Dongle Detected.\r\n"));
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
{
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Getting Config Data.\r\n"));
/* Get and process the configuration descriptor data */
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
{
if (ErrorCode == ControlError)
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
else
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n"));
/* Initialize the Bluetooth stack */
Bluetooth_Stack_Init();
USB_HostState = HOST_STATE_Configured;
break;
}
}
/** 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.
*
* \param[in] RemoteAddress Bluetooth address of the remote device attempting the connection
*
* \return Boolean true to accept the connection, false to reject it
*/
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress)
{
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]);
/* Always accept connections from remote devices */
return true;
}
/** Bluetooth stack callback event for a completed Bluetooth connection. When this callback is made,
* the connection information can be accessed through the global \ref Bluetooth_Connection structure.
*/
void Bluetooth_ConnectionComplete(void)
{
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]);
}
/** Bluetooth stack callback event for a completed Bluetooth disconnection. When this callback is made,
* the connection information in the global \ref Bluetooth_Connection structure is invalidated with the
* exception of the RemoteAddress element, which can be used to determine the address of the device that
* was disconnected.
*/
void Bluetooth_DisconnectionComplete(void)
{
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]);
}
/** Bluetooth stack callback event for a Bluetooth ACL Channel connection request. When is callback fires,
* the user application must indicate if the channel connection should be rejected or not, based on the
* protocol (PSM) value of the requested channel.
*
* \param PSM Protocol PSM value for the requested channel
*
* \return Boolean true to accept the channel connection request, false to reject it
*/
bool Bluetooth_ChannelConnectionRequest(const uint16_t PSM)
{
/* Always accept channel connection requests regardless of PSM */
return true;
}
/** Bluetooth stack callback event for a non-signal ACL packet reception. This callback fires once a connection
* to a remote Bluetooth device has been made, and the remote device has sent a non-signalling ACL packet.
*
* \param[in] Data Pointer to a buffer where the received data is stored
* \param[in] DataLen Length of the packet data, in bytes
* \param[in] Channel Bluetooth ACL data channel information structure for the packet's destination channel
*/
void Bluetooth_PacketReceived(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel)
{
switch (Channel->PSM)
{
case CHANNEL_PSM_SDP:
/* Service Discovery Protocol packet */
ServiceDiscovery_ProcessPacket(Data, Channel);
break;
default:
/* Unknown Protocol packet */
printf_P(PSTR("Packet Received (Channel 0x%04X, PSM: 0x%02x):\r\n"), Channel->LocalNumber, Channel->PSM);
for (uint16_t Byte = 0; Byte < DataLen; Byte++)
printf_P(PSTR("0x%02X "), ((uint8_t*)Data)[Byte]);
puts_P(PSTR("\r\n"));
break;
}
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the BluetoothHost demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration.
*/
#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.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "Bluetooth Host Demo running.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei();
for (;;)
{
Bluetooth_Stack_USBTask();
Bluetooth_Host_Task();
USB_USBTask();
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
SerialStream_Init(9600, false);
LEDs_Init();
USB_Init();
}
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_Host_DeviceAttached(void)
{
puts_P(PSTR(ESC_FG_GREEN "Device Attached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
* stops the library USB task management process.
*/
void EVENT_USB_Host_DeviceUnattached(void)
{
puts_P(PSTR(ESC_FG_GREEN "\r\nDevice Unattached.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
* enumerated by the host and is now ready to be used by the application.
*/
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
USB_ShutDown();
printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
for(;;);
}
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
* enumerating an attached USB device.
*/
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
{
printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
" -- Error Code %d\r\n"
" -- Sub Error Code %d\r\n"
" -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Task to set the configuration of the attached device after it has been enumerated. */
void Bluetooth_Host_Task(void)
{
uint8_t ErrorCode;
switch (USB_HostState)
{
case HOST_STATE_Addressed:
puts_P(PSTR("Getting Device Data.\r\n"));
/* Get and process the configuration descriptor data */
if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead)
{
if (ErrorCode == DevControlError)
puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n"));
else
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Bluetooth Dongle Detected.\r\n"));
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
{
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Getting Config Data.\r\n"));
/* Get and process the configuration descriptor data */
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
{
if (ErrorCode == ControlError)
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
else
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n"));
/* Initialize the Bluetooth stack */
Bluetooth_Stack_Init();
USB_HostState = HOST_STATE_Configured;
break;
}
}
/** 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.
*
* \param[in] RemoteAddress Bluetooth address of the remote device attempting the connection
*
* \return Boolean true to accept the connection, false to reject it
*/
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress)
{
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]);
/* Always accept connections from remote devices */
return true;
}
/** Bluetooth stack callback event for a completed Bluetooth connection. When this callback is made,
* the connection information can be accessed through the global \ref Bluetooth_Connection structure.
*/
void Bluetooth_ConnectionComplete(void)
{
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]);
}
/** Bluetooth stack callback event for a completed Bluetooth disconnection. When this callback is made,
* the connection information in the global \ref Bluetooth_Connection structure is invalidated with the
* exception of the RemoteAddress element, which can be used to determine the address of the device that
* was disconnected.
*/
void Bluetooth_DisconnectionComplete(void)
{
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]);
}
/** Bluetooth stack callback event for a Bluetooth ACL Channel connection request. When is callback fires,
* the user application must indicate if the channel connection should be rejected or not, based on the
* protocol (PSM) value of the requested channel.
*
* \param PSM Protocol PSM value for the requested channel
*
* \return Boolean true to accept the channel connection request, false to reject it
*/
bool Bluetooth_ChannelConnectionRequest(const uint16_t PSM)
{
/* Always accept channel connection requests regardless of PSM */
return true;
}
/** Bluetooth stack callback event for a non-signal ACL packet reception. This callback fires once a connection
* to a remote Bluetooth device has been made, and the remote device has sent a non-signalling ACL packet.
*
* \param[in] Data Pointer to a buffer where the received data is stored
* \param[in] DataLen Length of the packet data, in bytes
* \param[in] Channel Bluetooth ACL data channel information structure for the packet's destination channel
*/
void Bluetooth_PacketReceived(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel)
{
switch (Channel->PSM)
{
case CHANNEL_PSM_SDP:
/* Service Discovery Protocol packet */
ServiceDiscovery_ProcessPacket(Data, Channel);
break;
default:
/* Unknown Protocol packet */
printf_P(PSTR("Packet Received (Channel 0x%04X, PSM: 0x%02x):\r\n"), Channel->LocalNumber, Channel->PSM);
for (uint16_t Byte = 0; Byte < DataLen; Byte++)
printf_P(PSTR("0x%02X "), ((uint8_t*)Data)[Byte]);
puts_P(PSTR("\r\n"));
break;
}
}

View file

@ -1,85 +1,85 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for BluetoothHost.c.
*/
#ifndef _BLUETOOTH_HOST_H_
#define _BLUETOOTH_HOST_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "Lib/ServiceDiscoveryProtocol.h"
#include "Lib/BluetoothStack.h"
#include "DeviceDescriptor.h"
#include "ConfigDescriptor.h"
#include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/Board/LEDs.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Task Definitions: */
void Bluetooth_Host_Task(void);
/* Event Handlers: */
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
void EVENT_USB_Host_DeviceEnumerationComplete(void);
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
/* Function Prototypes: */
void SetupHardware(void);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for BluetoothHost.c.
*/
#ifndef _BLUETOOTH_HOST_H_
#define _BLUETOOTH_HOST_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "Lib/ServiceDiscoveryProtocol.h"
#include "Lib/BluetoothStack.h"
#include "DeviceDescriptor.h"
#include "ConfigDescriptor.h"
#include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/Board/LEDs.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Task Definitions: */
void Bluetooth_Host_Task(void);
/* Event Handlers: */
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
void EVENT_USB_Host_DeviceEnumerationComplete(void);
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
/* Function Prototypes: */
void SetupHardware(void);
#endif

View file

@ -1,162 +1,162 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Configuration Descriptor processing routines, to determine the correct pipe configurations
* needed to communication with an attached USB device. Descriptors are special computer-readable structures
* which the host requests upon device enumeration, to determine the device's capabilities and functions.
*/
#include "ConfigDescriptor.h"
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This
* routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate
* with compatible devices.
*
* This routine searches for a BT interface descriptor containing bulk IN and OUT data endpoints.
*
* \return An error code from the \ref BluetoothHost_GetConfigDescriptorDataCodes_t enum.
*/
uint8_t ProcessConfigurationDescriptor(void)
{
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
{
case HOST_GETCONFIG_Successful:
break;
case HOST_GETCONFIG_InvalidData:
return InvalidConfigDataReturned;
case HOST_GETCONFIG_BuffOverflow:
return DescriptorTooLarge;
default:
return ControlError;
}
/* The bluetooth USB transport addendum mandates that the data (not streaming voice) endpoints
be in the first interface descriptor (interface 0) */
USB_GetNextDescriptorOfType(&CurrConfigBytesRem, &CurrConfigLocation, DTYPE_Interface);
/* Ensure that an interface was found, and the end of the descriptor was not reached */
if (!(CurrConfigBytesRem))
return NoBTInterfaceFound;
/* Get the data IN, data OUT and event notification endpoints for the bluetooth interface */
while (FoundEndpoints != ((1 << BLUETOOTH_DATA_IN_PIPE) | (1 << BLUETOOTH_DATA_OUT_PIPE) |
(1 << BLUETOOTH_EVENTS_PIPE)))
{
/* Fetch the next endpoint from the current bluetooth interface */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextInterfaceBluetoothDataEndpoint))
{
/* Descriptor not found, error out */
return NoEndpointFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk or interrupt type endpoint */
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the events IN pipe */
Pipe_ConfigurePipe(BLUETOOTH_EVENTS_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
/* Set the flag indicating that the events notification pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_EVENTS_PIPE);
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_DATA_IN_PIPE);
}
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_DATA_OUT_PIPE);
}
}
}
/* Valid data found, return success */
return SuccessfulConfigRead;
}
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
* descriptor processing if an incompatible descriptor configuration is found.
*
* This comparator searches for the next Endpoint descriptor inside the current interface descriptor, aborting the
* search if another interface descriptor is found before the required endpoint.
*
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
*/
uint8_t DComp_NextInterfaceBluetoothDataEndpoint(void* CurrentDescriptor)
{
/* Determine the type of the current descriptor */
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
/* Indicate that the descriptor being searched for has been found */
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
/* Indicate that the search has failed prematurely and should be aborted */
return DESCRIPTOR_SEARCH_Fail;
}
/* Current descriptor does not match what this comparator is looking for */
return DESCRIPTOR_SEARCH_NotFound;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Configuration Descriptor processing routines, to determine the correct pipe configurations
* needed to communication with an attached USB device. Descriptors are special computer-readable structures
* which the host requests upon device enumeration, to determine the device's capabilities and functions.
*/
#include "ConfigDescriptor.h"
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This
* routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate
* with compatible devices.
*
* This routine searches for a BT interface descriptor containing bulk IN and OUT data endpoints.
*
* \return An error code from the \ref BluetoothHost_GetConfigDescriptorDataCodes_t enum.
*/
uint8_t ProcessConfigurationDescriptor(void)
{
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
{
case HOST_GETCONFIG_Successful:
break;
case HOST_GETCONFIG_InvalidData:
return InvalidConfigDataReturned;
case HOST_GETCONFIG_BuffOverflow:
return DescriptorTooLarge;
default:
return ControlError;
}
/* The bluetooth USB transport addendum mandates that the data (not streaming voice) endpoints
be in the first interface descriptor (interface 0) */
USB_GetNextDescriptorOfType(&CurrConfigBytesRem, &CurrConfigLocation, DTYPE_Interface);
/* Ensure that an interface was found, and the end of the descriptor was not reached */
if (!(CurrConfigBytesRem))
return NoBTInterfaceFound;
/* Get the data IN, data OUT and event notification endpoints for the bluetooth interface */
while (FoundEndpoints != ((1 << BLUETOOTH_DATA_IN_PIPE) | (1 << BLUETOOTH_DATA_OUT_PIPE) |
(1 << BLUETOOTH_EVENTS_PIPE)))
{
/* Fetch the next endpoint from the current bluetooth interface */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextInterfaceBluetoothDataEndpoint))
{
/* Descriptor not found, error out */
return NoEndpointFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk or interrupt type endpoint */
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the events IN pipe */
Pipe_ConfigurePipe(BLUETOOTH_EVENTS_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
/* Set the flag indicating that the events notification pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_EVENTS_PIPE);
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_DATA_IN_PIPE);
}
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_DATA_OUT_PIPE);
}
}
}
/* Valid data found, return success */
return SuccessfulConfigRead;
}
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
* descriptor processing if an incompatible descriptor configuration is found.
*
* This comparator searches for the next Endpoint descriptor inside the current interface descriptor, aborting the
* search if another interface descriptor is found before the required endpoint.
*
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
*/
uint8_t DComp_NextInterfaceBluetoothDataEndpoint(void* CurrentDescriptor)
{
/* Determine the type of the current descriptor */
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
/* Indicate that the descriptor being searched for has been found */
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
/* Indicate that the search has failed prematurely and should be aborted */
return DESCRIPTOR_SEARCH_Fail;
}
/* Current descriptor does not match what this comparator is looking for */
return DESCRIPTOR_SEARCH_NotFound;
}

View file

@ -1,63 +1,63 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for ConfigDescriptor.c.
*/
#ifndef _CONFIGDESCRIPTOR_H_
#define _CONFIGDESCRIPTOR_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "BluetoothHost.h"
/* Enums: */
/** Enum for the possible return codes of the ProcessConfigurationDescriptor() function. */
enum BluetoothHost_GetConfigDescriptorDataCodes_t
{
SuccessfulConfigRead = 0, /**< Configuration Descriptor was processed successfully */
DevControlError = 1, /**< A control request to the device failed to complete successfully */
DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
NoBTInterfaceFound = 4, /**< A compatible Blutooth interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< A compatible set of Bluetooth endpoints were not found in the
* device's Bluetooth interface
*/
};
/* Function Prototypes: */
uint8_t ProcessConfigurationDescriptor(void);
uint8_t DComp_NextInterfaceBluetoothDataEndpoint(void* CurrentDescriptor);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for ConfigDescriptor.c.
*/
#ifndef _CONFIGDESCRIPTOR_H_
#define _CONFIGDESCRIPTOR_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "BluetoothHost.h"
/* Enums: */
/** Enum for the possible return codes of the ProcessConfigurationDescriptor() function. */
enum BluetoothHost_GetConfigDescriptorDataCodes_t
{
SuccessfulConfigRead = 0, /**< Configuration Descriptor was processed successfully */
DevControlError = 1, /**< A control request to the device failed to complete successfully */
DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
NoBTInterfaceFound = 4, /**< A compatible Blutooth interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< A compatible set of Bluetooth endpoints were not found in the
* device's Bluetooth interface
*/
};
/* Function Prototypes: */
uint8_t ProcessConfigurationDescriptor(void);
uint8_t DComp_NextInterfaceBluetoothDataEndpoint(void* CurrentDescriptor);
#endif

View file

@ -1,67 +1,67 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Descriptor processing routines, to determine the overall device parameters. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine information about
* the attached device.
*/
#include "DeviceDescriptor.h"
/** Reads and processes an attached device's Device Descriptor, to determine compatibility
*
* This routine checks to ensure that the attached device's class codes match those for Bluetooth devices.
*
* \return An error code from the \ref BluetoothHost_GetDeviceDescriptorDataCodes_t enum.
*/
uint8_t ProcessDeviceDescriptor(void)
{
USB_Descriptor_Device_t DeviceDescriptor;
/* Send the request to retrieve the device descriptor */
if (USB_Host_GetDeviceDescriptor(&DeviceDescriptor) != HOST_SENDCONTROL_Successful)
return DevControlError;
/* Validate returned data - ensure the returned data is a device descriptor */
if (DeviceDescriptor.Header.Type != DTYPE_Device)
return InvalidDeviceDataReturned;
/* Validate returned device Class, SubClass and Protocol values against the Bluetooth spec values */
if ((DeviceDescriptor.Class != BLUETOOTH_DEVICE_CLASS) ||
(DeviceDescriptor.SubClass != BLUETOOTH_DEVICE_SUBCLASS) ||
(DeviceDescriptor.Protocol != BLUETOOTH_DEVICE_PROTOCOL))
{
return IncorrectBTDevice;
}
return SuccessfulDeviceRead;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Descriptor processing routines, to determine the overall device parameters. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine information about
* the attached device.
*/
#include "DeviceDescriptor.h"
/** Reads and processes an attached device's Device Descriptor, to determine compatibility
*
* This routine checks to ensure that the attached device's class codes match those for Bluetooth devices.
*
* \return An error code from the \ref BluetoothHost_GetDeviceDescriptorDataCodes_t enum.
*/
uint8_t ProcessDeviceDescriptor(void)
{
USB_Descriptor_Device_t DeviceDescriptor;
/* Send the request to retrieve the device descriptor */
if (USB_Host_GetDeviceDescriptor(&DeviceDescriptor) != HOST_SENDCONTROL_Successful)
return DevControlError;
/* Validate returned data - ensure the returned data is a device descriptor */
if (DeviceDescriptor.Header.Type != DTYPE_Device)
return InvalidDeviceDataReturned;
/* Validate returned device Class, SubClass and Protocol values against the Bluetooth spec values */
if ((DeviceDescriptor.Class != BLUETOOTH_DEVICE_CLASS) ||
(DeviceDescriptor.SubClass != BLUETOOTH_DEVICE_SUBCLASS) ||
(DeviceDescriptor.Protocol != BLUETOOTH_DEVICE_PROTOCOL))
{
return IncorrectBTDevice;
}
return SuccessfulDeviceRead;
}

View file

@ -1,66 +1,66 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for DeviceDescriptor.c.
*/
#ifndef _DEVICEDESCRIPTOR_H_
#define _DEVICEDESCRIPTOR_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "BluetoothHost.h"
/* Macros: */
/** Device Class value for the Bluetooth Device class */
#define BLUETOOTH_DEVICE_CLASS 0xE0
/** Device Subclass value for the Bluetooth Device class */
#define BLUETOOTH_DEVICE_SUBCLASS 0x01
/** Device Protocol value for the Bluetooth Device class */
#define BLUETOOTH_DEVICE_PROTOCOL 0x01
/* Enums: */
enum BluetoothHost_GetDeviceDescriptorDataCodes_t
{
SuccessfulDeviceRead = 0, /**< Device Descriptor was processed successfully */
ControlError = 1, /**< A control request to the device failed to complete successfully */
InvalidDeviceDataReturned = 2, /**< The device returned an invalid Device Descriptor */
IncorrectBTDevice = 3, /**< The attached device is not a Bluetooth class device */
};
/* Function Prototypes: */
uint8_t ProcessDeviceDescriptor(void);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for DeviceDescriptor.c.
*/
#ifndef _DEVICEDESCRIPTOR_H_
#define _DEVICEDESCRIPTOR_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "BluetoothHost.h"
/* Macros: */
/** Device Class value for the Bluetooth Device class */
#define BLUETOOTH_DEVICE_CLASS 0xE0
/** Device Subclass value for the Bluetooth Device class */
#define BLUETOOTH_DEVICE_SUBCLASS 0x01
/** Device Protocol value for the Bluetooth Device class */
#define BLUETOOTH_DEVICE_PROTOCOL 0x01
/* Enums: */
enum BluetoothHost_GetDeviceDescriptorDataCodes_t
{
SuccessfulDeviceRead = 0, /**< Device Descriptor was processed successfully */
ControlError = 1, /**< A control request to the device failed to complete successfully */
InvalidDeviceDataReturned = 2, /**< The device returned an invalid Device Descriptor */
IncorrectBTDevice = 3, /**< The attached device is not a Bluetooth class device */
};
/* Function Prototypes: */
uint8_t ProcessDeviceDescriptor(void);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,176 +1,176 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_ACLPACKETS_
#define _BLUETOOTH_ACLPACKETS_
/* Includes: */
#include <avr/io.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "BluetoothStack.h"
/* Macros: */
#define BT_ACL_DEBUG(l, s, ...) do { if (ACL_DEBUG_LEVEL >= l) printf_P(PSTR("(ACL) " s "\r\n"), ##__VA_ARGS__); } while (0)
#define ACL_DEBUG_LEVEL 0
#define BT_CHANNELNUMBER_BASEOFFSET 0x0040
#define BT_CHANNEL_SIGNALING 0x0001
#define BT_CHANNEL_CONNECTIONLESS 0x0002
#define BT_SIGNAL_COMMAND_REJECT 0x01
#define BT_SIGNAL_CONNECTION_REQUEST 0x02
#define BT_SIGNAL_CONNECTION_RESPONSE 0x03
#define BT_SIGNAL_CONFIGURATION_REQUEST 0x04
#define BT_SIGNAL_CONFIGURATION_RESPONSE 0x05
#define BT_SIGNAL_DISCONNECTION_REQUEST 0x06
#define BT_SIGNAL_DISCONNECTION_RESPONSE 0x07
#define BT_SIGNAL_ECHO_REQUEST 0x08
#define BT_SIGNAL_ECHO_RESPONSE 0x09
#define BT_SIGNAL_INFORMATION_REQUEST 0x0A
#define BT_SIGNAL_INFORMATION_RESPONSE 0x0B
#define BT_INFOREQ_MTU 0x0001
#define BT_INFOREQ_EXTENDEDFEATURES 0x0002
#define BT_INFORMATION_SUCCESSFUL 0x0000
#define BT_INFORMATION_NOTSUPPORTED 0x0001
#define BT_CONNECTION_SUCCESSFUL 0x0000
#define BT_CONNECTION_REFUSED_PSM 0x0002
#define BT_CONNECTION_REFUSED_RESOURCES 0x0004
#define BT_CONFIGURATION_SUCCESSFUL 0x0000
#define BT_CONFIGURATION_REJECTED 0x0002
#define BT_CONFIGURATION_UNKNOWNOPTIONS 0x0003
#define BT_CONFIG_OPTION_MTU 1
#define BT_ACL_FIRST_AUTOFLUSH (1 << 13)
/* Type Defines: */
typedef struct
{
uint16_t ConnectionHandle;
uint16_t DataLength;
} BT_ACL_Header_t;
typedef struct
{
uint16_t PayloadLength;
uint16_t DestinationChannel;
} BT_DataPacket_Header_t;
typedef struct
{
uint8_t Code;
uint8_t Identifier;
uint16_t Length;
} BT_Signal_Header_t;
typedef struct
{
uint16_t PSM;
uint16_t SourceChannel;
} BT_Signal_ConnectionReq_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t SourceChannel;
uint16_t Result;
uint16_t Status;
} BT_Signal_ConnectionResp_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t SourceChannel;
} BT_Signal_DisconnectionReq_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t SourceChannel;
} BT_Signal_DisconnectionResp_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t Flags;
} BT_Signal_ConfigurationReq_t;
typedef struct
{
uint16_t SourceChannel;
uint16_t Flags;
uint16_t Result;
} BT_Signal_ConfigurationResp_t;
typedef struct
{
uint16_t InfoType;
} BT_Signal_InformationReq_t;
typedef struct
{
uint16_t InfoType;
uint16_t Result;
} BT_Signal_InformationResp_t;
typedef struct
{
uint8_t Type;
uint8_t Length;
} BT_Config_Option_Header_t;
/* Function Prototypes: */
void Bluetooth_ACLTask(void);
#if defined(INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C)
static void Bluetooth_ProcessIncommingACLPackets(void);
static inline void Bluetooth_Signal_ConnectionReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_ConnectionResp(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_ConfigurationReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_ConfigurationResp(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_DisconnectionReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_DisconnectionResp(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_EchoReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_InformationReq(const BT_Signal_Header_t* const SignalCommandHeader);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_ACLPACKETS_
#define _BLUETOOTH_ACLPACKETS_
/* Includes: */
#include <avr/io.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "BluetoothStack.h"
/* Macros: */
#define BT_ACL_DEBUG(l, s, ...) do { if (ACL_DEBUG_LEVEL >= l) printf_P(PSTR("(ACL) " s "\r\n"), ##__VA_ARGS__); } while (0)
#define ACL_DEBUG_LEVEL 0
#define BT_CHANNELNUMBER_BASEOFFSET 0x0040
#define BT_CHANNEL_SIGNALING 0x0001
#define BT_CHANNEL_CONNECTIONLESS 0x0002
#define BT_SIGNAL_COMMAND_REJECT 0x01
#define BT_SIGNAL_CONNECTION_REQUEST 0x02
#define BT_SIGNAL_CONNECTION_RESPONSE 0x03
#define BT_SIGNAL_CONFIGURATION_REQUEST 0x04
#define BT_SIGNAL_CONFIGURATION_RESPONSE 0x05
#define BT_SIGNAL_DISCONNECTION_REQUEST 0x06
#define BT_SIGNAL_DISCONNECTION_RESPONSE 0x07
#define BT_SIGNAL_ECHO_REQUEST 0x08
#define BT_SIGNAL_ECHO_RESPONSE 0x09
#define BT_SIGNAL_INFORMATION_REQUEST 0x0A
#define BT_SIGNAL_INFORMATION_RESPONSE 0x0B
#define BT_INFOREQ_MTU 0x0001
#define BT_INFOREQ_EXTENDEDFEATURES 0x0002
#define BT_INFORMATION_SUCCESSFUL 0x0000
#define BT_INFORMATION_NOTSUPPORTED 0x0001
#define BT_CONNECTION_SUCCESSFUL 0x0000
#define BT_CONNECTION_REFUSED_PSM 0x0002
#define BT_CONNECTION_REFUSED_RESOURCES 0x0004
#define BT_CONFIGURATION_SUCCESSFUL 0x0000
#define BT_CONFIGURATION_REJECTED 0x0002
#define BT_CONFIGURATION_UNKNOWNOPTIONS 0x0003
#define BT_CONFIG_OPTION_MTU 1
#define BT_ACL_FIRST_AUTOFLUSH (1 << 13)
/* Type Defines: */
typedef struct
{
uint16_t ConnectionHandle;
uint16_t DataLength;
} BT_ACL_Header_t;
typedef struct
{
uint16_t PayloadLength;
uint16_t DestinationChannel;
} BT_DataPacket_Header_t;
typedef struct
{
uint8_t Code;
uint8_t Identifier;
uint16_t Length;
} BT_Signal_Header_t;
typedef struct
{
uint16_t PSM;
uint16_t SourceChannel;
} BT_Signal_ConnectionReq_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t SourceChannel;
uint16_t Result;
uint16_t Status;
} BT_Signal_ConnectionResp_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t SourceChannel;
} BT_Signal_DisconnectionReq_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t SourceChannel;
} BT_Signal_DisconnectionResp_t;
typedef struct
{
uint16_t DestinationChannel;
uint16_t Flags;
} BT_Signal_ConfigurationReq_t;
typedef struct
{
uint16_t SourceChannel;
uint16_t Flags;
uint16_t Result;
} BT_Signal_ConfigurationResp_t;
typedef struct
{
uint16_t InfoType;
} BT_Signal_InformationReq_t;
typedef struct
{
uint16_t InfoType;
uint16_t Result;
} BT_Signal_InformationResp_t;
typedef struct
{
uint8_t Type;
uint8_t Length;
} BT_Config_Option_Header_t;
/* Function Prototypes: */
void Bluetooth_ACLTask(void);
#if defined(INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C)
static void Bluetooth_ProcessIncommingACLPackets(void);
static inline void Bluetooth_Signal_ConnectionReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_ConnectionResp(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_ConfigurationReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_ConfigurationResp(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_DisconnectionReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_DisconnectionResp(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_EchoReq(const BT_Signal_Header_t* const SignalCommandHeader);
static inline void Bluetooth_Signal_InformationReq(const BT_Signal_Header_t* const SignalCommandHeader);
#endif
#endif

View file

@ -1,110 +1,110 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_CLASS_CODES_H_
#define _BLUETOOTH_CLASS_CODES_H_
/* Macros: */
#define DEVICE_CLASS_SERVICE_POSITIONING (1UL << 16)
#define DEVICE_CLASS_SERVICE_NETWORKING (1UL << 17)
#define DEVICE_CLASS_SERVICE_RENDERING (1UL << 18)
#define DEVICE_CLASS_SERVICE_CAPTURING (1UL << 19)
#define DEVICE_CLASS_SERVICE_OBJECTTRANSFER (1UL << 20)
#define DEVICE_CLASS_SERVICE_AUDIO (1UL << 21)
#define DEVICE_CLASS_SERVICE_TELEPHONY (1UL << 22)
#define DEVICE_CLASS_SERVICE_INFORMATION (1UL << 23)
#define DEVICE_CLASS_MAJOR_MISC (0x00 << 8)
#define DEVICE_CLASS_MAJOR_COMPUTER (0x01 << 8)
#define DEVICE_CLASS_MAJOR_PHONE (0x02 << 8)
#define DEVICE_CLASS_MAJOR_LAN (0x03 << 8)
#define DEVICE_CLASS_MAJOR_AUDIOVIDEO (0x04 << 8)
#define DEVICE_CLASS_MAJOR_PERIPHERAL (0x05 << 8)
#define DEVICE_CLASS_MAJOR_IMAGING (0x06 << 8)
#define DEVICE_CLASS_MAJOR_UNCLASSIFIED (0x1F << 8)
#define DEVICE_CLASS_MINOR_COMPUTER_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_DESKTOP (0x01 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_SERVER (0x02 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_LAPTOP (0x03 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_HANDHELD (0x04 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_PALM (0x05 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_WEARABLE (0x06 << 2)
#define DEVICE_CLASS_MINOR_PHONE_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_PHONE_CELLULAR (0x01 << 2)
#define DEVICE_CLASS_MINOR_PHONE_CORDLESS (0x02 << 2)
#define DEVICE_CLASS_MINOR_PHONE_SMARTPHONE (0x03 << 2)
#define DEVICE_CLASS_MINOR_PHONE_WIREDMODEM (0x04 << 2)
#define DEVICE_CLASS_MINOR_PHONE_ISDN (0x05 << 2)
#define DEVICE_CLASS_MINOR_LAN_FULLY_AVAILABLE (0x00 << 5)
#define DEVICE_CLASS_MINOR_LAN_1_TO_17_PC_UTILIZED (0x01 << 5)
#define DEVICE_CLASS_MINOR_LAN_17_TO_33_PC_UTILIZED (0x02 << 5)
#define DEVICE_CLASS_MINOR_LAN_33_TO_50_PC_UTILIZED (0x03 << 5)
#define DEVICE_CLASS_MINOR_LAN_50_TO_67_PC_UTILIZED (0x04 << 5)
#define DEVICE_CLASS_MINOR_LAN_67_TO_83_PC_UTILIZED (0x05 << 5)
#define DEVICE_CLASS_MINOR_LAN_83_TO_99_PC_UTILIZED (0x06 << 5)
#define DEVICE_CLASS_MINOR_NO_SERVICE_AVAILABLE (0x07 << 5)
#define DEVICE_CLASS_MINOR_AV_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_AV_HEADSET (0x01 << 2)
#define DEVICE_CLASS_MINOR_AV_HANDSFREE (0x02 << 2)
#define DEVICE_CLASS_MINOR_AV_MICROPHONE (0x04 << 2)
#define DEVICE_CLASS_MINOR_AV_LOUDSPEAKER (0x05 << 2)
#define DEVICE_CLASS_MINOR_AV_HEADPHONES (0x06 << 2)
#define DEVICE_CLASS_MINOR_AV_PORTABLE_AUDIO (0x07 << 2)
#define DEVICE_CLASS_MINOR_AV_CARAUDIO (0x08 << 2)
#define DEVICE_CLASS_MINOR_AV_SETTOP_BOX (0x09 << 2)
#define DEVICE_CLASS_MINOR_AV_HIFI (0x0A << 2)
#define DEVICE_CLASS_MINOR_AV_VCR (0x0B << 2)
#define DEVICE_CLASS_MINOR_AV_VIDEO_CAMERA (0x0C << 2)
#define DEVICE_CLASS_MINOR_AV_CAMCORDER (0x0D << 2)
#define DEVICE_CLASS_MINOR_AV_VIDEO_MONITOR (0x0E << 2)
#define DEVICE_CLASS_MINOR_AV_DISPLAY_AND_LOUDSPEAKER (0x0F << 2)
#define DEVICE_CLASS_MINOR_AV_VIDEO_CONFERENCING (0x10 << 2)
#define DEVICE_CLASS_MINOR_AV_GAMING_TOY (0x12 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_KEYBOARD (0x01 << 6)
#define DEVICE_CLASS_MINOR_PERIPHERAL_POINTING (0x02 << 6)
#define DEVICE_CLASS_MINOR_PERIPHERAL_COMBO (0x03 << 6)
#define DEVICE_CLASS_MINOR_PERIPHERAL_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_JOYSTICK (0x01 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_GAMEPAD (0x02 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_REMOTE_CONTROL (0x03 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_SENSING_DEVICE (0x04 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_DIGITIZER (0x05 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_CARD_READER (0x06 << 2)
#define DEVICE_CLASS_MINOR_IMAGING_DISPLAY (1 << 4)
#define DEVICE_CLASS_MINOR_IMAGING_CAMERA (1 << 5)
#define DEVICE_CLASS_MINOR_IMAGING_SCANNER (1 << 6)
#define DEVICE_CLASS_MINOR_IMAGING_PRINTER (1 << 7)
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_CLASS_CODES_H_
#define _BLUETOOTH_CLASS_CODES_H_
/* Macros: */
#define DEVICE_CLASS_SERVICE_POSITIONING (1UL << 16)
#define DEVICE_CLASS_SERVICE_NETWORKING (1UL << 17)
#define DEVICE_CLASS_SERVICE_RENDERING (1UL << 18)
#define DEVICE_CLASS_SERVICE_CAPTURING (1UL << 19)
#define DEVICE_CLASS_SERVICE_OBJECTTRANSFER (1UL << 20)
#define DEVICE_CLASS_SERVICE_AUDIO (1UL << 21)
#define DEVICE_CLASS_SERVICE_TELEPHONY (1UL << 22)
#define DEVICE_CLASS_SERVICE_INFORMATION (1UL << 23)
#define DEVICE_CLASS_MAJOR_MISC (0x00 << 8)
#define DEVICE_CLASS_MAJOR_COMPUTER (0x01 << 8)
#define DEVICE_CLASS_MAJOR_PHONE (0x02 << 8)
#define DEVICE_CLASS_MAJOR_LAN (0x03 << 8)
#define DEVICE_CLASS_MAJOR_AUDIOVIDEO (0x04 << 8)
#define DEVICE_CLASS_MAJOR_PERIPHERAL (0x05 << 8)
#define DEVICE_CLASS_MAJOR_IMAGING (0x06 << 8)
#define DEVICE_CLASS_MAJOR_UNCLASSIFIED (0x1F << 8)
#define DEVICE_CLASS_MINOR_COMPUTER_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_DESKTOP (0x01 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_SERVER (0x02 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_LAPTOP (0x03 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_HANDHELD (0x04 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_PALM (0x05 << 2)
#define DEVICE_CLASS_MINOR_COMPUTER_WEARABLE (0x06 << 2)
#define DEVICE_CLASS_MINOR_PHONE_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_PHONE_CELLULAR (0x01 << 2)
#define DEVICE_CLASS_MINOR_PHONE_CORDLESS (0x02 << 2)
#define DEVICE_CLASS_MINOR_PHONE_SMARTPHONE (0x03 << 2)
#define DEVICE_CLASS_MINOR_PHONE_WIREDMODEM (0x04 << 2)
#define DEVICE_CLASS_MINOR_PHONE_ISDN (0x05 << 2)
#define DEVICE_CLASS_MINOR_LAN_FULLY_AVAILABLE (0x00 << 5)
#define DEVICE_CLASS_MINOR_LAN_1_TO_17_PC_UTILIZED (0x01 << 5)
#define DEVICE_CLASS_MINOR_LAN_17_TO_33_PC_UTILIZED (0x02 << 5)
#define DEVICE_CLASS_MINOR_LAN_33_TO_50_PC_UTILIZED (0x03 << 5)
#define DEVICE_CLASS_MINOR_LAN_50_TO_67_PC_UTILIZED (0x04 << 5)
#define DEVICE_CLASS_MINOR_LAN_67_TO_83_PC_UTILIZED (0x05 << 5)
#define DEVICE_CLASS_MINOR_LAN_83_TO_99_PC_UTILIZED (0x06 << 5)
#define DEVICE_CLASS_MINOR_NO_SERVICE_AVAILABLE (0x07 << 5)
#define DEVICE_CLASS_MINOR_AV_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_AV_HEADSET (0x01 << 2)
#define DEVICE_CLASS_MINOR_AV_HANDSFREE (0x02 << 2)
#define DEVICE_CLASS_MINOR_AV_MICROPHONE (0x04 << 2)
#define DEVICE_CLASS_MINOR_AV_LOUDSPEAKER (0x05 << 2)
#define DEVICE_CLASS_MINOR_AV_HEADPHONES (0x06 << 2)
#define DEVICE_CLASS_MINOR_AV_PORTABLE_AUDIO (0x07 << 2)
#define DEVICE_CLASS_MINOR_AV_CARAUDIO (0x08 << 2)
#define DEVICE_CLASS_MINOR_AV_SETTOP_BOX (0x09 << 2)
#define DEVICE_CLASS_MINOR_AV_HIFI (0x0A << 2)
#define DEVICE_CLASS_MINOR_AV_VCR (0x0B << 2)
#define DEVICE_CLASS_MINOR_AV_VIDEO_CAMERA (0x0C << 2)
#define DEVICE_CLASS_MINOR_AV_CAMCORDER (0x0D << 2)
#define DEVICE_CLASS_MINOR_AV_VIDEO_MONITOR (0x0E << 2)
#define DEVICE_CLASS_MINOR_AV_DISPLAY_AND_LOUDSPEAKER (0x0F << 2)
#define DEVICE_CLASS_MINOR_AV_VIDEO_CONFERENCING (0x10 << 2)
#define DEVICE_CLASS_MINOR_AV_GAMING_TOY (0x12 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_KEYBOARD (0x01 << 6)
#define DEVICE_CLASS_MINOR_PERIPHERAL_POINTING (0x02 << 6)
#define DEVICE_CLASS_MINOR_PERIPHERAL_COMBO (0x03 << 6)
#define DEVICE_CLASS_MINOR_PERIPHERAL_UNCATEGORIZED (0x00 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_JOYSTICK (0x01 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_GAMEPAD (0x02 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_REMOTE_CONTROL (0x03 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_SENSING_DEVICE (0x04 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_DIGITIZER (0x05 << 2)
#define DEVICE_CLASS_MINOR_PERIPHERAL_CARD_READER (0x06 << 2)
#define DEVICE_CLASS_MINOR_IMAGING_DISPLAY (1 << 4)
#define DEVICE_CLASS_MINOR_IMAGING_CAMERA (1 << 5)
#define DEVICE_CLASS_MINOR_IMAGING_SCANNER (1 << 6)
#define DEVICE_CLASS_MINOR_IMAGING_PRINTER (1 << 7)
#endif

View file

@ -1,396 +1,396 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/*
TODO: Add local to remote device connections
*/
#define INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C
#include "BluetoothHCICommands.h"
/** 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.
*/
void Bluetooth_HCITask(void)
{
BT_HCICommand_Header_t HCICommandHeader;
switch (Bluetooth_State.CurrentHCIState)
{
case Bluetooth_ProcessEvents:
Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
Pipe_Unfreeze();
if (Pipe_IsReadWriteAllowed())
{
BT_HCIEvent_Header_t HCIEventHeader;
/* Read in the event header to fetch the event code and payload length */
Pipe_Read_Stream_LE(&HCIEventHeader, sizeof(HCIEventHeader));
/* Create a temporary buffer for the event parameters */
uint8_t EventParams[HCIEventHeader.ParameterLength];
/* Read in the event parameters into the temporary buffer */
Pipe_Read_Stream_LE(&EventParams, HCIEventHeader.ParameterLength);
Pipe_ClearIN();
BT_HCI_DEBUG(1, "Event Received (0x%02X)", HCIEventHeader.EventCode);
switch (HCIEventHeader.EventCode)
{
case EVENT_COMMAND_COMPLETE:
BT_HCI_DEBUG(1, "<< Command Complete");
/* 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");
BT_HCI_DEBUG(2, "-- Status Code: 0x%02X", (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status));
/* If the execution of a command failed, reset the stack */
if (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status)
Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break;
case EVENT_CONNECTION_REQUEST:
BT_HCI_DEBUG(1, "<< Connection Request");
BT_HCI_DEBUG(2, "-- Link Type: 0x%02X", (((BT_HCIEvent_ConnectionRequest_t*)&EventParams)->LinkType));
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress,
&((BT_HCIEvent_ConnectionRequest_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
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
and the user application has indicated that the connection should be allowed */
Bluetooth_State.CurrentHCIState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) ||
!(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ?
Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;
BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_State.CurrentHCIState == Bluetooth_Conn_RejectConnection) ?
PSTR("REJECTED") : PSTR("ACCEPTED"));
break;
case EVENT_PIN_CODE_REQUEST:
BT_HCI_DEBUG(1, "<< Pin Code Request");
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress,
&((BT_HCIEvent_PinCodeReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendPINCode;
break;
case EVENT_LINK_KEY_REQUEST:
BT_HCI_DEBUG(1, "<< Link Key Request");
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress,
&((BT_HCIEvent_LinkKeyReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendLinkKeyNAK;
break;
case EVENT_CONNECTION_COMPLETE:
BT_HCI_DEBUG(1, "<< Connection Complete");
BT_HCI_DEBUG(2, "-- Handle: 0x%04X", ((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->ConnectionHandle);
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_Connection.RemoteAddress,
&((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
/* Store the created connection handle and indicate that the connection has been established */
Bluetooth_Connection.ConnectionHandle = ((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->ConnectionHandle;
Bluetooth_Connection.IsConnected = true;
Bluetooth_ConnectionComplete();
break;
case EVENT_DISCONNECTION_COMPLETE:
BT_HCI_DEBUG(1, "<< Disconnection Complete");
/* Device disconnected, indicate connection information no longer valid */
Bluetooth_Connection.IsConnected = false;
Bluetooth_DisconnectionComplete();
Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break;
}
}
Pipe_Freeze();
break;
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_State.CurrentHCIState = Bluetooth_Init_Reset;
break;
case Bluetooth_Init_Reset:
BT_HCI_DEBUG(1, "# Reset");
HCICommandHeader = (BT_HCICommand_Header_t)
{
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_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_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_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_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_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_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE),
ParameterLength: 1,
};
uint8_t Interval = BT_SCANMODE_InquiryAndPageScans;
/* Send the command to set the remote device scanning mode */
Bluetooth_SendHCICommand(&HCICommandHeader, &Interval, 1);
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_LINK_CONTROL | OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_AcceptConnectionReq_t),
};
/* Copy over the temporary BT device address saved from the Connection Request event, indicate slave
connection role */
BT_HCICommand_AcceptConnectionReq_t AcceptConnectionParams;
memcpy(AcceptConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress,
sizeof(AcceptConnectionParams.RemoteAddress));
AcceptConnectionParams.SlaveRole = true;
/* Send the command to accept the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &AcceptConnectionParams, sizeof(BT_HCICommand_AcceptConnectionReq_t));
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_RejectConnection:
BT_HCI_DEBUG(1, "# Reject Connection");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_RejectConnectionReq_t),
};
/* 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 */
BT_HCICommand_RejectConnectionReq_t RejectConnectionParams;
memcpy(RejectConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(RejectConnectionParams.RemoteAddress));
RejectConnectionParams.Reason = Bluetooth_Connection.IsConnected ? ERROR_LIMITED_RESOURCES : ERROR_UNACCEPTABLE_BDADDR;
/* Send the command to reject the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &RejectConnectionParams, sizeof(BT_HCICommand_RejectConnectionReq_t));
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_SendPINCode:
BT_HCI_DEBUG(1, "# Send Pin Code");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY),
ParameterLength: sizeof(BT_HCICommand_PinCodeResp_t),
};
/* Copy over the temporary BT device address saved from the PIN Code Request event, copy over the
local PIN authentication code to the response */
BT_HCICommand_PinCodeResp_t PINCodeRequestParams;
memcpy(PINCodeRequestParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(PINCodeRequestParams.RemoteAddress));
PINCodeRequestParams.PINCodeLength = strlen(Bluetooth_DeviceConfiguration.PINCode);
memcpy(PINCodeRequestParams.PINCode, Bluetooth_DeviceConfiguration.PINCode, sizeof(PINCodeRequestParams.PINCode));
/* Send the command to transmit the device's local PIN number for authentication */
Bluetooth_SendHCICommand(&HCICommandHeader, &PINCodeRequestParams, sizeof(BT_HCICommand_PinCodeResp_t));
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_LINK_CONTROL | OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY),
ParameterLength: sizeof(BT_HCICommand_LinkKeyNAKResp_t),
};
/* Copy over the temporary BT device address saved from the Link Key Request event */
BT_HCICommand_LinkKeyNAKResp_t LinkKeyNAKParams;
memcpy(LinkKeyNAKParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(LinkKeyNAKParams.RemoteAddress));
/* Send the command to transmit the link key NAK to the receiver */
Bluetooth_SendHCICommand(&HCICommandHeader, &LinkKeyNAKParams, sizeof(BT_HCICommand_LinkKeyNAKResp_t));
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
}
}
/** Sends a Bluetooth HCI control command to the attached Bluetooth device.
*
* \param[in] HCICommandHeader HCI command header to send to the attached device
* \param[in] Parameters Pointer to the source of the control parameters (if any)
* \param[in] ParameterLength Length of the parameters to send in bytes
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum.
*/
static uint8_t Bluetooth_SendHCICommand(const BT_HCICommand_Header_t* const HCICommandHeader, const void* Parameters, const uint16_t ParameterLength)
{
/* Need to reserve the amount of bytes given in the header for the complete payload */
uint8_t CommandBuffer[sizeof(BT_HCICommand_Header_t) + 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(BT_HCICommand_Header_t));
/* Zero out the parameter section of the response so that all padding bytes are known to be zero */
memset(&CommandBuffer[sizeof(BT_HCICommand_Header_t)], 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(BT_HCICommand_Header_t)], Parameters, ParameterLength);
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(CommandBuffer);
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/*
TODO: Add local to remote device connections
*/
#define INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C
#include "BluetoothHCICommands.h"
/** 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.
*/
void Bluetooth_HCITask(void)
{
BT_HCICommand_Header_t HCICommandHeader;
switch (Bluetooth_State.CurrentHCIState)
{
case Bluetooth_ProcessEvents:
Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
Pipe_Unfreeze();
if (Pipe_IsReadWriteAllowed())
{
BT_HCIEvent_Header_t HCIEventHeader;
/* Read in the event header to fetch the event code and payload length */
Pipe_Read_Stream_LE(&HCIEventHeader, sizeof(HCIEventHeader));
/* Create a temporary buffer for the event parameters */
uint8_t EventParams[HCIEventHeader.ParameterLength];
/* Read in the event parameters into the temporary buffer */
Pipe_Read_Stream_LE(&EventParams, HCIEventHeader.ParameterLength);
Pipe_ClearIN();
BT_HCI_DEBUG(1, "Event Received (0x%02X)", HCIEventHeader.EventCode);
switch (HCIEventHeader.EventCode)
{
case EVENT_COMMAND_COMPLETE:
BT_HCI_DEBUG(1, "<< Command Complete");
/* 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");
BT_HCI_DEBUG(2, "-- Status Code: 0x%02X", (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status));
/* If the execution of a command failed, reset the stack */
if (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status)
Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break;
case EVENT_CONNECTION_REQUEST:
BT_HCI_DEBUG(1, "<< Connection Request");
BT_HCI_DEBUG(2, "-- Link Type: 0x%02X", (((BT_HCIEvent_ConnectionRequest_t*)&EventParams)->LinkType));
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress,
&((BT_HCIEvent_ConnectionRequest_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
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
and the user application has indicated that the connection should be allowed */
Bluetooth_State.CurrentHCIState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) ||
!(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ?
Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;
BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_State.CurrentHCIState == Bluetooth_Conn_RejectConnection) ?
PSTR("REJECTED") : PSTR("ACCEPTED"));
break;
case EVENT_PIN_CODE_REQUEST:
BT_HCI_DEBUG(1, "<< Pin Code Request");
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress,
&((BT_HCIEvent_PinCodeReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendPINCode;
break;
case EVENT_LINK_KEY_REQUEST:
BT_HCI_DEBUG(1, "<< Link Key Request");
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_TempDeviceAddress,
&((BT_HCIEvent_LinkKeyReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendLinkKeyNAK;
break;
case EVENT_CONNECTION_COMPLETE:
BT_HCI_DEBUG(1, "<< Connection Complete");
BT_HCI_DEBUG(2, "-- Handle: 0x%04X", ((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->ConnectionHandle);
/* Need to store the remote device's BT address in a temporary buffer for later use */
memcpy(Bluetooth_Connection.RemoteAddress,
&((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress));
/* Store the created connection handle and indicate that the connection has been established */
Bluetooth_Connection.ConnectionHandle = ((BT_HCIEvent_ConnectionComplete_t*)&EventParams)->ConnectionHandle;
Bluetooth_Connection.IsConnected = true;
Bluetooth_ConnectionComplete();
break;
case EVENT_DISCONNECTION_COMPLETE:
BT_HCI_DEBUG(1, "<< Disconnection Complete");
/* Device disconnected, indicate connection information no longer valid */
Bluetooth_Connection.IsConnected = false;
Bluetooth_DisconnectionComplete();
Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break;
}
}
Pipe_Freeze();
break;
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_State.CurrentHCIState = Bluetooth_Init_Reset;
break;
case Bluetooth_Init_Reset:
BT_HCI_DEBUG(1, "# Reset");
HCICommandHeader = (BT_HCICommand_Header_t)
{
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_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_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_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_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_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_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE),
ParameterLength: 1,
};
uint8_t Interval = BT_SCANMODE_InquiryAndPageScans;
/* Send the command to set the remote device scanning mode */
Bluetooth_SendHCICommand(&HCICommandHeader, &Interval, 1);
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_LINK_CONTROL | OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_AcceptConnectionReq_t),
};
/* Copy over the temporary BT device address saved from the Connection Request event, indicate slave
connection role */
BT_HCICommand_AcceptConnectionReq_t AcceptConnectionParams;
memcpy(AcceptConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress,
sizeof(AcceptConnectionParams.RemoteAddress));
AcceptConnectionParams.SlaveRole = true;
/* Send the command to accept the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &AcceptConnectionParams, sizeof(BT_HCICommand_AcceptConnectionReq_t));
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_RejectConnection:
BT_HCI_DEBUG(1, "# Reject Connection");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_RejectConnectionReq_t),
};
/* 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 */
BT_HCICommand_RejectConnectionReq_t RejectConnectionParams;
memcpy(RejectConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(RejectConnectionParams.RemoteAddress));
RejectConnectionParams.Reason = Bluetooth_Connection.IsConnected ? ERROR_LIMITED_RESOURCES : ERROR_UNACCEPTABLE_BDADDR;
/* Send the command to reject the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &RejectConnectionParams, sizeof(BT_HCICommand_RejectConnectionReq_t));
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Conn_SendPINCode:
BT_HCI_DEBUG(1, "# Send Pin Code");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY),
ParameterLength: sizeof(BT_HCICommand_PinCodeResp_t),
};
/* Copy over the temporary BT device address saved from the PIN Code Request event, copy over the
local PIN authentication code to the response */
BT_HCICommand_PinCodeResp_t PINCodeRequestParams;
memcpy(PINCodeRequestParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(PINCodeRequestParams.RemoteAddress));
PINCodeRequestParams.PINCodeLength = strlen(Bluetooth_DeviceConfiguration.PINCode);
memcpy(PINCodeRequestParams.PINCode, Bluetooth_DeviceConfiguration.PINCode, sizeof(PINCodeRequestParams.PINCode));
/* Send the command to transmit the device's local PIN number for authentication */
Bluetooth_SendHCICommand(&HCICommandHeader, &PINCodeRequestParams, sizeof(BT_HCICommand_PinCodeResp_t));
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_LINK_CONTROL | OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY),
ParameterLength: sizeof(BT_HCICommand_LinkKeyNAKResp_t),
};
/* Copy over the temporary BT device address saved from the Link Key Request event */
BT_HCICommand_LinkKeyNAKResp_t LinkKeyNAKParams;
memcpy(LinkKeyNAKParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(LinkKeyNAKParams.RemoteAddress));
/* Send the command to transmit the link key NAK to the receiver */
Bluetooth_SendHCICommand(&HCICommandHeader, &LinkKeyNAKParams, sizeof(BT_HCICommand_LinkKeyNAKResp_t));
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
}
}
/** Sends a Bluetooth HCI control command to the attached Bluetooth device.
*
* \param[in] HCICommandHeader HCI command header to send to the attached device
* \param[in] Parameters Pointer to the source of the control parameters (if any)
* \param[in] ParameterLength Length of the parameters to send in bytes
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum.
*/
static uint8_t Bluetooth_SendHCICommand(const BT_HCICommand_Header_t* const HCICommandHeader, const void* Parameters, const uint16_t ParameterLength)
{
/* Need to reserve the amount of bytes given in the header for the complete payload */
uint8_t CommandBuffer[sizeof(BT_HCICommand_Header_t) + 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(BT_HCICommand_Header_t));
/* Zero out the parameter section of the response so that all padding bytes are known to be zero */
memset(&CommandBuffer[sizeof(BT_HCICommand_Header_t)], 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(BT_HCICommand_Header_t)], Parameters, ParameterLength);
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(CommandBuffer);
}

View file

@ -1,206 +1,206 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_HCICOMMANDS_H_
#define _BLUETOOTH_HCICOMMANDS_H_
/* Includes: */
#include <avr/io.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "BluetoothStack.h"
#include "BluetoothClassCodes.h"
/* Macros: */
#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 << 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
#define OCF_LINK_CONTROL_PERIODIC_INQUIRY 0x0003
#define OCF_LINK_CONTROL_EXIT_PERIODIC_INQUIRY 0x0004
#define OCF_LINK_CONTROL_CREATE_CONNECTION 0x0005
#define OCF_LINK_CONTROL_DISCONNECT 0x0006
#define OCF_LINK_CONTROL_CREATE_CONNECTION_CANCEL 0x0008
#define OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST 0x0009
#define OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST 0x000A
#define OCF_LINK_CONTROL_LINK_KEY_REQUEST_REPLY 0x000B
#define OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY 0x000C
#define OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY 0x000D
#define OCF_LINK_CONTROL_PIN_CODE_REQUEST_NEG_REPLY 0x000E
#define OCF_LINK_CONTROL_CHANGE_CONNECTION_PACKET_TYPE 0x000F
#define OCF_LINK_CONTROL_REMOTE_NAME_REQUEST 0x0019
#define OCF_CTRLR_BASEBAND_SET_EVENT_MASK 0x0001
#define OCF_CTRLR_BASEBAND_RESET 0x0003
#define OCF_CTRLR_BASEBAND_WRITE_PIN_TYPE 0x000A
#define OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME 0x0013
#define OCF_CTRLR_BASEBAND_READ_LOCAL_NAME 0x0014
#define OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE 0x001A
#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 OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005
#define OCF_CTRLR_INFORMATIONAL_READBDADDR 0x0009
#define EVENT_COMMAND_STATUS 0x0F
#define EVENT_COMMAND_COMPLETE 0x0E
#define EVENT_CONNECTION_COMPLETE 0x03
#define EVENT_CONNECTION_REQUEST 0x04
#define EVENT_DISCONNECTION_COMPLETE 0x05
#define EVENT_REMOTE_NAME_REQUEST_COMPLETE 0x07
#define EVENT_PIN_CODE_REQUEST 0x16
#define EVENT_LINK_KEY_REQUEST 0x17
#define ERROR_LIMITED_RESOURCES 0x0D
#define ERROR_UNACCEPTABLE_BDADDR 0x0F
/* Type Defines: */
typedef struct
{
uint16_t OpCode;
uint8_t ParameterLength;
uint8_t Parameters[];
} BT_HCICommand_Header_t;
typedef struct
{
uint8_t EventCode;
uint8_t ParameterLength;
} BT_HCIEvent_Header_t;
typedef struct
{
uint8_t Status;
uint8_t Packets;
uint16_t OpCode;
} BT_HCIEvent_CommandStatus_t;
typedef struct
{
uint8_t HCIPacketsAllowable;
uint16_t Opcode;
uint8_t ReturnParams[];
} BT_HCIEvent_CommandComplete_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t ClassOfDevice_Service;
uint16_t ClassOfDevice_MajorMinor;
uint8_t LinkType;
} BT_HCIEvent_ConnectionRequest_t;
typedef struct
{
uint8_t Status;
uint16_t ConnectionHandle;
uint8_t RemoteAddress[6];
uint8_t LinkType;
uint8_t EncryptionEnabled;
} BT_HCIEvent_ConnectionComplete_t;
typedef struct
{
uint8_t RemoteAddress[6];
} BT_HCIEvent_PinCodeReq_t;
typedef struct
{
uint8_t RemoteAddress[6];
} BT_HCIEvent_LinkKeyReq_t;
typedef struct
{
uint8_t RemoteAddress[6];
} BT_HCICommand_LinkKeyNAKResp_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t PINCodeLength;
char PINCode[16];
} BT_HCICommand_PinCodeResp_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t SlaveRole;
} BT_HCICommand_AcceptConnectionReq_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t Reason;
} BT_HCICommand_RejectConnectionReq_t;
/* Enums: */
enum BT_ScanEnable_Modes_t
{
BT_SCANMODE_NoScansEnabled = 0,
BT_SCANMODE_InquiryScanOnly = 1,
BT_SCANMODE_PageScanOnly = 2,
BT_SCANMODE_InquiryAndPageScans = 3,
};
enum BT_HCIStates_t
{
Bluetooth_ProcessEvents = 0,
Bluetooth_Init = 1,
Bluetooth_Init_Reset = 2,
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,
};
/* Function Prototypes: */
void Bluetooth_HCITask(void);
#if defined(INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C)
static uint8_t Bluetooth_SendHCICommand(const BT_HCICommand_Header_t* const HCICommandHeader, const void* Parameters,
const uint16_t ParameterLength);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_HCICOMMANDS_H_
#define _BLUETOOTH_HCICOMMANDS_H_
/* Includes: */
#include <avr/io.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "BluetoothStack.h"
#include "BluetoothClassCodes.h"
/* Macros: */
#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 << 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
#define OCF_LINK_CONTROL_PERIODIC_INQUIRY 0x0003
#define OCF_LINK_CONTROL_EXIT_PERIODIC_INQUIRY 0x0004
#define OCF_LINK_CONTROL_CREATE_CONNECTION 0x0005
#define OCF_LINK_CONTROL_DISCONNECT 0x0006
#define OCF_LINK_CONTROL_CREATE_CONNECTION_CANCEL 0x0008
#define OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST 0x0009
#define OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST 0x000A
#define OCF_LINK_CONTROL_LINK_KEY_REQUEST_REPLY 0x000B
#define OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY 0x000C
#define OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY 0x000D
#define OCF_LINK_CONTROL_PIN_CODE_REQUEST_NEG_REPLY 0x000E
#define OCF_LINK_CONTROL_CHANGE_CONNECTION_PACKET_TYPE 0x000F
#define OCF_LINK_CONTROL_REMOTE_NAME_REQUEST 0x0019
#define OCF_CTRLR_BASEBAND_SET_EVENT_MASK 0x0001
#define OCF_CTRLR_BASEBAND_RESET 0x0003
#define OCF_CTRLR_BASEBAND_WRITE_PIN_TYPE 0x000A
#define OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME 0x0013
#define OCF_CTRLR_BASEBAND_READ_LOCAL_NAME 0x0014
#define OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE 0x001A
#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 OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005
#define OCF_CTRLR_INFORMATIONAL_READBDADDR 0x0009
#define EVENT_COMMAND_STATUS 0x0F
#define EVENT_COMMAND_COMPLETE 0x0E
#define EVENT_CONNECTION_COMPLETE 0x03
#define EVENT_CONNECTION_REQUEST 0x04
#define EVENT_DISCONNECTION_COMPLETE 0x05
#define EVENT_REMOTE_NAME_REQUEST_COMPLETE 0x07
#define EVENT_PIN_CODE_REQUEST 0x16
#define EVENT_LINK_KEY_REQUEST 0x17
#define ERROR_LIMITED_RESOURCES 0x0D
#define ERROR_UNACCEPTABLE_BDADDR 0x0F
/* Type Defines: */
typedef struct
{
uint16_t OpCode;
uint8_t ParameterLength;
uint8_t Parameters[];
} BT_HCICommand_Header_t;
typedef struct
{
uint8_t EventCode;
uint8_t ParameterLength;
} BT_HCIEvent_Header_t;
typedef struct
{
uint8_t Status;
uint8_t Packets;
uint16_t OpCode;
} BT_HCIEvent_CommandStatus_t;
typedef struct
{
uint8_t HCIPacketsAllowable;
uint16_t Opcode;
uint8_t ReturnParams[];
} BT_HCIEvent_CommandComplete_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t ClassOfDevice_Service;
uint16_t ClassOfDevice_MajorMinor;
uint8_t LinkType;
} BT_HCIEvent_ConnectionRequest_t;
typedef struct
{
uint8_t Status;
uint16_t ConnectionHandle;
uint8_t RemoteAddress[6];
uint8_t LinkType;
uint8_t EncryptionEnabled;
} BT_HCIEvent_ConnectionComplete_t;
typedef struct
{
uint8_t RemoteAddress[6];
} BT_HCIEvent_PinCodeReq_t;
typedef struct
{
uint8_t RemoteAddress[6];
} BT_HCIEvent_LinkKeyReq_t;
typedef struct
{
uint8_t RemoteAddress[6];
} BT_HCICommand_LinkKeyNAKResp_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t PINCodeLength;
char PINCode[16];
} BT_HCICommand_PinCodeResp_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t SlaveRole;
} BT_HCICommand_AcceptConnectionReq_t;
typedef struct
{
uint8_t RemoteAddress[6];
uint8_t Reason;
} BT_HCICommand_RejectConnectionReq_t;
/* Enums: */
enum BT_ScanEnable_Modes_t
{
BT_SCANMODE_NoScansEnabled = 0,
BT_SCANMODE_InquiryScanOnly = 1,
BT_SCANMODE_PageScanOnly = 2,
BT_SCANMODE_InquiryAndPageScans = 3,
};
enum BT_HCIStates_t
{
Bluetooth_ProcessEvents = 0,
Bluetooth_Init = 1,
Bluetooth_Init_Reset = 2,
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,
};
/* Function Prototypes: */
void Bluetooth_HCITask(void);
#if defined(INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C)
static uint8_t Bluetooth_SendHCICommand(const BT_HCICommand_Header_t* const HCICommandHeader, const void* Parameters,
const uint16_t ParameterLength);
#endif
#endif

View file

@ -1,99 +1,99 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#include "BluetoothStack.h"
/** 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 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 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_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
* to remote Bluetooth devices, including both the HCI control layer and the ACL channel layer.
*/
void Bluetooth_Stack_USBTask(void)
{
Bluetooth_HCITask();
Bluetooth_ACLTask();
}
/** Retrieves the channel information structure with the given local or remote channel number from the channel list.
*
* \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 SearchValue, const uint8_t SearchKey)
{
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
{
Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
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 (FoundMatch)
return ChannelData;
}
return NULL;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#include "BluetoothStack.h"
/** 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 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 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_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
* to remote Bluetooth devices, including both the HCI control layer and the ACL channel layer.
*/
void Bluetooth_Stack_USBTask(void)
{
Bluetooth_HCITask();
Bluetooth_ACLTask();
}
/** Retrieves the channel information structure with the given local or remote channel number from the channel list.
*
* \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 SearchValue, const uint8_t SearchKey)
{
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
{
Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
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 (FoundMatch)
return ChannelData;
}
return NULL;
}

View file

@ -1,161 +1,161 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_STACK_
#define _BLUETOOTH_STACK_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
/* Macros: */
#define BLUETOOTH_DATA_IN_PIPE 1
#define BLUETOOTH_DATA_OUT_PIPE 2
#define BLUETOOTH_EVENTS_PIPE 3
#define BLUETOOTH_MAX_OPEN_CHANNELS 6
#define CHANNEL_PSM_SDP 0x0001
#define CHANNEL_PSM_UDP 0x0002
#define CHANNEL_PSM_RFCOMM 0x0003
#define CHANNEL_PSM_TCP 0x0004
#define CHANNEL_PSM_IP 0x0009
#define CHANNEL_PSM_FTP 0x000A
#define CHANNEL_PSM_HTTP 0x000C
#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: */
/** Enum for the possible states for a bluetooth ACL channel. */
enum BT_ChannelStates_t
{
Channel_Closed = 0, /**< Channel is closed and inactive. No data may be sent or received. */
Channel_WaitConnect = 1, /**< A connection request has been received, but a response has not been sent. */
Channel_WaitConnectRsp = 2, /**< A connection request has been sent, but a response has not been received. */
Channel_Config_WaitConfig = 3, /**< Channel has been connected, but not yet configured on either end. */
Channel_Config_WaitSendConfig = 4, /**< Channel configuration has been received and accepted, but not yet sent. */
Channel_Config_WaitReqResp = 5, /**< Channel configuration has been sent but not responded to, and a configuration
request from the remote end has not yet been received. */
Channel_Config_WaitResp = 6, /**< Channel configuration has been sent but not accepted, but a configuration request
from the remote end has been accepted. */
Channel_Config_WaitReq = 7, /**< Channel configuration has been sent and accepted, but a configuration request
from the remote end has not yet been accepted. */
Channel_Open = 8, /**< Channel is open and ready to send or receive data */
Channel_WaitDisconnect = 9, /**< A disconnection request has been sent, but not yet acknowledged. */
};
/** Enum for the possible error codes returned by the \ref Bluetooth_SendPacket() function. */
enum BT_SendPacket_ErrorCodes_t
{
BT_SENDPACKET_NoError = 0, /**< The packet was sent sucessfully. */
BT_SENDPACKET_NotConnected = 1, /**< The bluetooth stack is not currently connected to a remote device. */
BT_SENDPACKET_ChannelNotOpen = 2, /**< The given channel is not currently in the Open state. */
};
/* Type Defines: */
/** Type define for a Bluetooth ACL channel information structure. This structure contains all the relevent
* information on an ACL channel for data transmission and reception by the stack.
*/
typedef struct
{
uint8_t State;
uint16_t LocalNumber;
uint16_t RemoteNumber;
uint16_t PSM;
uint16_t LocalMTU;
uint16_t RemoteMTU;
} Bluetooth_Channel_t;
/** Type define for a Bluetooth device connection information structure. This structure contains all the
* information needed to maintain a connection to a remote Bluetooth device via the Bluetooth stack.
*/
typedef struct
{
bool IsConnected; /**< Indicates if the stack is currently connected to a remote device - if this value is
* false, the remaining elements are invalid.
*/
uint16_t ConnectionHandle; /**< Connection handle to the remote device, used internally in the stack. */
uint8_t RemoteAddress[6]; /**< Bluetooth device address of the attached remote device. */
Bluetooth_Channel_t Channels[BLUETOOTH_MAX_OPEN_CHANNELS]; /**< Channel information structures for the connection. */
uint8_t SignallingIdentifier; /**< Next Signalling Channel unique command sequence identifier. */
} Bluetooth_Connection_t;
/** Local Bluetooth device information structure, for the defining of local device characteristics for the Bluetooth stack. */
typedef struct
{
uint32_t Class; /**< Class of the local device, a mask of DEVICE_CLASS_* masks. */
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;
/** Bluetooth stack state information structure, for the containment of the Bluetooth stack state. The values in
* this structure are set by the Bluetooth stack internally, and should all be treated as read only by the user
* application.
*/
typedef struct
{
uint8_t CurrentHCIState; /**< Current HCI state machine state. */
uint8_t NextHCIState; /**< Next HCI state machine state to progress to once the currently issued command completes. */
bool IsInitialized; /**< Indicates if the Bluetooth stack is currently initialized and ready for connections
* to or from a remote Bluetooth device.
*/
uint8_t LocalBDADDR[6]; /**< Local bluetooth adapter's BDADDR, valid when the stack is fully initialized. */
} Bluetooth_Stack_State_t;
/* Includes: */
#include "BluetoothHCICommands.h"
#include "BluetoothACLPackets.h"
/* Function Prototypes: */
void Bluetooth_Stack_Init(void);
void Bluetooth_Stack_USBTask(void);
void Bluetooth_StackInitialized(void);
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress);
void Bluetooth_ConnectionComplete(void);
void Bluetooth_DisconnectionComplete(void);
bool Bluetooth_ChannelConnectionRequest(const uint16_t PSM);
void Bluetooth_PacketReceived(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);
Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t SearchValue, const uint8_t SearchKey);
Bluetooth_Channel_t* Bluetooth_OpenChannel(const uint16_t PSM);
void Bluetooth_CloseChannel(Bluetooth_Channel_t* const Channel);
uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);
/* External Variables: */
extern Bluetooth_Device_t Bluetooth_DeviceConfiguration;
extern Bluetooth_Connection_t Bluetooth_Connection;
extern Bluetooth_Stack_State_t Bluetooth_State;
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _BLUETOOTH_STACK_
#define _BLUETOOTH_STACK_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
/* Macros: */
#define BLUETOOTH_DATA_IN_PIPE 1
#define BLUETOOTH_DATA_OUT_PIPE 2
#define BLUETOOTH_EVENTS_PIPE 3
#define BLUETOOTH_MAX_OPEN_CHANNELS 6
#define CHANNEL_PSM_SDP 0x0001
#define CHANNEL_PSM_UDP 0x0002
#define CHANNEL_PSM_RFCOMM 0x0003
#define CHANNEL_PSM_TCP 0x0004
#define CHANNEL_PSM_IP 0x0009
#define CHANNEL_PSM_FTP 0x000A
#define CHANNEL_PSM_HTTP 0x000C
#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: */
/** Enum for the possible states for a bluetooth ACL channel. */
enum BT_ChannelStates_t
{
Channel_Closed = 0, /**< Channel is closed and inactive. No data may be sent or received. */
Channel_WaitConnect = 1, /**< A connection request has been received, but a response has not been sent. */
Channel_WaitConnectRsp = 2, /**< A connection request has been sent, but a response has not been received. */
Channel_Config_WaitConfig = 3, /**< Channel has been connected, but not yet configured on either end. */
Channel_Config_WaitSendConfig = 4, /**< Channel configuration has been received and accepted, but not yet sent. */
Channel_Config_WaitReqResp = 5, /**< Channel configuration has been sent but not responded to, and a configuration
request from the remote end has not yet been received. */
Channel_Config_WaitResp = 6, /**< Channel configuration has been sent but not accepted, but a configuration request
from the remote end has been accepted. */
Channel_Config_WaitReq = 7, /**< Channel configuration has been sent and accepted, but a configuration request
from the remote end has not yet been accepted. */
Channel_Open = 8, /**< Channel is open and ready to send or receive data */
Channel_WaitDisconnect = 9, /**< A disconnection request has been sent, but not yet acknowledged. */
};
/** Enum for the possible error codes returned by the \ref Bluetooth_SendPacket() function. */
enum BT_SendPacket_ErrorCodes_t
{
BT_SENDPACKET_NoError = 0, /**< The packet was sent sucessfully. */
BT_SENDPACKET_NotConnected = 1, /**< The bluetooth stack is not currently connected to a remote device. */
BT_SENDPACKET_ChannelNotOpen = 2, /**< The given channel is not currently in the Open state. */
};
/* Type Defines: */
/** Type define for a Bluetooth ACL channel information structure. This structure contains all the relevent
* information on an ACL channel for data transmission and reception by the stack.
*/
typedef struct
{
uint8_t State;
uint16_t LocalNumber;
uint16_t RemoteNumber;
uint16_t PSM;
uint16_t LocalMTU;
uint16_t RemoteMTU;
} Bluetooth_Channel_t;
/** Type define for a Bluetooth device connection information structure. This structure contains all the
* information needed to maintain a connection to a remote Bluetooth device via the Bluetooth stack.
*/
typedef struct
{
bool IsConnected; /**< Indicates if the stack is currently connected to a remote device - if this value is
* false, the remaining elements are invalid.
*/
uint16_t ConnectionHandle; /**< Connection handle to the remote device, used internally in the stack. */
uint8_t RemoteAddress[6]; /**< Bluetooth device address of the attached remote device. */
Bluetooth_Channel_t Channels[BLUETOOTH_MAX_OPEN_CHANNELS]; /**< Channel information structures for the connection. */
uint8_t SignallingIdentifier; /**< Next Signalling Channel unique command sequence identifier. */
} Bluetooth_Connection_t;
/** Local Bluetooth device information structure, for the defining of local device characteristics for the Bluetooth stack. */
typedef struct
{
uint32_t Class; /**< Class of the local device, a mask of DEVICE_CLASS_* masks. */
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;
/** Bluetooth stack state information structure, for the containment of the Bluetooth stack state. The values in
* this structure are set by the Bluetooth stack internally, and should all be treated as read only by the user
* application.
*/
typedef struct
{
uint8_t CurrentHCIState; /**< Current HCI state machine state. */
uint8_t NextHCIState; /**< Next HCI state machine state to progress to once the currently issued command completes. */
bool IsInitialized; /**< Indicates if the Bluetooth stack is currently initialized and ready for connections
* to or from a remote Bluetooth device.
*/
uint8_t LocalBDADDR[6]; /**< Local bluetooth adapter's BDADDR, valid when the stack is fully initialized. */
} Bluetooth_Stack_State_t;
/* Includes: */
#include "BluetoothHCICommands.h"
#include "BluetoothACLPackets.h"
/* Function Prototypes: */
void Bluetooth_Stack_Init(void);
void Bluetooth_Stack_USBTask(void);
void Bluetooth_StackInitialized(void);
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress);
void Bluetooth_ConnectionComplete(void);
void Bluetooth_DisconnectionComplete(void);
bool Bluetooth_ChannelConnectionRequest(const uint16_t PSM);
void Bluetooth_PacketReceived(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);
Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t SearchValue, const uint8_t SearchKey);
Bluetooth_Channel_t* Bluetooth_OpenChannel(const uint16_t PSM);
void Bluetooth_CloseChannel(Bluetooth_Channel_t* const Channel);
uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);
/* External Variables: */
extern Bluetooth_Device_t Bluetooth_DeviceConfiguration;
extern Bluetooth_Connection_t Bluetooth_Connection;
extern Bluetooth_Stack_State_t Bluetooth_State;
#endif

View file

@ -1,195 +1,195 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#define INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C
#include "ServiceDiscoveryProtocol.h"
SERVICE_ATTRIBUTE_TEXT(SDP_Attribute_Name, "SDP");
SERVICE_ATTRIBUTE_TEXT(SDP_Attribute_Description, "BT Service Discovery");
SERVICE_ATTRIBUTE_8BIT_LEN(SDP_Attribute_Availability, SDP_DATATYPE_UNSIGNED_INT, 1, {0xFF});
const ServiceAttributeTable_t SDP_Attribute_Table[] PROGMEM =
{
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &SDP_Attribute_Name},
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &SDP_Attribute_Description},
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &SDP_Attribute_Availability},
SERVICE_ATTRIBUTE_TABLE_TERMINATOR
};
SERVICE_ATTRIBUTE_TEXT(RFCOMM_Attribute_Name, "RFCOMM");
SERVICE_ATTRIBUTE_TEXT(RFCOMM_Attribute_Description, "Virtual Serial");
SERVICE_ATTRIBUTE_8BIT_LEN(RFCOMM_Attribute_Availability, SDP_DATATYPE_UNSIGNED_INT, 1, {0xFF});
const ServiceAttributeTable_t RFCOMM_Attribute_Table[] PROGMEM =
{
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &RFCOMM_Attribute_Name},
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &RFCOMM_Attribute_Description},
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &RFCOMM_Attribute_Availability},
SERVICE_ATTRIBUTE_TABLE_TERMINATOR
};
const ServiceTable_t SDP_Services_Table[] =
{
{ // 128-bit UUID for the SDP service
.UUID = {BASE_96BIT_UUID, 0x01, 0x00, 0x00, 0x00},
.AttributeTable = &SDP_Attribute_Table,
},
{ // 128-bit UUID for the RFCOMM service
.UUID = {BASE_96BIT_UUID, 0x03, 0x00, 0x00, 0x00},
.AttributeTable = &RFCOMM_Attribute_Table,
},
};
void ServiceDiscovery_ProcessPacket(void* Data, Bluetooth_Channel_t* Channel)
{
SDP_PDUHeader_t* SDPHeader = (SDP_PDUHeader_t*)Data;
SDPHeader->ParameterLength = SwapEndian_16(SDPHeader->ParameterLength);
BT_SDP_DEBUG(1, "SDP Packet Received");
BT_SDP_DEBUG(2, "-- PDU ID: 0x%02X", SDPHeader->PDU);
BT_SDP_DEBUG(2, "-- Param Length: 0x%04X", SDPHeader->ParameterLength);
switch (SDPHeader->PDU)
{
case SDP_PDU_SERVICESEARCHREQUEST:
ServiceDiscovery_ProcessServiceSearch(SDPHeader);
break;
case SDP_PDU_SERVICEATTRIBUTEREQUEST:
ServiceDiscovery_ProcessServiceAttribute(SDPHeader);
break;
case SDP_PDU_SERVICESEARCHATTRIBUTEREQUEST:
ServiceDiscovery_ProcessServiceSearchAttribute(SDPHeader);
break;
}
}
static void ServiceDiscovery_ProcessServiceSearch(SDP_PDUHeader_t* SDPHeader)
{
BT_SDP_DEBUG(1, "<< Service Search");
}
static void ServiceDiscovery_ProcessServiceAttribute(SDP_PDUHeader_t* SDPHeader)
{
BT_SDP_DEBUG(1, "<< Service Attribute");
}
static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPHeader)
{
void* CurrentParameter = ((void*)SDPHeader + sizeof(SDP_PDUHeader_t));
BT_SDP_DEBUG(1, "<< Service Search Attribute");
uint8_t ElementHeaderSize;
uint16_t ServicePatternLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
BT_SDP_DEBUG(2, "-- Total UUID Length: 0x%04X", ServicePatternLength);
while (ServicePatternLength)
{
uint8_t UUIDLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
uint8_t UUID[16] = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x00};
if (UUIDLength <= 32)
memcpy(&UUID[sizeof(UUID) - sizeof(uint32_t)], CurrentParameter, UUIDLength);
else
memcpy(UUID, CurrentParameter, UUIDLength);
CurrentParameter += UUIDLength;
BT_SDP_DEBUG(2, "-- UUID (%d): 0x%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
UUIDLength,
UUID[15], UUID[14], UUID[13], UUID[12], UUID[11], UUID[10], UUID[9], UUID[8],
UUID[7], UUID[6], UUID[5], UUID[4], UUID[3], UUID[2], UUID[1], UUID[0]);
ServicePatternLength -= (UUIDLength + ElementHeaderSize);
}
uint16_t MaxAttributeSize = ServiceDiscovery_Read16BitParameter(&CurrentParameter);
BT_SDP_DEBUG(2, "-- Max Return Attribute Bytes: 0x%04X", MaxAttributeSize);
uint16_t AttributeIDListLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
BT_SDP_DEBUG(2, "-- Total Attribute Length: 0x%04X", AttributeIDListLength);
while (AttributeIDListLength)
{
uint8_t AttributeLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
uint32_t Attribute = 0;
memcpy(&Attribute, CurrentParameter, AttributeLength);
CurrentParameter += AttributeLength;
BT_SDP_DEBUG(2, "-- Attribute(%d): 0x%08lX", AttributeLength, Attribute);
AttributeIDListLength -= (AttributeLength + ElementHeaderSize);
}
}
static uint32_t ServiceDiscovery_GetDataElementSize(void** DataElementHeader, uint8_t* ElementHeaderSize)
{
uint8_t SizeIndex = (*((uint8_t*)*DataElementHeader) & 0x07);
*DataElementHeader += sizeof(uint8_t);
*ElementHeaderSize = 1;
uint32_t ElementValue;
switch (SizeIndex)
{
case 0:
ElementValue = 1;
break;
case 1:
ElementValue = 2;
break;
case 2:
ElementValue = 4;
break;
case 3:
ElementValue = 8;
break;
case 4:
ElementValue = 16;
break;
case 5:
ElementValue = *((uint8_t*)*DataElementHeader);
*DataElementHeader += sizeof(uint8_t);
*ElementHeaderSize = (1 + sizeof(uint8_t));
break;
case 6:
ElementValue = *((uint16_t*)*DataElementHeader);
*DataElementHeader += sizeof(uint16_t);
*ElementHeaderSize = (1 + sizeof(uint16_t));
break;
default:
ElementValue = *((uint32_t*)*DataElementHeader);
*DataElementHeader += sizeof(uint32_t);
*ElementHeaderSize = (1 + sizeof(uint32_t));
break;
}
return ElementValue;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#define INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C
#include "ServiceDiscoveryProtocol.h"
SERVICE_ATTRIBUTE_TEXT(SDP_Attribute_Name, "SDP");
SERVICE_ATTRIBUTE_TEXT(SDP_Attribute_Description, "BT Service Discovery");
SERVICE_ATTRIBUTE_8BIT_LEN(SDP_Attribute_Availability, SDP_DATATYPE_UNSIGNED_INT, 1, {0xFF});
const ServiceAttributeTable_t SDP_Attribute_Table[] PROGMEM =
{
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &SDP_Attribute_Name},
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &SDP_Attribute_Description},
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &SDP_Attribute_Availability},
SERVICE_ATTRIBUTE_TABLE_TERMINATOR
};
SERVICE_ATTRIBUTE_TEXT(RFCOMM_Attribute_Name, "RFCOMM");
SERVICE_ATTRIBUTE_TEXT(RFCOMM_Attribute_Description, "Virtual Serial");
SERVICE_ATTRIBUTE_8BIT_LEN(RFCOMM_Attribute_Availability, SDP_DATATYPE_UNSIGNED_INT, 1, {0xFF});
const ServiceAttributeTable_t RFCOMM_Attribute_Table[] PROGMEM =
{
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &RFCOMM_Attribute_Name},
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &RFCOMM_Attribute_Description},
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &RFCOMM_Attribute_Availability},
SERVICE_ATTRIBUTE_TABLE_TERMINATOR
};
const ServiceTable_t SDP_Services_Table[] =
{
{ // 128-bit UUID for the SDP service
.UUID = {BASE_96BIT_UUID, 0x01, 0x00, 0x00, 0x00},
.AttributeTable = &SDP_Attribute_Table,
},
{ // 128-bit UUID for the RFCOMM service
.UUID = {BASE_96BIT_UUID, 0x03, 0x00, 0x00, 0x00},
.AttributeTable = &RFCOMM_Attribute_Table,
},
};
void ServiceDiscovery_ProcessPacket(void* Data, Bluetooth_Channel_t* Channel)
{
SDP_PDUHeader_t* SDPHeader = (SDP_PDUHeader_t*)Data;
SDPHeader->ParameterLength = SwapEndian_16(SDPHeader->ParameterLength);
BT_SDP_DEBUG(1, "SDP Packet Received");
BT_SDP_DEBUG(2, "-- PDU ID: 0x%02X", SDPHeader->PDU);
BT_SDP_DEBUG(2, "-- Param Length: 0x%04X", SDPHeader->ParameterLength);
switch (SDPHeader->PDU)
{
case SDP_PDU_SERVICESEARCHREQUEST:
ServiceDiscovery_ProcessServiceSearch(SDPHeader);
break;
case SDP_PDU_SERVICEATTRIBUTEREQUEST:
ServiceDiscovery_ProcessServiceAttribute(SDPHeader);
break;
case SDP_PDU_SERVICESEARCHATTRIBUTEREQUEST:
ServiceDiscovery_ProcessServiceSearchAttribute(SDPHeader);
break;
}
}
static void ServiceDiscovery_ProcessServiceSearch(SDP_PDUHeader_t* SDPHeader)
{
BT_SDP_DEBUG(1, "<< Service Search");
}
static void ServiceDiscovery_ProcessServiceAttribute(SDP_PDUHeader_t* SDPHeader)
{
BT_SDP_DEBUG(1, "<< Service Attribute");
}
static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPHeader)
{
void* CurrentParameter = ((void*)SDPHeader + sizeof(SDP_PDUHeader_t));
BT_SDP_DEBUG(1, "<< Service Search Attribute");
uint8_t ElementHeaderSize;
uint16_t ServicePatternLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
BT_SDP_DEBUG(2, "-- Total UUID Length: 0x%04X", ServicePatternLength);
while (ServicePatternLength)
{
uint8_t UUIDLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
uint8_t UUID[16] = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x00};
if (UUIDLength <= 32)
memcpy(&UUID[sizeof(UUID) - sizeof(uint32_t)], CurrentParameter, UUIDLength);
else
memcpy(UUID, CurrentParameter, UUIDLength);
CurrentParameter += UUIDLength;
BT_SDP_DEBUG(2, "-- UUID (%d): 0x%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
UUIDLength,
UUID[15], UUID[14], UUID[13], UUID[12], UUID[11], UUID[10], UUID[9], UUID[8],
UUID[7], UUID[6], UUID[5], UUID[4], UUID[3], UUID[2], UUID[1], UUID[0]);
ServicePatternLength -= (UUIDLength + ElementHeaderSize);
}
uint16_t MaxAttributeSize = ServiceDiscovery_Read16BitParameter(&CurrentParameter);
BT_SDP_DEBUG(2, "-- Max Return Attribute Bytes: 0x%04X", MaxAttributeSize);
uint16_t AttributeIDListLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
BT_SDP_DEBUG(2, "-- Total Attribute Length: 0x%04X", AttributeIDListLength);
while (AttributeIDListLength)
{
uint8_t AttributeLength = ServiceDiscovery_GetDataElementSize(&CurrentParameter, &ElementHeaderSize);
uint32_t Attribute = 0;
memcpy(&Attribute, CurrentParameter, AttributeLength);
CurrentParameter += AttributeLength;
BT_SDP_DEBUG(2, "-- Attribute(%d): 0x%08lX", AttributeLength, Attribute);
AttributeIDListLength -= (AttributeLength + ElementHeaderSize);
}
}
static uint32_t ServiceDiscovery_GetDataElementSize(void** DataElementHeader, uint8_t* ElementHeaderSize)
{
uint8_t SizeIndex = (*((uint8_t*)*DataElementHeader) & 0x07);
*DataElementHeader += sizeof(uint8_t);
*ElementHeaderSize = 1;
uint32_t ElementValue;
switch (SizeIndex)
{
case 0:
ElementValue = 1;
break;
case 1:
ElementValue = 2;
break;
case 2:
ElementValue = 4;
break;
case 3:
ElementValue = 8;
break;
case 4:
ElementValue = 16;
break;
case 5:
ElementValue = *((uint8_t*)*DataElementHeader);
*DataElementHeader += sizeof(uint8_t);
*ElementHeaderSize = (1 + sizeof(uint8_t));
break;
case 6:
ElementValue = *((uint16_t*)*DataElementHeader);
*DataElementHeader += sizeof(uint16_t);
*ElementHeaderSize = (1 + sizeof(uint16_t));
break;
default:
ElementValue = *((uint32_t*)*DataElementHeader);
*DataElementHeader += sizeof(uint32_t);
*ElementHeaderSize = (1 + sizeof(uint32_t));
break;
}
return ElementValue;
}

View file

@ -1,148 +1,148 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _SERVICEDISCOVERYPROTOCOL_H_
#define _SERVICEDISCOVERYPROTOCOL_H_
/* Includes: */
#include <avr/io.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <LUFA/Common/Common.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "BluetoothStack.h"
/* Macros: */
#define BT_SDP_DEBUG(l, s, ...) do { if (SDP_DEBUG_LEVEL >= l) printf_P(PSTR("(SDP) " s "\r\n"), ##__VA_ARGS__); } while (0)
#define SDP_DEBUG_LEVEL 2
#define SDP_PDU_ERRORRESPONSE 0x01
#define SDP_PDU_SERVICESEARCHREQUEST 0x02
#define SDP_PDU_SERVICESEARCHRESPONSE 0x03
#define SDP_PDU_SERVICEATTRIBUTEREQUEST 0x04
#define SDP_PDU_SERVICEATTRIBUTERESPONSE 0x05
#define SDP_PDU_SERVICESEARCHATTRIBUTEREQUEST 0x06
#define SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE 0x07
#define SDP_ATTRIBUTE_NAME 0x0000
#define SDP_ATTRIBUTE_DESCRIPTION 0x0001
#define SDP_ATTRIBUTE_PROVIDER 0x0002
#define SDP_ATTRIBUTE_AVAILABILITY 0x0008
#define SDP_DATATYPE_NIL (0x00 << 3)
#define SDP_DATATYPE_UNSIGNED_INT (0x01 << 3)
#define SDP_DATATYPE_SIGNED_INT (0x02 << 3)
#define SDP_DATATYPE_UUID (0x03 << 3)
#define SDP_DATATYPE_TEXT (0x04 << 3)
#define SDP_DATATYPE_BOOLEAN (0x05 << 3)
#define SDP_DATATYPE_ELEMENT_SEQUENCE (0x06 << 3)
#define SDP_DATATYPE_ELEMENT_ALTERNATIVE (0x07 << 3)
#define SDP_DATATYPE_URL (0x08 << 3)
#define BASE_96BIT_UUID 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00
#define SERVICE_ATTRIBUTE_TEXT(name, string) SERVICE_ATTRIBUTE_8BIT_LEN(name, SDP_DATATYPE_TEXT, sizeof(string), string)
#define SERVICE_ATTRIBUTE_8BIT_LEN(name, type, size, ...) const ServiceAttributeData8Bit_t name PROGMEM = \
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_16BIT_LEN(name, type, size, ...) const ServiceAttributeData16Bit_t name PROGMEM = \
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_32BIT_LEN(name, type, size, ...) const ServiceAttributeData32Bit_t name PROGMEM = \
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_TABLE_TERMINATOR {.AttributeData = NULL}
/* Type Defines: */
typedef struct
{
uint8_t PDU;
uint16_t TransactionID;
uint16_t ParameterLength;
} SDP_PDUHeader_t;
typedef struct
{
uint16_t AttributeID;
const void* AttributeData;
} ServiceAttributeTable_t;
typedef struct
{
uint8_t UUID[16];
const void* AttributeTable;
} ServiceTable_t;
typedef struct
{
uint8_t Header;
uint32_t Size;
uint8_t Data[];
} ServiceAttributeData32Bit_t;
typedef struct
{
uint8_t Header;
uint16_t Size;
uint8_t Data[];
} ServiceAttributeData16Bit_t;
typedef struct
{
uint8_t Header;
uint8_t Size;
uint8_t Data[];
} ServiceAttributeData8Bit_t;
typedef struct
{
uint8_t Header;
uint8_t Data[];
} ServiceAttributeData_t;
/* Function Prototypes: */
void ServiceDiscovery_ProcessPacket(void* Data, Bluetooth_Channel_t* Channel);
#if defined(INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C)
static void ServiceDiscovery_ProcessServiceSearch(SDP_PDUHeader_t* SDPHeader);
static void ServiceDiscovery_ProcessServiceAttribute(SDP_PDUHeader_t* SDPHeader);
static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPHeader);
static inline uint16_t ServiceDiscovery_Read16BitParameter(void** AttributeHeader)
{
uint16_t ParamValue = *((uint16_t*)*AttributeHeader);
*AttributeHeader += sizeof(uint16_t);
return ParamValue;
}
static uint32_t ServiceDiscovery_GetDataElementSize(void** AttributeHeader, uint8_t* ElementHeaderSize);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _SERVICEDISCOVERYPROTOCOL_H_
#define _SERVICEDISCOVERYPROTOCOL_H_
/* Includes: */
#include <avr/io.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <LUFA/Common/Common.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "BluetoothStack.h"
/* Macros: */
#define BT_SDP_DEBUG(l, s, ...) do { if (SDP_DEBUG_LEVEL >= l) printf_P(PSTR("(SDP) " s "\r\n"), ##__VA_ARGS__); } while (0)
#define SDP_DEBUG_LEVEL 2
#define SDP_PDU_ERRORRESPONSE 0x01
#define SDP_PDU_SERVICESEARCHREQUEST 0x02
#define SDP_PDU_SERVICESEARCHRESPONSE 0x03
#define SDP_PDU_SERVICEATTRIBUTEREQUEST 0x04
#define SDP_PDU_SERVICEATTRIBUTERESPONSE 0x05
#define SDP_PDU_SERVICESEARCHATTRIBUTEREQUEST 0x06
#define SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE 0x07
#define SDP_ATTRIBUTE_NAME 0x0000
#define SDP_ATTRIBUTE_DESCRIPTION 0x0001
#define SDP_ATTRIBUTE_PROVIDER 0x0002
#define SDP_ATTRIBUTE_AVAILABILITY 0x0008
#define SDP_DATATYPE_NIL (0x00 << 3)
#define SDP_DATATYPE_UNSIGNED_INT (0x01 << 3)
#define SDP_DATATYPE_SIGNED_INT (0x02 << 3)
#define SDP_DATATYPE_UUID (0x03 << 3)
#define SDP_DATATYPE_TEXT (0x04 << 3)
#define SDP_DATATYPE_BOOLEAN (0x05 << 3)
#define SDP_DATATYPE_ELEMENT_SEQUENCE (0x06 << 3)
#define SDP_DATATYPE_ELEMENT_ALTERNATIVE (0x07 << 3)
#define SDP_DATATYPE_URL (0x08 << 3)
#define BASE_96BIT_UUID 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00
#define SERVICE_ATTRIBUTE_TEXT(name, string) SERVICE_ATTRIBUTE_8BIT_LEN(name, SDP_DATATYPE_TEXT, sizeof(string), string)
#define SERVICE_ATTRIBUTE_8BIT_LEN(name, type, size, ...) const ServiceAttributeData8Bit_t name PROGMEM = \
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_16BIT_LEN(name, type, size, ...) const ServiceAttributeData16Bit_t name PROGMEM = \
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_32BIT_LEN(name, type, size, ...) const ServiceAttributeData32Bit_t name PROGMEM = \
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_TABLE_TERMINATOR {.AttributeData = NULL}
/* Type Defines: */
typedef struct
{
uint8_t PDU;
uint16_t TransactionID;
uint16_t ParameterLength;
} SDP_PDUHeader_t;
typedef struct
{
uint16_t AttributeID;
const void* AttributeData;
} ServiceAttributeTable_t;
typedef struct
{
uint8_t UUID[16];
const void* AttributeTable;
} ServiceTable_t;
typedef struct
{
uint8_t Header;
uint32_t Size;
uint8_t Data[];
} ServiceAttributeData32Bit_t;
typedef struct
{
uint8_t Header;
uint16_t Size;
uint8_t Data[];
} ServiceAttributeData16Bit_t;
typedef struct
{
uint8_t Header;
uint8_t Size;
uint8_t Data[];
} ServiceAttributeData8Bit_t;
typedef struct
{
uint8_t Header;
uint8_t Data[];
} ServiceAttributeData_t;
/* Function Prototypes: */
void ServiceDiscovery_ProcessPacket(void* Data, Bluetooth_Channel_t* Channel);
#if defined(INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C)
static void ServiceDiscovery_ProcessServiceSearch(SDP_PDUHeader_t* SDPHeader);
static void ServiceDiscovery_ProcessServiceAttribute(SDP_PDUHeader_t* SDPHeader);
static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPHeader);
static inline uint16_t ServiceDiscovery_Read16BitParameter(void** AttributeHeader)
{
uint16_t ParamValue = *((uint16_t*)*AttributeHeader);
*AttributeHeader += sizeof(uint16_t);
return ParamValue;
}
static uint32_t ServiceDiscovery_GetDataElementSize(void** AttributeHeader, uint8_t* ElementHeaderSize);
#endif
#endif

File diff suppressed because it is too large Load diff