+\r
+ /* If no free channel item was found in the list, all channels are occupied - abort */\r
+ if (ChannelData == NULL)\r
+ return NULL;\r
+\r
+ /* Reset and fill out the allocated channel's information structure with defaults */\r
+ ChannelData->RemoteNumber = 0;\r
+ ChannelData->PSM = PSM;\r
+ ChannelData->LocalMTU = MAXIMUM_CHANNEL_MTU;\r
+ ChannelData->State = Channel_WaitConnectRsp;\r
+ \r
+ struct\r
+ {\r
+ BT_Signal_Header_t SignalCommandHeader;\r
+ BT_Signal_ConnectionReq_t ConnectionRequest;\r
+ } PacketData;\r
+\r
+ /* Fill out the Signal Command header in the response packet */\r
+ PacketData.SignalCommandHeader.Code = BT_SIGNAL_CONNECTION_REQUEST;\r
+ PacketData.SignalCommandHeader.Identifier = ++Bluetooth_Connection.SignallingIdentifier;\r
+ PacketData.SignalCommandHeader.Length = sizeof(PacketData.ConnectionRequest);\r
+ \r
+ /* Fill out the Connection Request in the response packet */\r
+ PacketData.ConnectionRequest.PSM = PSM;\r
+ PacketData.ConnectionRequest.SourceChannel = ChannelData->LocalNumber;\r
+ \r
+ Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);\r
+\r
+ BT_ACL_DEBUG(1, ">> L2CAP Connection Request");\r
+ BT_ACL_DEBUG(2, "-- PSM 0x%04X", PacketData.ConnectionRequest.PSM);\r
+ BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.ConnectionRequest.SourceChannel);\r
+\r
+ return ChannelData;\r
+}\r
+\r
+/** Closes a bluetooth channel that is open to the currently connected remote device, so that no further data\r
+ * can be exchanged.\r
+ *\r
+ * \note The channel is not immediately closed when this function returns - it must undergo an asynchronous\r
+ * disconnection process first as the main Bluetooth stack processing task is repeatedly called. The\r
+ * returned channel is unusable by the user application upon return however the channel is not completely\r
+ * closed until its State element has progressed to the Closed state.\r
+ *\r
+ * \param[in,out] Channel Channel information structure of the channel to close\r
+ */\r
+void Bluetooth_CloseChannel(Bluetooth_Channel_t* const Channel)\r
+{\r
+ /* Don't try to close a non-existing or already closed channel */\r
+ if ((Channel == NULL) || (Channel->State == Channel_Closed))\r
+ return;\r
+\r
+ /* Set the channel's state to the start of the teardown process */\r
+ Channel->State = Channel_WaitDisconnect;\r
+\r
+ struct\r
+ {\r
+ BT_Signal_Header_t SignalCommandHeader;\r
+ BT_Signal_DisconnectionReq_t DisconnectionRequest;\r
+ } PacketData;\r
+ \r
+ /* Fill out the Signal Command header in the response packet */\r
+ PacketData.SignalCommandHeader.Code = BT_SIGNAL_DISCONNECTION_REQUEST;\r
+ PacketData.SignalCommandHeader.Identifier = ++Bluetooth_Connection.SignallingIdentifier;\r
+ PacketData.SignalCommandHeader.Length = sizeof(PacketData.DisconnectionRequest);\r
+\r
+ /* Fill out the Disconnection Request in the response packet */\r
+ PacketData.DisconnectionRequest.DestinationChannel = Channel->RemoteNumber;\r
+ PacketData.DisconnectionRequest.SourceChannel = Channel->LocalNumber;\r
+\r
+ Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);\r
+ \r
+ BT_ACL_DEBUG(1, ">> L2CAP Disconnection Request");\r
+ BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData.DisconnectionRequest.DestinationChannel); \r
+ BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.DisconnectionRequest.SourceChannel); \r