From 28f1ac81176bbcd9fd13d94e61323522a5279d27 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Sat, 10 Apr 2010 07:33:19 +0000
Subject: [PATCH] Add LUFA-side channel open/close routines, add signalling
 handlers for the creation and configuration of channels from the local device
 to the remote device, to add to the existing remote to local channel
 capabilities.

---
 .../BluetoothHost/Lib/BluetoothACLPackets.c   | 150 +++++++++++++++++-
 .../BluetoothHost/Lib/BluetoothACLPackets.h   |   8 +-
 .../BluetoothHost/Lib/BluetoothStack.c        |  28 ----
 .../BluetoothHost/Lib/BluetoothStack.h        |  18 +--
 4 files changed, 163 insertions(+), 41 deletions(-)

diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c
index 7c238e9a6..50fba7c5d 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.c
@@ -120,6 +120,9 @@ static void Bluetooth_ProcessACLPackets(void)
 			case BT_SIGNAL_CONNECTION_REQUEST:
 				Bluetooth_Signal_ConnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
 				break;
+			case BT_SIGNAL_CONNECTION_RESPONSE:
+				Bluetooth_Signal_ConnectionResp(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
+				break;
 			case BT_SIGNAL_CONFIGURATION_REQUEST:
 				Bluetooth_Signal_ConfigurationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
 				break;
@@ -128,7 +131,10 @@ static void Bluetooth_ProcessACLPackets(void)
 				break;
 			case BT_SIGNAL_DISCONNECTION_REQUEST:
 				Bluetooth_Signal_DisconnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
-				break;			
+				break;
+			case BT_SIGNAL_DISCONNECTION_RESPONSE:
+				Bluetooth_Signal_DisconnectionResp(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
+				break;
 			case BT_SIGNAL_ECHO_REQUEST:
 				Bluetooth_Signal_EchoReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
 				break;
@@ -193,6 +199,75 @@ uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t*
 	return BT_SENDPACKET_NoError;
 }
 
+Bluetooth_Channel_t* Bluetooth_OpenChannel(uint16_t PSM)
+{
+	Bluetooth_Channel_t* ChannelData = NULL;
+
+	for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
+	{
+		if (Bluetooth_Connection.Channels[i].State == Channel_Closed)
+		{
+			ChannelData = &Bluetooth_Connection.Channels[i];				
+			ChannelData->LocalNumber = (BLUETOOTH_CHANNELNUMBER_BASEOFFSET + i);
+			break;
+		}
+	}
+
+	if (ChannelData == NULL)
+	  return NULL;
+
+	ChannelData->RemoteNumber = 0;
+	ChannelData->PSM          = PSM;
+	ChannelData->LocalMTU     = MAXIMUM_CHANNEL_MTU;
+	ChannelData->State        = Channel_Config_WaitConfig;
+	  
+	struct
+	{
+		BT_Signal_Header_t        SignalCommandHeader;
+		BT_Signal_ConnectionReq_t ConnectionRequest;
+	} PacketData;
+
+	PacketData.SignalCommandHeader.Code              = BT_SIGNAL_CONNECTION_REQUEST;
+	PacketData.SignalCommandHeader.Identifier        = ++Bluetooth_Connection.SignallingIdentifier;
+	PacketData.SignalCommandHeader.Length            = sizeof(PacketData.ConnectionRequest);
+	PacketData.ConnectionRequest.PSM                 = PSM;
+	PacketData.ConnectionRequest.SourceChannel       = ChannelData->LocalNumber;
+	
+	Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);
+
+	BT_ACL_DEBUG(1, ">> L2CAP Connection Request", NULL);
+	BT_ACL_DEBUG(2, "-- PSM 0x%04X", PacketData.ConnectionRequest.PSM);
+	BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.ConnectionRequest.SourceChannel);
+
+	return ChannelData;
+}
+
+void Bluetooth_CloseChannel(Bluetooth_Channel_t* Channel)
+{
+	if ((Channel == NULL) || (Channel->State == Channel_Closed))
+	  return;
+	  
+	Channel->State = Channel_WaitDisconnect;
+
+	struct
+	{
+		BT_Signal_Header_t           SignalCommandHeader;
+		BT_Signal_DisconnectionReq_t DisconnectionRequest;
+	} PacketData;
+	
+	PacketData.SignalCommandHeader.Code            = BT_SIGNAL_DISCONNECTION_REQUEST;
+	PacketData.SignalCommandHeader.Identifier      = ++Bluetooth_Connection.SignallingIdentifier;
+	PacketData.SignalCommandHeader.Length          = sizeof(PacketData.DisconnectionRequest);
+	PacketData.DisconnectionRequest.DestinationChannel = Channel->RemoteNumber;
+	PacketData.DisconnectionRequest.SourceChannel = Channel->LocalNumber;
+
+	Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);
+	
+	BT_ACL_DEBUG(1, ">> L2CAP Disconnection Request", NULL);
+	BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData.DisconnectionRequest.DestinationChannel);	
+	BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.DisconnectionRequest.SourceChannel);	
+}
+
 static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t*        ACLPacketHeader,
                                                   BT_DataPacket_Header_t* DataHeader,
                                                   BT_Signal_Header_t*     SignalCommandHeader)
@@ -208,8 +283,29 @@ static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t*        ACLPac
 	BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest.PSM);
 	BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
 	
-	Bluetooth_Channel_t* ChannelData = Bluetooth_InitChannelData(ConnectionRequest.SourceChannel, ConnectionRequest.PSM);
+	Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, true);
 
+	if (ChannelData == NULL)
+	{
+		for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
+		{
+			if (Bluetooth_Connection.Channels[i].State == Channel_Closed)
+			{
+				ChannelData = &Bluetooth_Connection.Channels[i];				
+				ChannelData->LocalNumber = (BLUETOOTH_CHANNELNUMBER_BASEOFFSET + i);
+				break;
+			}
+		}
+	}
+
+	if (ChannelData != NULL)
+	{
+		ChannelData->RemoteNumber = ConnectionRequest.SourceChannel;
+		ChannelData->PSM          = ConnectionRequest.PSM;
+		ChannelData->LocalMTU     = MAXIMUM_CHANNEL_MTU;
+		ChannelData->State        = Channel_Config_WaitConfig;
+	}
+	
 	struct
 	{
 		BT_Signal_Header_t         SignalCommandHeader;
@@ -228,10 +324,37 @@ static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t*        ACLPac
 
 	BT_ACL_DEBUG(1, ">> L2CAP Connection Response", NULL);
 	BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.ConnectionResponse.Result);
-	BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConnectionResponse.SourceChannel);
 	BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.ConnectionResponse.DestinationChannel);
+	BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConnectionResponse.SourceChannel);
+}
+
+static inline void Bluetooth_Signal_ConnectionResp(BT_ACL_Header_t* ACLPacketHeader,
+                                                   BT_DataPacket_Header_t* DataHeader,
+                                                   BT_Signal_Header_t* SignalCommandHeader)
+{
+	BT_Signal_ConnectionResp_t ConnectionResponse;
+	
+	Pipe_Read_Stream_LE(&ConnectionResponse, sizeof(ConnectionResponse));
+
+	Pipe_ClearIN();
+	Pipe_Freeze();
+
+	BT_ACL_DEBUG(1, "<< L2CAP Connection Response", NULL);
+	BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConnectionResponse.Result);	
+	BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);	
+	BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);	
+
+	Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.DestinationChannel, false);
+
+	if (ChannelData != NULL)
+	{
+		ChannelData->RemoteNumber = ConnectionResponse.SourceChannel;
+		ChannelData->State        = (ConnectionResponse.Result == BT_CONNECTION_SUCCESSFUL) ?
+		                             Channel_Config_WaitConfig : Channel_Closed;
+	}
 }
 
+
 static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t*        ACLPacketHeader,
                                                      BT_DataPacket_Header_t* DataHeader,
                                                      BT_Signal_Header_t*     SignalCommandHeader)
@@ -375,6 +498,27 @@ static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t*        ACL
 	BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.DisconnectionResponse.DestinationChannel);
 }
 
+static inline void Bluetooth_Signal_DisconnectionResp(BT_ACL_Header_t*        ACLPacketHeader,
+                                                      BT_DataPacket_Header_t* DataHeader,
+                                                      BT_Signal_Header_t*     SignalCommandHeader)
+{
+	BT_Signal_DisconnectionResp_t DisconnectionResponse;
+	
+	Pipe_Read_Stream_LE(&DisconnectionResponse, sizeof(DisconnectionResponse));
+
+	BT_ACL_DEBUG(1, "<< L2CAP Disconnection Response", NULL);
+	BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel);
+	BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel);
+	
+	Pipe_ClearIN();
+	Pipe_Freeze();
+	
+	Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, true);
+	
+	if (ChannelData->State == Channel_WaitDisconnect)
+	  ChannelData->State = Channel_Closed;
+}
+
 static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
                                             BT_DataPacket_Header_t* DataHeader,
                                             BT_Signal_Header_t* SignalCommandHeader)
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.h b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.h
index 1edbfa603..40f2bbdcd 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.h
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothACLPackets.h
@@ -42,7 +42,7 @@
 		
 	/* 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                   2
+		#define ACL_DEBUG_LEVEL                   1
 
 		#define BT_CHANNEL_SIGNALING              0x0001
 		#define BT_CHANNEL_CONNECTIONLESS         0x0002
@@ -160,6 +160,9 @@
 			static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t* ACLPacketHeader,
                                                               BT_DataPacket_Header_t* DataHeader,
                                                               BT_Signal_Header_t* SignalCommandHeader);
+			static inline void Bluetooth_Signal_ConnectionResp(BT_ACL_Header_t* ACLPacketHeader,
+                                                               BT_DataPacket_Header_t* DataHeader,
+                                                               BT_Signal_Header_t* SignalCommandHeader);
 			static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
                                                         BT_DataPacket_Header_t* DataHeader,
                                                         BT_Signal_Header_t* SignalCommandHeader);
@@ -172,6 +175,9 @@
 			static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t* ACLPacketHeader,
                                                                  BT_DataPacket_Header_t* DataHeader,
                                                                  BT_Signal_Header_t* SignalCommandHeader);
+			static inline void Bluetooth_Signal_DisconnectionResp(BT_ACL_Header_t* ACLPacketHeader,
+                                                                  BT_DataPacket_Header_t* DataHeader,
+                                                                  BT_Signal_Header_t* SignalCommandHeader);
 			static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t* ACLPacketHeader,
                                                                BT_DataPacket_Header_t* DataHeader,
                                                                BT_Signal_Header_t* SignalCommandHeader);
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c
index 11b6a616b..ec1f637d7 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c
@@ -68,31 +68,3 @@ Bluetooth_Channel_t* Bluetooth_GetChannelData(uint16_t ChannelNumber, bool Searc
 
 	return NULL;
 }
-
-Bluetooth_Channel_t* Bluetooth_InitChannelData(uint16_t RemoteChannelNumber, uint16_t PSM)
-{
-	Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(RemoteChannelNumber, false);
-
-	if (ChannelData == NULL)
-	{
-		for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
-		{
-			if (Bluetooth_Connection.Channels[i].State == Channel_Closed)
-			{
-				ChannelData = &Bluetooth_Connection.Channels[i];				
-				ChannelData->LocalNumber = (BLUETOOTH_CHANNELNUMBER_BASEOFFSET + i);
-				break;
-			}
-		}
-	}
-
-	if (ChannelData != NULL)
-	{
-		ChannelData->RemoteNumber = RemoteChannelNumber;
-		ChannelData->PSM          = PSM;
-		ChannelData->LocalMTU     = MAXIMUM_CHANNEL_MTU;
-		ChannelData->State        = Channel_Config_WaitConfig;
-	}
-
-	return ChannelData;
-}
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.h b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.h
index b768bc2d2..9a90cffc6 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.h
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.h
@@ -102,18 +102,18 @@
 		#include "BluetoothHCICommands.h"
 		#include "BluetoothACLPackets.h"		
 		
-	/* Function Prototypes: */
-		Bluetooth_Channel_t* Bluetooth_GetChannelData(uint16_t ChannelNumber, bool SearchByRemoteChannel);
-		Bluetooth_Channel_t* Bluetooth_InitChannelData(uint16_t RemoteChannelNumber, uint16_t PSM);
-		
+	/* Function Prototypes: */		
 		void Bluetooth_Stack_Init(void);
 		void Bluetooth_Stack_USBTask(void);
 
-		bool    Bluetooth_ConnectionRequest(uint8_t* RemoteAddress);
-		void    Bluetooth_ConnectionComplete(void);
-		void    Bluetooth_DisconnectionComplete(void);
-		void    Bluetooth_PacketReceived(uint16_t* PacketLength, Bluetooth_Channel_t* Channel);
-		uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel);
+		bool                 Bluetooth_ConnectionRequest(uint8_t* RemoteAddress);
+		void                 Bluetooth_ConnectionComplete(void);
+		void                 Bluetooth_DisconnectionComplete(void);
+		void                 Bluetooth_PacketReceived(uint16_t* PacketLength, Bluetooth_Channel_t* Channel);
+		Bluetooth_Channel_t* Bluetooth_GetChannelData(uint16_t ChannelNumber, bool SearchByRemoteChannel);
+		Bluetooth_Channel_t* Bluetooth_OpenChannel(uint16_t PSM);
+		void                 Bluetooth_CloseChannel(Bluetooth_Channel_t* Channel);
+		uint8_t              Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel);
 
 	/* External Variables: */
 		extern Bluetooth_Device_t     Bluetooth_DeviceConfiguration;
-- 
GitLab