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_CONFIGURATION_RESPONSE
:
127 Bluetooth_Signal_ConfigurationResp(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
);
129 case BT_SIGNAL_DISCONNECTION_REQUEST
:
130 Bluetooth_Signal_DisconnectionReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
);
132 case BT_SIGNAL_ECHO_REQUEST
:
133 Bluetooth_Signal_EchoReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
);
135 case BT_SIGNAL_INFORMATION_REQUEST
:
136 Bluetooth_Signal_InformationReq(&ACLPacketHeader
, &DataHeader
, &SignalCommandHeader
);
139 BT_ACL_DEBUG(1, "<< Unknown Signaling Command 0x%02X", SignalCommandHeader
.Code
);
141 Pipe_Discard_Stream(ACLPacketHeader
.DataLength
);
149 Bluetooth_PacketReceived(&DataHeader
.PayloadLength
, Bluetooth_GetChannelData(DataHeader
.DestinationChannel
, false));
151 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE
);
152 Pipe_Discard_Stream(DataHeader
.PayloadLength
);
158 uint8_t Bluetooth_SendPacket(void* Data
, uint16_t DataLen
, Bluetooth_Channel_t
* Channel
)
160 BT_ACL_Header_t ACLPacketHeader
;
161 BT_DataPacket_Header_t DataHeader
;
163 if (!(Bluetooth_Connection
.IsConnected
))
164 return BT_SENDPACKET_NotConnected
;
166 if ((Channel
!= NULL
) && (Channel
->State
!= Channel_Open
))
167 return BT_SENDPACKET_ChannelNotOpen
;
169 // TODO: Add packet fragmentation here after retrieving the device's signal channel MTU
171 ACLPacketHeader
.ConnectionHandle
= (Bluetooth_Connection
.ConnectionHandle
| BT_ACL_FIRST_AUTOFLUSH
);
172 ACLPacketHeader
.DataLength
= sizeof(DataHeader
) + DataLen
;
173 DataHeader
.PayloadLength
= DataLen
;
174 DataHeader
.DestinationChannel
= (Channel
== NULL
) ? BT_CHANNEL_SIGNALING
: Channel
->RemoteNumber
;
176 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE
);
179 Pipe_Write_Stream_LE(&ACLPacketHeader
, sizeof(ACLPacketHeader
));
180 Pipe_Write_Stream_LE(&DataHeader
, sizeof(DataHeader
));
181 Pipe_Write_Stream_LE(Data
, DataLen
);
186 BT_ACL_DEBUG(2, "", NULL
);
187 BT_ACL_DEBUG(2, "Packet Sent", NULL
);
188 BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader
.ConnectionHandle
& 0x0FFF));
189 BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader
.DataLength
);
190 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader
.DestinationChannel
);
191 BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader
.PayloadLength
);
193 return BT_SENDPACKET_NoError
;
196 static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t
* ACLPacketHeader
,
197 BT_DataPacket_Header_t
* DataHeader
,
198 BT_Signal_Header_t
* SignalCommandHeader
)
200 BT_Signal_ConnectionReq_t ConnectionRequest
;
202 Pipe_Read_Stream_LE(&ConnectionRequest
, sizeof(ConnectionRequest
));
207 BT_ACL_DEBUG(1, "<< L2CAP Connection Request", NULL
);
208 BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest
.PSM
);
209 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest
.SourceChannel
);
211 Bluetooth_Channel_t
* ChannelData
= Bluetooth_InitChannelData(ConnectionRequest
.SourceChannel
, ConnectionRequest
.PSM
);
215 BT_Signal_Header_t SignalCommandHeader
;
216 BT_Signal_ConnectionResp_t ConnectionResponse
;
219 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_CONNECTION_RESPONSE
;
220 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
221 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.ConnectionResponse
);
222 ResponsePacket
.ConnectionResponse
.Result
= (ChannelData
== NULL
) ? BT_CONNECTION_REFUSED_RESOURCES
: BT_CONNECTION_SUCCESSFUL
;
223 ResponsePacket
.ConnectionResponse
.DestinationChannel
= ChannelData
->RemoteNumber
;
224 ResponsePacket
.ConnectionResponse
.SourceChannel
= ChannelData
->LocalNumber
;
225 ResponsePacket
.ConnectionResponse
.Status
= 0x00;
227 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
229 BT_ACL_DEBUG(1, ">> L2CAP Connection Response", NULL
);
230 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConnectionResponse
.Result
);
231 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.SourceChannel
);
232 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.DestinationChannel
);
235 static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t
* ACLPacketHeader
,
236 BT_DataPacket_Header_t
* DataHeader
,
237 BT_Signal_Header_t
* SignalCommandHeader
)
239 BT_Signal_ConfigurationReq_t ConfigurationRequest
;
242 Pipe_Read_Stream_LE(&ConfigurationRequest
, sizeof(ConfigurationRequest
));
243 OptionsLen
= (DataHeader
->PayloadLength
- sizeof(*SignalCommandHeader
));
245 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConfigurationRequest
.DestinationChannel
, false);
249 BT_Config_Option_Header_t OptionHeader
;
251 Pipe_Read_Stream_LE(&OptionHeader
, sizeof(OptionHeader
));
253 if ((OptionHeader
.Type
== BT_CONFIG_OPTION_MTU
) && (ChannelData
!= NULL
))
254 Pipe_Read_Stream_LE(&ChannelData
->RemoteMTU
, sizeof(ChannelData
->RemoteMTU
));
256 Pipe_Discard_Stream(OptionHeader
.Length
);
258 OptionsLen
-= (sizeof(OptionHeader
) + OptionHeader
.Length
);
264 BT_ACL_DEBUG(1, "<< L2CAP Configuration Request", NULL
);
265 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest
.DestinationChannel
);
266 BT_ACL_DEBUG(2, "-- Options Len: 0x%04X", (DataHeader
->PayloadLength
- sizeof(*SignalCommandHeader
)));
267 BT_ACL_DEBUG(2, "-- Remote MTU: 0x%04X", ChannelData
->RemoteMTU
);
271 BT_Signal_Header_t SignalCommandHeader
;
272 BT_Signal_ConfigurationResp_t ConfigurationResponse
;
275 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_CONFIGURATION_RESPONSE
;
276 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
277 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.ConfigurationResponse
);
278 ResponsePacket
.ConfigurationResponse
.SourceChannel
= ChannelData
->RemoteNumber
;
279 ResponsePacket
.ConfigurationResponse
.Flags
= 0x00;
280 ResponsePacket
.ConfigurationResponse
.Result
= (ChannelData
!= NULL
) ? BT_CONFIGURATION_SUCCESSFUL
: BT_CONFIGURATION_REJECTED
;
282 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
284 if (ChannelData
!= NULL
)
286 switch (ChannelData
->State
)
288 case Channel_Config_WaitConfig
:
289 ChannelData
->State
= Channel_Config_WaitSendConfig
;
291 case Channel_Config_WaitReqResp
:
292 ChannelData
->State
= Channel_Config_WaitResp
;
294 case Channel_Config_WaitReq
:
295 ChannelData
->State
= Channel_Open
;
300 BT_ACL_DEBUG(1, ">> L2CAP Configuration Response", NULL
);
301 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConfigurationResponse
.SourceChannel
);
302 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConfigurationResponse
.Result
);
305 static inline void Bluetooth_Signal_ConfigurationResp(BT_ACL_Header_t
* ACLPacketHeader
,
306 BT_DataPacket_Header_t
* DataHeader
,
307 BT_Signal_Header_t
* SignalCommandHeader
)
309 BT_Signal_ConfigurationResp_t ConfigurationResponse
;
311 Pipe_Read_Stream_LE(&ConfigurationResponse
, sizeof(ConfigurationResponse
));
316 BT_ACL_DEBUG(1, "<< L2CAP Configuration Response", NULL
);
317 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConfigurationResponse
.SourceChannel
);
318 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse
.Result
);
320 if (ConfigurationResponse
.Result
== BT_CONFIGURATION_SUCCESSFUL
)
322 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConfigurationResponse
.SourceChannel
, true);
324 if (ChannelData
!= NULL
)
326 switch (ChannelData
->State
)
328 case Channel_Config_WaitReqResp
:
329 ChannelData
->State
= Channel_Config_WaitReq
;
331 case Channel_Config_WaitResp
:
332 ChannelData
->State
= Channel_Open
;
339 static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t
* ACLPacketHeader
,
340 BT_DataPacket_Header_t
* DataHeader
,
341 BT_Signal_Header_t
* SignalCommandHeader
)
343 BT_Signal_DisconnectionReq_t DisconnectionRequest
;
345 Pipe_Read_Stream_LE(&DisconnectionRequest
, sizeof(DisconnectionRequest
));
347 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Request", NULL
);
348 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionRequest
.DestinationChannel
);
349 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionRequest
.SourceChannel
);
354 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(DisconnectionRequest
.SourceChannel
, true);
358 BT_Signal_Header_t SignalCommandHeader
;
359 BT_Signal_DisconnectionResp_t DisconnectionResponse
;
362 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_DISCONNECTION_RESPONSE
;
363 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
364 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.DisconnectionResponse
);
365 ResponsePacket
.DisconnectionResponse
.DestinationChannel
= ChannelData
->RemoteNumber
;
366 ResponsePacket
.DisconnectionResponse
.SourceChannel
= ChannelData
->LocalNumber
;
368 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
370 if (ChannelData
!= NULL
)
371 ChannelData
->State
= Channel_Closed
;
373 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Response", NULL
);
374 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.SourceChannel
);
375 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.DestinationChannel
);
378 static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t
* ACLPacketHeader
,
379 BT_DataPacket_Header_t
* DataHeader
,
380 BT_Signal_Header_t
* SignalCommandHeader
)
382 BT_ACL_DEBUG(1, "<< L2CAP Echo Request", NULL
);
389 BT_Signal_Header_t SignalCommandHeader
;
392 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_ECHO_RESPONSE
;
393 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
394 ResponsePacket
.SignalCommandHeader
.Length
= 0;
396 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
398 BT_ACL_DEBUG(1, ">> L2CAP Echo Response", NULL
);
401 static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t
* ACLPacketHeader
,
402 BT_DataPacket_Header_t
* DataHeader
,
403 BT_Signal_Header_t
* SignalCommandHeader
)
405 BT_Signal_InformationReq_t InformationRequest
;
407 Pipe_Read_Stream_LE(&InformationRequest
, sizeof(InformationRequest
));
409 BT_ACL_DEBUG(1, "<< L2CAP Information Request", NULL
);
410 BT_ACL_DEBUG(2, "-- Info Type: 0x%04X", InformationRequest
.InfoType
);
417 BT_Signal_Header_t SignalCommandHeader
;
418 BT_Signal_InformationResp_t InformationResponse
;
425 switch (InformationRequest
.InfoType
)
428 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_SUCCESSFUL
;
431 *((uint16_t*)&ResponsePacket
.Data
) = MAXIMUM_CHANNEL_MTU
;
433 case BT_INFOREQ_EXTENDEDFEATURES
:
434 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_SUCCESSFUL
;
437 *((uint32_t*)&ResponsePacket
.Data
) = 0;
440 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_NOTSUPPORTED
;
445 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_INFORMATION_RESPONSE
;
446 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
447 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.InformationResponse
) + DataLen
;
449 Bluetooth_SendPacket(&ResponsePacket
, (sizeof(ResponsePacket
) - sizeof(ResponsePacket
.Data
) + DataLen
), NULL
);
451 BT_ACL_DEBUG(1, ">> L2CAP Information Response", NULL
);
452 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.InformationResponse
.Result
);