3      Copyright (C) Dean Camera, 2010. 
   5   dean [at] fourwalledcubicle [dot] com 
   6       www.fourwalledcubicle.com 
  10   Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, distribute, and sell this  
  13   software and its documentation for any purpose is hereby granted 
  14   without fee, provided that the above copyright notice appear in  
  15   all copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting  
  17   documentation, and that the name of the author not be used in  
  18   advertising or publicity pertaining to distribution of the  
  19   software without specific, written prior permission. 
  21   The author disclaim all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #define  INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C 
  32 #include "BluetoothACLPackets.h" 
  34 void Bluetooth_ACLTask(void) 
  36         Bluetooth_ProcessACLPackets(); 
  38         for (uint8_t i 
= 0; i 
< BLUETOOTH_MAX_OPEN_CHANNELS
; i
++) 
  40                 Bluetooth_Channel_t
* ChannelData 
= &Bluetooth_Connection
.Channels
[i
]; 
  42                 bool MustSendConfigReq 
= true; 
  44                 switch (ChannelData
->State
) 
  46                         case Channel_Config_WaitConfig
: 
  47                                 ChannelData
->State 
= Channel_Config_WaitReqResp
; 
  49                         case Channel_Config_WaitSendConfig
: 
  50                                 ChannelData
->State 
= Channel_Config_WaitResp
; 
  53                                 MustSendConfigReq  
= false; 
  57                 if (MustSendConfigReq
) 
  61                                 BT_Signal_Header_t           SignalCommandHeader
; 
  62                                 BT_Signal_ConfigurationReq_t ConfigurationRequest
; 
  66                                         BT_Config_Option_Header_t Header
; 
  71                         PacketData
.SignalCommandHeader
.Code            
= BT_SIGNAL_CONFIGURATION_REQUEST
; 
  72                         PacketData
.SignalCommandHeader
.Identifier      
= ++Bluetooth_Connection
.SignallingIdentifier
; 
  73                         PacketData
.SignalCommandHeader
.Length          
= sizeof(PacketData
.ConfigurationRequest
) + 
  74                                                                          sizeof(PacketData
.Option_LocalMTU
); 
  75                         PacketData
.ConfigurationRequest
.DestinationChannel 
= ChannelData
->RemoteNumber
; 
  76                         PacketData
.ConfigurationRequest
.Flags          
= 0; 
  77                         PacketData
.Option_LocalMTU
.Header
.Type         
= BT_CONFIG_OPTION_MTU
; 
  78                         PacketData
.Option_LocalMTU
.Header
.Length       
= sizeof(PacketData
.Option_LocalMTU
.Value
); 
  79                         PacketData
.Option_LocalMTU
.Value               
= ChannelData
->LocalMTU
; 
  81                         Bluetooth_SendPacket(&PacketData
, sizeof(PacketData
), NULL
); 
  83                         BT_ACL_DEBUG(1, ">> L2CAP Configuration Request", NULL
); 
  84                         BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData
.ConfigurationRequest
.DestinationChannel
); 
  89 static void Bluetooth_ProcessACLPackets(void) 
  91         BT_ACL_Header_t        ACLPacketHeader
; 
  92         BT_DataPacket_Header_t DataHeader
; 
  94         Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE
); 
  97         if (!(Pipe_IsReadWriteAllowed())) 
 103         Pipe_Read_Stream_LE(&ACLPacketHeader
, sizeof(ACLPacketHeader
)); 
 104         Pipe_Read_Stream_LE(&DataHeader
, sizeof(DataHeader
)); 
 106         BT_ACL_DEBUG(2, "", NULL
); 
 107         BT_ACL_DEBUG(2, "Packet Received", NULL
); 
 108         BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader
.ConnectionHandle 
& 0x0FFF)); 
 109         BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader
.DataLength
); 
 110         BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader
.DestinationChannel
); 
 111         BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader
.PayloadLength
); 
 113         if (DataHeader
.DestinationChannel 
== BT_CHANNEL_SIGNALING
) 
 115                 BT_Signal_Header_t SignalCommandHeader
; 
 116                 Pipe_Read_Stream_LE(&SignalCommandHeader
, sizeof(SignalCommandHeader
)); 
 118                 switch (SignalCommandHeader
.Code
) 
 120                         case BT_SIGNAL_CONNECTION_REQUEST
: 
 121                                 Bluetooth_Signal_ConnectionReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
); 
 123                         case BT_SIGNAL_CONFIGURATION_REQUEST
: 
 124                                 Bluetooth_Signal_ConfigurationReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
); 
 126                         case BT_SIGNAL_DISCONNECTION_REQUEST
: 
 127                                 Bluetooth_Signal_DisconnectionReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
); 
 129                         case BT_SIGNAL_ECHO_REQUEST
: 
 130                                 Bluetooth_Signal_EchoReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
); 
 132                         case BT_SIGNAL_INFORMATION_REQUEST
: 
 133                                 Bluetooth_Signal_InformationReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
); 
 136                                 BT_ACL_DEBUG(1, "<< Unknown Signaling Command 0x%02X", SignalCommandHeader
.Code
); 
 138                                 Pipe_Discard_Stream(ACLPacketHeader
.DataLength
); 
 146                 Bluetooth_PacketReceived(&DataHeader
.PayloadLength
, Bluetooth_GetChannelData(DataHeader
.DestinationChannel
, true)); 
 148                 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE
); 
 149                 Pipe_Discard_Stream(DataHeader
.PayloadLength
); 
 155 uint8_t Bluetooth_SendPacket(void* Data
, uint16_t DataLen
, Bluetooth_Channel_t
* Channel
) 
 157         BT_ACL_Header_t        ACLPacketHeader
; 
 158         BT_DataPacket_Header_t DataHeader
; 
 160         if (!(Bluetooth_Connection
.IsConnected
)) 
 161           return BT_SENDPACKET_NotConnected
; 
 163         if ((Channel 
!= NULL
) && (Channel
->State 
!= Channel_Open
)) 
 164           return BT_SENDPACKET_ChannelNotOpen
; 
 166         // TODO: Add packet fragmentation here after retrieving the device's signal channel MTU 
 168         ACLPacketHeader
.ConnectionHandle      
= Bluetooth_Connection
.ConnectionHandle 
| (1 << 13); 
 169         ACLPacketHeader
.DataLength            
= sizeof(DataHeader
) + DataLen
; 
 170         DataHeader
.PayloadLength              
= DataLen
; 
 171         DataHeader
.DestinationChannel         
= (Channel 
== NULL
) ? BT_CHANNEL_SIGNALING 
: Channel
->RemoteNumber
; 
 173         Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE
); 
 176         Pipe_Write_Stream_LE(&ACLPacketHeader
, sizeof(ACLPacketHeader
)); 
 177         Pipe_Write_Stream_LE(&DataHeader
, sizeof(DataHeader
)); 
 178         Pipe_Write_Stream_LE(Data
, DataLen
); 
 182         BT_ACL_DEBUG(2, "", NULL
); 
 183         BT_ACL_DEBUG(2, "Packet Sent", NULL
); 
 184         BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader
.ConnectionHandle 
& 0x0FFF)); 
 185         BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader
.DataLength
); 
 186         BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader
.DestinationChannel
); 
 187         BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader
.PayloadLength
); 
 189         return BT_SENDPACKET_NoError
; 
 192 static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t
* ACLPacketHeader
, 
 193                                                   BT_DataPacket_Header_t
* DataHeader
, 
 194                                                   BT_Signal_Header_t
* SignalCommandHeader
) 
 196         BT_Signal_ConnectionReq_t ConnectionRequest
; 
 198         Pipe_Read_Stream_LE(&ConnectionRequest
, sizeof(ConnectionRequest
)); 
 203         BT_ACL_DEBUG(1, "<< L2CAP Connection Request", NULL
); 
 204         BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest
.PSM
); 
 205         BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest
.SourceChannel
); 
 207         Bluetooth_Channel_t
* ChannelData 
= Bluetooth_InitChannelData(ConnectionRequest
.SourceChannel
, ConnectionRequest
.PSM
); 
 211                 BT_Signal_Header_t         SignalCommandHeader
; 
 212                 BT_Signal_ConnectionResp_t ConnectionResponse
; 
 215         ResponsePacket
.SignalCommandHeader
.Code              
= BT_SIGNAL_CONNECTION_RESPONSE
; 
 216         ResponsePacket
.SignalCommandHeader
.Identifier        
= SignalCommandHeader
->Identifier
; 
 217         ResponsePacket
.SignalCommandHeader
.Length            
= sizeof(ResponsePacket
.ConnectionResponse
); 
 218         ResponsePacket
.ConnectionResponse
.Result             
= (ChannelData 
== NULL
) ? BT_CONNECTION_REFUSED_RESOURCES 
: BT_CONNECTION_SUCCESSFUL
; 
 219         ResponsePacket
.ConnectionResponse
.DestinationChannel 
= ChannelData
->LocalNumber
; 
 220         ResponsePacket
.ConnectionResponse
.SourceChannel      
= ChannelData
->RemoteNumber
; 
 221         ResponsePacket
.ConnectionResponse
.Status             
= 0x00; 
 223         Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
); 
 225         BT_ACL_DEBUG(1, ">> L2CAP Connection Response", NULL
); 
 226         BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConnectionResponse
.Result
); 
 227         BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.SourceChannel
); 
 228         BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.DestinationChannel
); 
 231 static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t
* ACLPacketHeader
, 
 232                                                      BT_DataPacket_Header_t
* DataHeader
, 
 233                                                      BT_Signal_Header_t
* SignalCommandHeader
) 
 235         BT_Signal_ConfigurationReq_t ConfigurationRequest
; 
 238         Pipe_Read_Stream_LE(&ConfigurationRequest
, sizeof(ConfigurationRequest
)); 
 239         OptionsLen 
= (DataHeader
->PayloadLength 
- sizeof(*SignalCommandHeader
)); 
 241         Bluetooth_Channel_t
* ChannelData 
= Bluetooth_GetChannelData(ConfigurationRequest
.DestinationChannel
, false); 
 245                 BT_Config_Option_Header_t OptionHeader
; 
 247                 Pipe_Read_Stream_LE(&OptionHeader
, sizeof(OptionHeader
)); 
 249                 if ((OptionHeader
.Type 
== BT_CONFIG_OPTION_MTU
) && (ChannelData 
!= NULL
)) 
 250                   Pipe_Read_Stream_LE(&ChannelData
->RemoteMTU
, sizeof(ChannelData
->RemoteMTU
)); 
 252                   Pipe_Discard_Stream(OptionHeader
.Length
); 
 254                 OptionsLen 
-= (sizeof(OptionHeader
) + OptionHeader
.Length
); 
 260         BT_ACL_DEBUG(1, "<< L2CAP Configuration Request", NULL
); 
 261         BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest
.DestinationChannel
); 
 262         BT_ACL_DEBUG(2, "-- Options Len: 0x%04X", ConfigurationRequest
.DestinationChannel
); 
 263         BT_ACL_DEBUG(2, "-- Remote MTU: 0x%04X", ChannelData
->RemoteMTU
); 
 267                 BT_Signal_Header_t            SignalCommandHeader
; 
 268                 BT_Signal_ConfigurationResp_t ConfigurationResponse
; 
 271         ResponsePacket
.SignalCommandHeader
.Code              
= BT_SIGNAL_CONFIGURATION_RESPONSE
; 
 272         ResponsePacket
.SignalCommandHeader
.Identifier        
= SignalCommandHeader
->Identifier
; 
 273         ResponsePacket
.SignalCommandHeader
.Length            
= sizeof(ResponsePacket
.ConfigurationResponse
); 
 274         ResponsePacket
.ConfigurationResponse
.SourceChannel   
= ChannelData
->RemoteNumber
; 
 275         ResponsePacket
.ConfigurationResponse
.Flags           
= 0x00; 
 276         ResponsePacket
.ConfigurationResponse
.Result          
= (ChannelData 
!= NULL
) ? BT_CONFIGURATION_SUCCESSFUL 
: BT_CONFIGURATION_REJECTED
; 
 278         Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
); 
 280         if (ChannelData 
!= NULL
) 
 282                 switch (ChannelData
->State
) 
 284                         case Channel_Config_WaitConfig
: 
 285                                 ChannelData
->State 
= Channel_Config_WaitSendConfig
; 
 287                         case Channel_Config_WaitReqResp
: 
 288                                 ChannelData
->State 
= Channel_Config_WaitResp
; 
 290                         case Channel_Config_WaitReq
: 
 291                                 ChannelData
->State 
= Channel_Open
; 
 296         BT_ACL_DEBUG(1, ">> L2CAP Configuration Response", NULL
); 
 297         BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConfigurationResponse
.SourceChannel
); 
 298         BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConfigurationResponse
.Result
); 
 301 static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t
* ACLPacketHeader
, 
 302                                                      BT_DataPacket_Header_t
* DataHeader
, 
 303                                                      BT_Signal_Header_t
* SignalCommandHeader
) 
 305         BT_Signal_DisconnectionReq_t DisconnectionRequest
; 
 307         Pipe_Read_Stream_LE(&DisconnectionRequest
, sizeof(DisconnectionRequest
)); 
 309         BT_ACL_DEBUG(1, "<< L2CAP Disconnection Request", NULL
); 
 310         BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionRequest
.DestinationChannel
); 
 311         BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionRequest
.SourceChannel
); 
 316         Bluetooth_Channel_t
* ChannelData      
= Bluetooth_GetChannelData(DisconnectionRequest
.SourceChannel
, true); 
 320                 BT_Signal_Header_t            SignalCommandHeader
; 
 321                 BT_Signal_DisconnectionResp_t DisconnectionResponse
; 
 324         ResponsePacket
.SignalCommandHeader
.Code                 
= BT_SIGNAL_DISCONNECTION_RESPONSE
; 
 325         ResponsePacket
.SignalCommandHeader
.Identifier           
= SignalCommandHeader
->Identifier
; 
 326         ResponsePacket
.SignalCommandHeader
.Length               
= sizeof(ResponsePacket
.DisconnectionResponse
); 
 327         ResponsePacket
.DisconnectionResponse
.DestinationChannel 
= ChannelData
->LocalNumber
; 
 328         ResponsePacket
.DisconnectionResponse
.SourceChannel      
= ChannelData
->RemoteNumber
; 
 330         Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
); 
 332         if (ChannelData 
!= NULL
) 
 333           ChannelData
->State 
= Channel_Closed
; 
 335         BT_ACL_DEBUG(1, ">> L2CAP Disconnection Response", NULL
); 
 336         BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.SourceChannel
); 
 337         BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.DestinationChannel
); 
 340 static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t
* ACLPacketHeader
, 
 341                                             BT_DataPacket_Header_t
* DataHeader
, 
 342                                             BT_Signal_Header_t
* SignalCommandHeader
) 
 344         BT_ACL_DEBUG(1, "<< L2CAP Echo Request", NULL
); 
 351                 BT_Signal_Header_t SignalCommandHeader
; 
 354         ResponsePacket
.SignalCommandHeader
.Code                 
= BT_SIGNAL_ECHO_RESPONSE
; 
 355         ResponsePacket
.SignalCommandHeader
.Identifier           
= SignalCommandHeader
->Identifier
; 
 356         ResponsePacket
.SignalCommandHeader
.Length               
= 0; 
 358         Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
); 
 360         BT_ACL_DEBUG(1, ">> L2CAP Echo Response", NULL
); 
 363 static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t
* ACLPacketHeader
, 
 364                                                    BT_DataPacket_Header_t
* DataHeader
, 
 365                                                    BT_Signal_Header_t
* SignalCommandHeader
) 
 367         BT_Signal_InformationReq_t InformationRequest
; 
 369         Pipe_Read_Stream_LE(&InformationRequest
, sizeof(InformationRequest
)); 
 371         BT_ACL_DEBUG(1, "<< L2CAP Information Request", NULL
); 
 372         BT_ACL_DEBUG(2, "-- Info Type: 0x%04X", InformationRequest
.InfoType
); 
 379                 BT_Signal_Header_t SignalCommandHeader
; 
 380                 BT_Signal_InformationResp_t InformationResponse
; 
 387         switch (InformationRequest
.InfoType
) 
 390                         ResponsePacket
.InformationResponse
.Result 
= BT_INFORMATION_SUCCESSFUL
; 
 393                         *((uint16_t*)&ResponsePacket
.Data
) = MAXIMUM_CHANNEL_MTU
; 
 395                 case BT_INFOREQ_EXTENDEDFEATURES
: 
 396                         ResponsePacket
.InformationResponse
.Result 
= BT_INFORMATION_SUCCESSFUL
; 
 399                         *((uint32_t*)&ResponsePacket
.Data
) = 0; 
 402                         ResponsePacket
.InformationResponse
.Result 
= BT_INFORMATION_NOTSUPPORTED
; 
 407         ResponsePacket
.SignalCommandHeader
.Code                 
= BT_SIGNAL_INFORMATION_RESPONSE
; 
 408         ResponsePacket
.SignalCommandHeader
.Identifier           
= SignalCommandHeader
->Identifier
; 
 409         ResponsePacket
.SignalCommandHeader
.Length               
= sizeof(ResponsePacket
.InformationResponse
) + DataLen
; 
 411         Bluetooth_SendPacket(&ResponsePacket
, (sizeof(ResponsePacket
) - sizeof(ResponsePacket
.Data
) + DataLen
), NULL
); 
 413         BT_ACL_DEBUG(1, ">> L2CAP Information Response", NULL
);  
 414         BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.InformationResponse
.Result
);