Update UC3 platform driver support to use the bitmasks defined in the header files...
[pub/USBasp.git] / Demos / Host / Incomplete / BluetoothHost / Lib / RFCOMMControl.c
index 23a1876..7d5a461 100644 (file)
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2010.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, distribute, and sell this \r
-  software and its documentation for any purpose is hereby granted\r
-  without fee, provided that the above copyright notice appear in \r
-  all copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting \r
-  documentation, and that the name of the author not be used in \r
-  advertising or publicity pertaining to distribution of the \r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  RFCOMM multiplexer control layer module. This module handles multiplexer\r
- *  channel commands to the control DLCI in the RFCOMM layer, to open, configure,\r
- *  test and close logical RFCOMM channels.\r
- */\r
-\r
-#define  INCLUDE_FROM_RFCOMM_CONTROL_C\r
-#include "RFCOMMControl.h"\r
-\r
-void RFCOMM_ProcessControlCommand(const uint8_t* Command, Bluetooth_Channel_t* const Channel)\r
-{\r
-       const RFCOMM_Command_t* CommandHeader  = (const RFCOMM_Command_t*)Command;\r
-       const uint8_t*          CommandData    = (const uint8_t*)Command + sizeof(RFCOMM_Command_t);\r
-       uint16_t                ControlDataLen = RFCOMM_GetFrameDataLength(CommandData);\r
-\r
-       /* Adjust the command data pointer to skip over the variable size field */\r
-       CommandData += (ControlDataLen < 128) ? 1 : 2;\r
-\r
-       switch (CommandHeader->Command)\r
-       {\r
-               case RFCOMM_Control_Test:\r
-                       RFCOMM_ProcessTestCommand(CommandHeader, CommandData, Channel);\r
-                       break;\r
-               case RFCOMM_Control_FlowControlEnable:\r
-                       RFCOMM_ProcessFCECommand(CommandHeader, CommandData, Channel);\r
-                       break;\r
-               case RFCOMM_Control_FlowControlDisable:\r
-                       RFCOMM_ProcessFCDCommand(CommandHeader, CommandData, Channel);\r
-                       break;\r
-               case RFCOMM_Control_ModemStatus:\r
-                       RFCOMM_ProcessMSCommand(CommandHeader, CommandData, Channel);\r
-                       break;\r
-               case RFCOMM_Control_RemotePortNegotiation:\r
-                       RFCOMM_ProcessRPNCommand(CommandHeader, CommandData, Channel);\r
-                       break;\r
-               case RFCOMM_Control_RemoteLineStatus:\r
-                       RFCOMM_ProcessRLSCommand(CommandHeader, CommandData, Channel);\r
-                       break;\r
-               case RFCOMM_Control_DLCParameterNegotiation:\r
-                       RFCOMM_ProcessDPNCommand(CommandHeader, CommandData, Channel);\r
-                       break;\r
-               default:\r
-                       BT_RFCOMM_DEBUG(1, "<< Unknown Command");               \r
-                       break;\r
-       }\r
-}\r
-\r
-static void RFCOMM_ProcessTestCommand(const RFCOMM_Command_t* const CommandHeader, const uint8_t* CommandData,\r
-                                                 Bluetooth_Channel_t* const Channel)\r
-{\r
-       BT_RFCOMM_DEBUG(1, "<< TEST Command");\r
-}\r
-\r
-static void RFCOMM_ProcessFCECommand(const RFCOMM_Command_t* const CommandHeader, const uint8_t* CommandData,\r
-                                                Bluetooth_Channel_t* const Channel)\r
-{\r
-       BT_RFCOMM_DEBUG(1, "<< FCE Command");\r
-}\r
-\r
-static void RFCOMM_ProcessFCDCommand(const RFCOMM_Command_t* const CommandHeader, const uint8_t* CommandData,\r
-                                                Bluetooth_Channel_t* const Channel)\r
-{\r
-       BT_RFCOMM_DEBUG(1, "<< FCD Command");\r
-}\r
-\r
-static void RFCOMM_ProcessMSCommand(const RFCOMM_Command_t* const CommandHeader, const uint8_t* CommandData,\r
-                                               Bluetooth_Channel_t* const Channel)\r
-{\r
-       BT_RFCOMM_DEBUG(1, "<< MS Command");\r
-}\r
-\r
-static void RFCOMM_ProcessRPNCommand(const RFCOMM_Command_t* const CommandHeader, const uint8_t* CommandData,\r
-                                                Bluetooth_Channel_t* const Channel)\r
-{\r
-       BT_RFCOMM_DEBUG(1, "<< RPN Command");\r
-}\r
-\r
-static void RFCOMM_ProcessRLSCommand(const RFCOMM_Command_t* const CommandHeader, const uint8_t* CommandData,\r
-                                                Bluetooth_Channel_t* const Channel)\r
-{\r
-       BT_RFCOMM_DEBUG(1, "<< RLS Command");\r
-}\r
-\r
-static void RFCOMM_ProcessDPNCommand(const RFCOMM_Command_t* const CommandHeader, const uint8_t* CommandData,\r
-                                                Bluetooth_Channel_t* const Channel)\r
-{\r
-       const RFCOMM_DPN_Parameters_t* Params = (const RFCOMM_DPN_Parameters_t*)CommandData;\r
-\r
-       BT_RFCOMM_DEBUG(1, "<< DPN Command");\r
-       BT_RFCOMM_DEBUG(2, "-- Config DLCI: 0x%02X", Params->DLCI);\r
-       \r
-       /* Ignore parameter negotiations to the control channel */\r
-       if (Params->DLCI == RFCOMM_CONTROL_DLCI)\r
-         return;\r
-       \r
-       /* Retrieve existing channel configuration data, if already opened */\r
-       RFCOMM_Channel_t* RFCOMMChannel = RFCOMM_GetChannelData(Params->DLCI);\r
-       \r
-       /* Check if the channel has no corresponding entry - remote did not open it first */\r
-       if (RFCOMMChannel == NULL)\r
-       {\r
-               /* Find a free entry in the RFCOMM channel multiplexer state array */\r
-               for (uint8_t i = 0; i < RFCOMM_MAX_OPEN_CHANNELS; i++)\r
-               {\r
-                       /* If the channel's DLCI is zero, the channel state entry is free */\r
-                       if (!(RFCOMM_Channels[i].DLCI))\r
-                       {\r
-                               RFCOMMChannel       = &RFCOMM_Channels[i];\r
-                               RFCOMMChannel->DLCI = Params->DLCI;\r
-                               break;\r
-                       }\r
-               }\r
-               \r
-               /* No free entry was found, discard the request */\r
-               if (RFCOMMChannel == NULL)\r
-               {\r
-                       BT_RFCOMM_DEBUG(2, "-- No Free Channel");\r
-                       return;\r
-               }\r
-       }\r
-       \r
-       /* Save the new channel configuration */\r
-       RFCOMMChannel->State       = RFCOMM_Channel_Open;\r
-       RFCOMMChannel->Priority    = Params->Priority;\r
-       RFCOMMChannel->UseUIFrames = (Params->FrameType != 0);\r
-       RFCOMMChannel->RemoteMTU   = Params->MaximumFrameSize;\r
-       \r
-       struct\r
-       {\r
-               RFCOMM_Command_t        CommandHeader;\r
-               uint8_t                 Length;\r
-               RFCOMM_DPN_Parameters_t Params;\r
-       } DPNResponse;\r
-       \r
-       /* Fill out the DPN response data */\r
-       DPNResponse.CommandHeader.Command = CommandHeader->Command;\r
-       DPNResponse.CommandHeader.EA      = true;\r
-       DPNResponse.Length                = (sizeof(DPNResponse.Params) << 1) | 0x01;\r
-       DPNResponse.Params                = *Params;\r
-       \r
-       BT_RFCOMM_DEBUG(1, ">> DPN Response");\r
-\r
-       /* Send the PDN response to acknowledge the command */\r
-       RFCOMM_SendFrame(RFCOMM_CONTROL_DLCI, false, RFCOMM_Frame_UIH, sizeof(DPNResponse), &DPNResponse, Channel);\r
-}\r
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2011.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2011  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
+ *
+ *  RFCOMM multiplexer control layer module. This module handles multiplexer
+ *  channel commands to the control DLCI in the RFCOMM layer, to open, configure,
+ *  test and close logical RFCOMM channels.
+ */
+
+#define  INCLUDE_FROM_RFCOMM_CONTROL_C
+#include "RFCOMMControl.h"
+
+void RFCOMM_ProcessControlCommand(const uint8_t* Command,
+                                  Bluetooth_Channel_t* const ACLChannel)
+{
+       const RFCOMM_Command_t* CommandHeader  = (const RFCOMM_Command_t*)Command;
+       const uint8_t*          CommandData    = (const uint8_t*)Command + sizeof(RFCOMM_Command_t);
+       uint8_t                 CommandDataLen = RFCOMM_GetVariableFieldValue(&CommandData);
+
+       switch (CommandHeader->Command)
+       {
+               case RFCOMM_Control_Test:
+                       RFCOMM_ProcessTestCommand(CommandHeader, CommandDataLen, CommandData, ACLChannel);
+                       break;
+               case RFCOMM_Control_FlowControlEnable:
+                       RFCOMM_ProcessFCECommand(CommandHeader, CommandData, ACLChannel);
+                       break;
+               case RFCOMM_Control_FlowControlDisable:
+                       RFCOMM_ProcessFCDCommand(CommandHeader, CommandData, ACLChannel);
+                       break;
+               case RFCOMM_Control_ModemStatus:
+                       RFCOMM_ProcessMSCCommand(CommandHeader, CommandDataLen, CommandData, ACLChannel);
+                       break;
+               case RFCOMM_Control_RemotePortNegotiation:
+                       RFCOMM_ProcessRPNCommand(CommandHeader, CommandData, ACLChannel);
+                       break;
+               case RFCOMM_Control_RemoteLineStatus:
+                       RFCOMM_ProcessRLSCommand(CommandHeader, CommandData, ACLChannel);
+                       break;
+               case RFCOMM_Control_DLCParameterNegotiation:
+                       RFCOMM_ProcessDPNCommand(CommandHeader, CommandData, ACLChannel);
+                       break;
+               default:
+                       BT_RFCOMM_DEBUG(1, "<< Unknown Command");
+                       break;
+       }
+}
+
+static void RFCOMM_ProcessTestCommand(const RFCOMM_Command_t* const CommandHeader,
+                                      const uint8_t CommandDataLen,
+                                      const uint8_t* CommandData,
+                                      Bluetooth_Channel_t* const ACLChannel)
+{
+       const uint8_t* Params = (const uint8_t*)CommandData;
+
+       BT_RFCOMM_DEBUG(1, "<< TEST Command");
+
+       struct
+       {
+               RFCOMM_Command_t CommandHeader;
+               uint8_t          Length;
+               uint8_t          TestData[CommandDataLen];
+       } TestResponse;
+
+       /* Fill out the Test response data */
+       TestResponse.CommandHeader = (RFCOMM_Command_t){.Command = RFCOMM_Control_Test, .EA = true, .CR = false};
+       TestResponse.Length        = (CommandDataLen << 1) | 0x01;
+       memcpy(TestResponse.TestData, Params, CommandDataLen);
+
+       BT_RFCOMM_DEBUG(1, ">> TEST Response");
+
+       /* Send the PDN response to acknowledge the command */
+       RFCOMM_SendFrame(RFCOMM_CONTROL_DLCI, false, RFCOMM_Frame_UIH, sizeof(TestResponse), &TestResponse, ACLChannel);
+}
+
+static void RFCOMM_ProcessFCECommand(const RFCOMM_Command_t* const CommandHeader,
+                                     const uint8_t* CommandData,
+                                                Bluetooth_Channel_t* const ACLChannel)
+{
+       BT_RFCOMM_DEBUG(1, "<< FCE Command");
+}
+
+static void RFCOMM_ProcessFCDCommand(const RFCOMM_Command_t* const CommandHeader,
+                                     const uint8_t* CommandData,
+                                                Bluetooth_Channel_t* const ACLChannel)
+{
+       BT_RFCOMM_DEBUG(1, "<< FCD Command");
+}
+
+static void RFCOMM_ProcessMSCCommand(const RFCOMM_Command_t* const CommandHeader,
+                                     const uint8_t CommandDataLen,
+                                     const uint8_t* CommandData,
+                                     Bluetooth_Channel_t* const ACLChannel)
+{
+       const RFCOMM_MSC_Parameters_t* Params = (const RFCOMM_MSC_Parameters_t*)CommandData;
+
+       BT_RFCOMM_DEBUG(1, "<< MSC %s", (CommandHeader->CR) ? "Command" : "Response");
+       BT_RFCOMM_DEBUG(2, "-- DLCI: 0x%02X", Params->Channel.DLCI);
+
+       /* Ignore status flags sent to the control channel */
+       if (Params->Channel.DLCI == RFCOMM_CONTROL_DLCI)
+         return;
+
+       /* Retrieve existing channel configuration data, if already opened */
+       RFCOMM_Channel_t* RFCOMMChannel = RFCOMM_GetChannelData(Params->Channel.DLCI);
+
+       /* If the channel does not exist, abort */
+       if (RFCOMMChannel == NULL)
+         return;
+
+       /* Check if the MSC packet is a command or a response */
+       if (CommandHeader->CR)
+       {
+               /* Save the new channel signals to the channel state structure */
+               RFCOMMChannel->Remote.Signals  = Params->Signals;
+               RFCOMMChannel->ConfigFlags    |= RFCOMM_CONFIG_REMOTESIGNALS;
+
+               /* If the command contains the optional break signals field, store the value */
+               if (CommandDataLen == sizeof(RFCOMM_MSC_Parameters_t))
+                 RFCOMMChannel->Remote.BreakSignal = Params->BreakSignal;
+
+               /* Notify the user application that the signals have been received */
+               RFCOMM_ChannelSignalsReceived(RFCOMMChannel);
+
+               struct
+               {
+                       RFCOMM_Command_t        CommandHeader;
+                       uint8_t                 Length;
+                       RFCOMM_MSC_Parameters_t Params;
+               } MSResponse;
+
+               /* Fill out the MS response data */
+               MSResponse.CommandHeader  = (RFCOMM_Command_t){.Command = RFCOMM_Control_ModemStatus, .EA = true, .CR = false};
+               MSResponse.Length         = (CommandDataLen << 1) | 0x01;
+               memcpy(&MSResponse.Params, Params, sizeof(RFCOMM_MSC_Parameters_t));
+
+               BT_RFCOMM_DEBUG(1, ">> MSC Response");
+
+               /* Send the MSC response to acknowledge the command */
+               RFCOMM_SendFrame(RFCOMM_CONTROL_DLCI, false, RFCOMM_Frame_UIH,
+                                                (sizeof(MSResponse) - sizeof(MSResponse.Params) + CommandDataLen), &MSResponse, ACLChannel);
+       }
+       else
+       {
+               /* Indicate that the remote device has acknowledged the sent signals */
+               RFCOMMChannel->ConfigFlags |= RFCOMM_CONFIG_LOCALSIGNALS;
+       }
+}
+
+static void RFCOMM_ProcessRPNCommand(const RFCOMM_Command_t* const CommandHeader,
+                                     const uint8_t* CommandData,
+                                                Bluetooth_Channel_t* const ACLChannel)
+{
+       BT_RFCOMM_DEBUG(1, "<< RPN Command");
+}
+
+static void RFCOMM_ProcessRLSCommand(const RFCOMM_Command_t* const CommandHeader,
+                                     const uint8_t* CommandData,
+                                                Bluetooth_Channel_t* const ACLChannel)
+{
+       BT_RFCOMM_DEBUG(1, "<< RLS Command");
+}
+
+static void RFCOMM_ProcessDPNCommand(const RFCOMM_Command_t* const CommandHeader,
+                                     const uint8_t* CommandData,
+                                                Bluetooth_Channel_t* const ACLChannel)
+{
+       const RFCOMM_DPN_Parameters_t* Params = (const RFCOMM_DPN_Parameters_t*)CommandData;
+
+       BT_RFCOMM_DEBUG(1, "<< DPN Command");
+       BT_RFCOMM_DEBUG(2, "-- DLCI: 0x%02X", Params->DLCI);
+
+       /* Ignore parameter negotiations to the control channel */
+       if (Params->DLCI == RFCOMM_CONTROL_DLCI)
+         return;
+
+       /* Retrieve existing channel configuration data, if already opened */
+       RFCOMM_Channel_t* RFCOMMChannel = RFCOMM_GetChannelData(Params->DLCI);
+
+       /* Check if the channel has no corresponding entry - remote did not open it first */
+       if (RFCOMMChannel == NULL)
+       {
+               /* Create a new entry in the channel table for the new channel */
+               RFCOMMChannel = RFCOMM_GetFreeChannelEntry(Params->DLCI);
+
+               /* No free entry was found, discard the request */
+               if (RFCOMMChannel == NULL)
+               {
+                       BT_RFCOMM_DEBUG(2, "-- No Free Channel");
+                       return;
+               }
+       }
+
+       /* Save the new channel configuration */
+       RFCOMMChannel->State       = RFCOMM_Channel_Configure;
+       RFCOMMChannel->Priority    = Params->Priority;
+       RFCOMMChannel->MTU         = Params->MaximumFrameSize;
+
+       struct
+       {
+               RFCOMM_Command_t        CommandHeader;
+               uint8_t                 Length;
+               RFCOMM_DPN_Parameters_t Params;
+       } DPNResponse;
+
+       /* Fill out the DPN response data */
+       DPNResponse.CommandHeader = (RFCOMM_Command_t){.Command = RFCOMM_Control_DLCParameterNegotiation, .EA = true, .CR = false};
+       DPNResponse.Length                  = (sizeof(DPNResponse.Params) << 1) | 0x01;
+       memcpy(&DPNResponse.Params, Params, sizeof(RFCOMM_DPN_Parameters_t));
+       DPNResponse.Params.ConvergenceLayer = 0x00; // TODO: Enable credit based transaction support
+
+       BT_RFCOMM_DEBUG(1, ">> DPN Response");
+
+       /* Send the DPN response to acknowledge the command */
+       RFCOMM_SendFrame(RFCOMM_CONTROL_DLCI, false, RFCOMM_Frame_UIH, sizeof(DPNResponse), &DPNResponse, ACLChannel);
+}
+