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
32 TODO: Make SendPacket respect receiver's MTU
33 TODO: Make ReceivePacket stitch together MTU fragments (?)
34 TODO: Add channel opened/closed callbacks
37 #define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C
38 #include "BluetoothACLPackets.h"
40 /** Bluetooth ACL processing task. This task should be called repeatedly the main Bluetooth
41 * stack task to manage the ACL processing state.
43 void Bluetooth_ACLTask(void)
45 /* Process incomming ACL packets, if any */
46 Bluetooth_ProcessIncommingACLPackets();
48 /* Check for any half-open channels, send configuration details to the remote device if found */
49 for (uint8_t i
= 0; i
< BLUETOOTH_MAX_OPEN_CHANNELS
; i
++)
51 Bluetooth_Channel_t
* ChannelData
= &Bluetooth_Connection
.Channels
[i
];
53 bool MustSendConfigReq
= true;
55 /* Check if we are in a channel state which requires a configuration request to be sent */
56 switch (ChannelData
->State
)
58 case Channel_Config_WaitConfig
:
59 ChannelData
->State
= Channel_Config_WaitReqResp
;
61 case Channel_Config_WaitSendConfig
:
62 ChannelData
->State
= Channel_Config_WaitResp
;
65 MustSendConfigReq
= false;
69 /* Only send a configuration request if it the channel was in a state which required it */
70 if (MustSendConfigReq
)
74 BT_Signal_Header_t SignalCommandHeader
;
75 BT_Signal_ConfigurationReq_t ConfigurationRequest
;
79 BT_Config_Option_Header_t Header
;
84 /* Fill out the Signal Command header in the response packet */
85 PacketData
.SignalCommandHeader
.Code
= BT_SIGNAL_CONFIGURATION_REQUEST
;
86 PacketData
.SignalCommandHeader
.Identifier
= ++Bluetooth_Connection
.SignallingIdentifier
;
87 PacketData
.SignalCommandHeader
.Length
= sizeof(PacketData
.ConfigurationRequest
) +
88 sizeof(PacketData
.Option_LocalMTU
);
90 /* Fill out the Configuration Request in the response packet, including local MTU information */
91 PacketData
.ConfigurationRequest
.DestinationChannel
= ChannelData
->RemoteNumber
;
92 PacketData
.ConfigurationRequest
.Flags
= 0;
93 PacketData
.Option_LocalMTU
.Header
.Type
= BT_CONFIG_OPTION_MTU
;
94 PacketData
.Option_LocalMTU
.Header
.Length
= sizeof(PacketData
.Option_LocalMTU
.Value
);
95 PacketData
.Option_LocalMTU
.Value
= ChannelData
->LocalMTU
;
97 Bluetooth_SendPacket(&PacketData
, sizeof(PacketData
), NULL
);
99 BT_ACL_DEBUG(1, ">> L2CAP Configuration Request");
100 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData
.ConfigurationRequest
.DestinationChannel
);
105 /** Incomming ACL packet processing task. This task is called by the main ACL processing task to read in and process
106 * any incomming ACL packets to the device, handling signal requests as they are received or passing along channel
107 * data to the user application.
109 static void Bluetooth_ProcessIncommingACLPackets(void)
111 BT_ACL_Header_t ACLPacketHeader
;
112 BT_DataPacket_Header_t DataHeader
;
114 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE
);
117 if (!(Pipe_IsReadWriteAllowed()))
123 /* Read in the received ACL packet headers when it has been discovered that a packet has been received */
124 Pipe_Read_Stream_LE(&ACLPacketHeader
, sizeof(ACLPacketHeader
));
125 Pipe_Read_Stream_LE(&DataHeader
, sizeof(DataHeader
));
128 BT_ACL_DEBUG(2, "Packet Received");
129 BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader
.ConnectionHandle
& 0x0FFF));
130 BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader
.DataLength
);
131 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader
.DestinationChannel
);
132 BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader
.PayloadLength
);
134 /* Check the packet's destination channel - signalling channel should be processed by the stack internally */
135 if (DataHeader
.DestinationChannel
== BT_CHANNEL_SIGNALING
)
137 /* Read in the Signal Command header of the incomming packet */
138 BT_Signal_Header_t SignalCommandHeader
;
139 Pipe_Read_Stream_LE(&SignalCommandHeader
, sizeof(SignalCommandHeader
));
141 /* Dispatch to the appropriate handler function based on the Signal message code */
142 switch (SignalCommandHeader
.Code
)
144 case BT_SIGNAL_CONNECTION_REQUEST
:
145 Bluetooth_Signal_ConnectionReq(&SignalCommandHeader
);
147 case BT_SIGNAL_CONNECTION_RESPONSE
:
148 Bluetooth_Signal_ConnectionResp(&SignalCommandHeader
);
150 case BT_SIGNAL_CONFIGURATION_REQUEST
:
151 Bluetooth_Signal_ConfigurationReq(&SignalCommandHeader
);
153 case BT_SIGNAL_CONFIGURATION_RESPONSE
:
154 Bluetooth_Signal_ConfigurationResp(&SignalCommandHeader
);
156 case BT_SIGNAL_DISCONNECTION_REQUEST
:
157 Bluetooth_Signal_DisconnectionReq(&SignalCommandHeader
);
159 case BT_SIGNAL_DISCONNECTION_RESPONSE
:
160 Bluetooth_Signal_DisconnectionResp(&SignalCommandHeader
);
162 case BT_SIGNAL_ECHO_REQUEST
:
163 Bluetooth_Signal_EchoReq(&SignalCommandHeader
);
165 case BT_SIGNAL_INFORMATION_REQUEST
:
166 Bluetooth_Signal_InformationReq(&SignalCommandHeader
);
168 case BT_SIGNAL_COMMAND_REJECT
:
169 BT_ACL_DEBUG(1, "<< Command Reject");
171 uint16_t RejectReason
;
172 Pipe_Read_Stream_LE(&RejectReason
, sizeof(RejectReason
));
173 Pipe_Discard_Stream(ACLPacketHeader
.DataLength
- sizeof(RejectReason
));
177 BT_ACL_DEBUG(2, "-- Reason: %d", RejectReason
);
180 BT_ACL_DEBUG(1, "<< Unknown Signaling Command 0x%02X", SignalCommandHeader
.Code
);
182 Pipe_Discard_Stream(ACLPacketHeader
.DataLength
);
190 /* Non-signalling packet received, read in the packet contents and pass to the user application */
191 uint8_t PacketData
[DataHeader
.PayloadLength
];
192 Pipe_Read_Stream_LE(PacketData
, DataHeader
.PayloadLength
);
196 Bluetooth_PacketReceived(PacketData
, DataHeader
.PayloadLength
,
197 Bluetooth_GetChannelData(DataHeader
.DestinationChannel
, CHANNEL_SEARCH_LOCALNUMBER
));
201 /** Sends a packet to the remote device on the specified channel.
203 * \param[in] Data Pointer to a buffer where the data is to be sourced from
204 * \param[in] DataLen Length of the data to send
205 * \param[in] Channel Channel information structure containing the destination channel's information, NULL to send
206 * to the remote device's signalling channel
208 * \return A value from the \ref BT_SendPacket_ErrorCodes_t enum
210 uint8_t Bluetooth_SendPacket(void* Data
, const uint16_t DataLen
, Bluetooth_Channel_t
* const Channel
)
212 BT_ACL_Header_t ACLPacketHeader
;
213 BT_DataPacket_Header_t DataHeader
;
215 /* A remote device must be connected before a packet transmission is attempted */
216 if (!(Bluetooth_Connection
.IsConnected
))
217 return BT_SENDPACKET_NotConnected
;
219 /* If the destination channel is not the signalling channel and it is not currently fully open, abort */
220 if ((Channel
!= NULL
) && (Channel
->State
!= Channel_Open
))
221 return BT_SENDPACKET_ChannelNotOpen
;
223 /* Fill out the packet's header from the remote device connection information structure */
224 ACLPacketHeader
.ConnectionHandle
= (Bluetooth_Connection
.ConnectionHandle
| BT_ACL_FIRST_AUTOFLUSH
);
225 ACLPacketHeader
.DataLength
= sizeof(DataHeader
) + DataLen
;
226 DataHeader
.PayloadLength
= DataLen
;
227 DataHeader
.DestinationChannel
= (Channel
== NULL
) ? BT_CHANNEL_SIGNALING
: Channel
->RemoteNumber
;
229 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE
);
231 Pipe_WaitUntilReady();
234 /* Write the packet contents to the pipe so that it can be sent to the remote device */
235 Pipe_Write_Stream_LE(&ACLPacketHeader
, sizeof(ACLPacketHeader
));
236 Pipe_Write_Stream_LE(&DataHeader
, sizeof(DataHeader
));
237 Pipe_Write_Stream_LE(Data
, DataLen
);
243 BT_ACL_DEBUG(2, "Packet Sent");
244 BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader
.ConnectionHandle
& 0x0FFF));
245 BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader
.DataLength
);
246 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader
.DestinationChannel
);
247 BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader
.PayloadLength
);
249 return BT_SENDPACKET_NoError
;
252 /** Opens a bluetooth channel to the currently connected remote device, so that data can be exchanged.
254 * \note The channel is not immediately opened when this function returns - it must undergo a two way
255 * connection and configuration process first as the main Bluetooth stack processing task is
256 * repeatedly called. The returned channel is unusable by the user application until its State
257 * element has progressed to the Open state.
259 * \param[in] PSM PSM of the service that the channel is to be opened for
261 * \return Pointer to the channel information structure of the opened channel, or NULL if no free channels
263 Bluetooth_Channel_t
* Bluetooth_OpenChannel(const uint16_t PSM
)
265 Bluetooth_Channel_t
* ChannelData
= NULL
;
267 /* Search through the channel information list for a free channel item */
268 for (uint8_t i
= 0; i
< BLUETOOTH_MAX_OPEN_CHANNELS
; i
++)
270 if (Bluetooth_Connection
.Channels
[i
].State
== Channel_Closed
)
272 ChannelData
= &Bluetooth_Connection
.Channels
[i
];
274 /* Set the new channel structure's local channel number to a unique value within the connection orientated
275 channel address space */
276 ChannelData
->LocalNumber
= (BT_CHANNELNUMBER_BASEOFFSET
+ i
);
281 /* If no free channel item was found in the list, all channels are occupied - abort */
282 if (ChannelData
== NULL
)
285 /* Reset and fill out the allocated channel's information structure with defaults */
286 ChannelData
->RemoteNumber
= 0;
287 ChannelData
->PSM
= PSM
;
288 ChannelData
->LocalMTU
= MAXIMUM_CHANNEL_MTU
;
289 ChannelData
->State
= Channel_WaitConnectRsp
;
293 BT_Signal_Header_t SignalCommandHeader
;
294 BT_Signal_ConnectionReq_t ConnectionRequest
;
297 /* Fill out the Signal Command header in the response packet */
298 PacketData
.SignalCommandHeader
.Code
= BT_SIGNAL_CONNECTION_REQUEST
;
299 PacketData
.SignalCommandHeader
.Identifier
= ++Bluetooth_Connection
.SignallingIdentifier
;
300 PacketData
.SignalCommandHeader
.Length
= sizeof(PacketData
.ConnectionRequest
);
302 /* Fill out the Connection Request in the response packet */
303 PacketData
.ConnectionRequest
.PSM
= PSM
;
304 PacketData
.ConnectionRequest
.SourceChannel
= ChannelData
->LocalNumber
;
306 Bluetooth_SendPacket(&PacketData
, sizeof(PacketData
), NULL
);
308 BT_ACL_DEBUG(1, ">> L2CAP Connection Request");
309 BT_ACL_DEBUG(2, "-- PSM 0x%04X", PacketData
.ConnectionRequest
.PSM
);
310 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData
.ConnectionRequest
.SourceChannel
);
315 /** Closes a bluetooth channel that is open to the currently connected remote device, so that no further data
318 * \note The channel is not immediately closed when this function returns - it must undergo an asynchronous
319 * disconnection process first as the main Bluetooth stack processing task is repeatedly called. The
320 * returned channel is unusable by the user application upon return however the channel is not completely
321 * closed until its State element has progressed to the Closed state.
323 * \param[in,out] Channel Channel information structure of the channel to close
325 void Bluetooth_CloseChannel(Bluetooth_Channel_t
* const Channel
)
327 /* Don't try to close a non-existing or already closed channel */
328 if ((Channel
== NULL
) || (Channel
->State
== Channel_Closed
))
331 /* Set the channel's state to the start of the teardown process */
332 Channel
->State
= Channel_WaitDisconnect
;
336 BT_Signal_Header_t SignalCommandHeader
;
337 BT_Signal_DisconnectionReq_t DisconnectionRequest
;
340 /* Fill out the Signal Command header in the response packet */
341 PacketData
.SignalCommandHeader
.Code
= BT_SIGNAL_DISCONNECTION_REQUEST
;
342 PacketData
.SignalCommandHeader
.Identifier
= ++Bluetooth_Connection
.SignallingIdentifier
;
343 PacketData
.SignalCommandHeader
.Length
= sizeof(PacketData
.DisconnectionRequest
);
345 /* Fill out the Disconnection Request in the response packet */
346 PacketData
.DisconnectionRequest
.DestinationChannel
= Channel
->RemoteNumber
;
347 PacketData
.DisconnectionRequest
.SourceChannel
= Channel
->LocalNumber
;
349 Bluetooth_SendPacket(&PacketData
, sizeof(PacketData
), NULL
);
351 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Request");
352 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData
.DisconnectionRequest
.DestinationChannel
);
353 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData
.DisconnectionRequest
.SourceChannel
);
356 /** Internal Bluetooth stack Signal Command processing routine for a Connection Request command.
358 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
360 static inline void Bluetooth_Signal_ConnectionReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
362 BT_Signal_ConnectionReq_t ConnectionRequest
;
364 Pipe_Read_Stream_LE(&ConnectionRequest
, sizeof(ConnectionRequest
));
369 BT_ACL_DEBUG(1, "<< L2CAP Connection Request");
370 BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest
.PSM
);
371 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest
.SourceChannel
);
373 /* Try to retrieve the existing channel's information structure if it exists */
374 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConnectionRequest
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
376 /* If an existing channel item with the correct remote channel number was not found, find a free channel entry */
377 if (ChannelData
== NULL
)
379 /* Look through the channel information list for a free entry */
380 for (uint8_t i
= 0; i
< BLUETOOTH_MAX_OPEN_CHANNELS
; i
++)
382 if (Bluetooth_Connection
.Channels
[i
].State
== Channel_Closed
)
384 ChannelData
= &Bluetooth_Connection
.Channels
[i
];
386 /* Set the new channel structure's local channel number to a unique value within the connection orientated
387 channel address space */
388 ChannelData
->LocalNumber
= (BT_CHANNELNUMBER_BASEOFFSET
+ i
);
394 uint8_t ChannelStatus
= BT_CONNECTION_REFUSED_RESOURCES
;
396 /* Reset the channel item contents only if a channel entry was found for it */
397 if (ChannelData
!= NULL
)
399 /* Check if the user application will allow the connection based on its PSM */
400 if (Bluetooth_ChannelConnectionRequest(ConnectionRequest
.PSM
))
402 ChannelData
->RemoteNumber
= ConnectionRequest
.SourceChannel
;
403 ChannelData
->PSM
= ConnectionRequest
.PSM
;
404 ChannelData
->LocalMTU
= MAXIMUM_CHANNEL_MTU
;
405 ChannelData
->State
= Channel_Config_WaitConfig
;
407 ChannelStatus
= BT_CONNECTION_SUCCESSFUL
;
411 ChannelStatus
= BT_CONNECTION_REFUSED_PSM
;
417 BT_Signal_Header_t SignalCommandHeader
;
418 BT_Signal_ConnectionResp_t ConnectionResponse
;
421 /* Fill out the Signal Command header in the response packet */
422 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_CONNECTION_RESPONSE
;
423 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
424 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.ConnectionResponse
);
426 /* Fill out the Connection Response in the response packet */
427 ResponsePacket
.ConnectionResponse
.DestinationChannel
= ChannelData
->LocalNumber
;
428 ResponsePacket
.ConnectionResponse
.SourceChannel
= ChannelData
->RemoteNumber
;
429 ResponsePacket
.ConnectionResponse
.Result
= ChannelStatus
;
430 ResponsePacket
.ConnectionResponse
.Status
= 0x00;
432 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
434 BT_ACL_DEBUG(1, ">> L2CAP Connection Response");
435 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConnectionResponse
.Result
);
436 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.DestinationChannel
);
437 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.SourceChannel
);
440 /** Internal Bluetooth stack Signal Command processing routine for a Connection Response command.
442 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
444 static inline void Bluetooth_Signal_ConnectionResp(const BT_Signal_Header_t
* const SignalCommandHeader
)
446 BT_Signal_ConnectionResp_t ConnectionResponse
;
448 Pipe_Read_Stream_LE(&ConnectionResponse
, sizeof(ConnectionResponse
));
453 BT_ACL_DEBUG(1, "<< L2CAP Connection Response");
454 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConnectionResponse
.Result
);
455 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionResponse
.SourceChannel
);
456 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse
.DestinationChannel
);
458 /* Search for the referenced channel in the channel information list */
459 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConnectionResponse
.SourceChannel
, CHANNEL_SEARCH_LOCALNUMBER
);
461 /* Only progress if the referenced channel data was found */
462 if (ChannelData
!= NULL
)
464 /* Set the channel structure's remote channel number to the channel allocated on the remote device */
465 ChannelData
->RemoteNumber
= ConnectionResponse
.SourceChannel
;
466 ChannelData
->State
= (ConnectionResponse
.Result
== BT_CONNECTION_SUCCESSFUL
) ?
467 Channel_Config_WaitConfig
: Channel_Closed
;
471 /** Internal Bluetooth stack Signal Command processing routine for a Configuration Request command.
473 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
475 static inline void Bluetooth_Signal_ConfigurationReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
477 BT_Signal_ConfigurationReq_t ConfigurationRequest
;
479 /* Allocate a buffer large enough to hold the variable number of configuration options in the request */
480 uint8_t OptionsLen
= (SignalCommandHeader
->Length
- sizeof(ConfigurationRequest
));
481 uint8_t Options
[OptionsLen
];
483 Pipe_Read_Stream_LE(&ConfigurationRequest
, sizeof(ConfigurationRequest
));
484 Pipe_Read_Stream_LE(&Options
, sizeof(Options
));
489 /* Search for the referenced channel in the channel information list */
490 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConfigurationRequest
.DestinationChannel
, CHANNEL_SEARCH_LOCALNUMBER
);
492 BT_ACL_DEBUG(1, "<< L2CAP Configuration Request");
493 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest
.DestinationChannel
);
494 BT_ACL_DEBUG(2, "-- Options Len: 0x%04X", OptionsLen
);
496 /* Only look at the channel configuration options if a valid channel entry for the local channel number was found */
497 if (ChannelData
!= NULL
)
499 /* Iterate through each option in the configuration request to look for ones which can be processed */
500 uint8_t OptionPos
= 0;
501 while (OptionPos
< OptionsLen
)
503 BT_Config_Option_Header_t
* OptionHeader
= (BT_Config_Option_Header_t
*)&Options
[OptionPos
];
504 void* OptionData
= &Options
[OptionPos
+ sizeof(BT_Config_Option_Header_t
)];
506 BT_ACL_DEBUG(2, "-- Option Type: 0x%04X", OptionHeader
->Type
);
507 BT_ACL_DEBUG(2, "-- Option Length: 0x%04X", (sizeof(BT_Config_Option_Header_t
) + OptionHeader
->Length
));
509 /* Store the remote MTU option's value if present */
510 if (OptionHeader
->Type
== BT_CONFIG_OPTION_MTU
)
511 ChannelData
->RemoteMTU
= *((uint16_t*)OptionData
);
513 /* Progress to the next option in the packet */
514 OptionPos
+= (sizeof(BT_Config_Option_Header_t
) + OptionHeader
->Length
);
520 BT_Signal_Header_t SignalCommandHeader
;
521 BT_Signal_ConfigurationResp_t ConfigurationResponse
;
524 /* Fill out the Signal Command header in the response packet */
525 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_CONFIGURATION_RESPONSE
;
526 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
527 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.ConfigurationResponse
);
529 /* Fill out the Configuration Response in the response packet */
530 ResponsePacket
.ConfigurationResponse
.SourceChannel
= ChannelData
->RemoteNumber
;
531 ResponsePacket
.ConfigurationResponse
.Flags
= 0x00;
532 ResponsePacket
.ConfigurationResponse
.Result
= (ChannelData
!= NULL
) ? BT_CONFIGURATION_SUCCESSFUL
: BT_CONFIGURATION_REJECTED
;
534 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
536 if (ChannelData
!= NULL
)
538 switch (ChannelData
->State
)
540 case Channel_Config_WaitConfig
:
541 ChannelData
->State
= Channel_Config_WaitSendConfig
;
543 case Channel_Config_WaitReqResp
:
544 ChannelData
->State
= Channel_Config_WaitResp
;
546 case Channel_Config_WaitReq
:
547 ChannelData
->State
= Channel_Open
;
552 BT_ACL_DEBUG(1, ">> L2CAP Configuration Response");
553 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConfigurationResponse
.SourceChannel
);
554 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConfigurationResponse
.Result
);
557 /** Internal Bluetooth stack Signal Command processing routine for a Configuration Response command.
559 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
561 static inline void Bluetooth_Signal_ConfigurationResp(const BT_Signal_Header_t
* const SignalCommandHeader
)
563 BT_Signal_ConfigurationResp_t ConfigurationResponse
;
565 Pipe_Read_Stream_LE(&ConfigurationResponse
, sizeof(ConfigurationResponse
));
570 BT_ACL_DEBUG(1, "<< L2CAP Configuration Response");
571 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConfigurationResponse
.SourceChannel
);
572 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse
.Result
);
574 /* Search for the referenced channel in the channel information list */
575 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConfigurationResponse
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
577 /* Only update the channel's state if it was found in the channel list */
578 if (ChannelData
!= NULL
)
580 /* Check if the channel configuration completed successfuly */
581 if (ConfigurationResponse
.Result
== BT_CONFIGURATION_SUCCESSFUL
)
583 switch (ChannelData
->State
)
585 case Channel_Config_WaitReqResp
:
586 ChannelData
->State
= Channel_Config_WaitReq
;
588 case Channel_Config_WaitResp
:
589 ChannelData
->State
= Channel_Open
;
595 /* Configuration failed - close the channel */
596 ChannelData
->State
= Channel_Closed
;
601 /** Internal Bluetooth stack Signal Command processing routine for a Disconnection Request command.
603 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
605 static inline void Bluetooth_Signal_DisconnectionReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
607 BT_Signal_DisconnectionReq_t DisconnectionRequest
;
609 Pipe_Read_Stream_LE(&DisconnectionRequest
, sizeof(DisconnectionRequest
));
611 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Request");
612 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionRequest
.DestinationChannel
);
613 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionRequest
.SourceChannel
);
618 /* Search for the referenced channel in the channel information list */
619 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(DisconnectionRequest
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
623 BT_Signal_Header_t SignalCommandHeader
;
624 BT_Signal_DisconnectionResp_t DisconnectionResponse
;
627 /* Fill out the Signal Command header in the response packet */
628 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_DISCONNECTION_RESPONSE
;
629 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
630 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.DisconnectionResponse
);
632 /* Fill out the Disconnection Response in the response packet */
633 ResponsePacket
.DisconnectionResponse
.DestinationChannel
= ChannelData
->RemoteNumber
;
634 ResponsePacket
.DisconnectionResponse
.SourceChannel
= ChannelData
->LocalNumber
;
636 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
638 /* If the channel was found in the channel list, close it */
639 if (ChannelData
!= NULL
)
640 ChannelData
->State
= Channel_Closed
;
642 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Response");
643 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.SourceChannel
);
644 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.DestinationChannel
);
647 /** Internal Bluetooth stack Signal Command processing routine for a Disconnection Response command.
649 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
651 static inline void Bluetooth_Signal_DisconnectionResp(const BT_Signal_Header_t
* const SignalCommandHeader
)
653 BT_Signal_DisconnectionResp_t DisconnectionResponse
;
655 Pipe_Read_Stream_LE(&DisconnectionResponse
, sizeof(DisconnectionResponse
));
657 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Response");
658 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionResponse
.DestinationChannel
);
659 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionResponse
.SourceChannel
);
664 /* Search for the referenced channel in the channel information list */
665 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(DisconnectionResponse
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
667 /* If the channel was found in the channel list, close it */
668 if (ChannelData
!= NULL
)
669 ChannelData
->State
= Channel_Closed
;
672 /** Internal Bluetooth stack Signal Command processing routine for an Echo Request command.
674 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
676 static inline void Bluetooth_Signal_EchoReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
678 BT_ACL_DEBUG(1, "<< L2CAP Echo Request");
685 BT_Signal_Header_t SignalCommandHeader
;
688 /* Fill out the Signal Command header in the response packet */
689 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_ECHO_RESPONSE
;
690 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
691 ResponsePacket
.SignalCommandHeader
.Length
= 0;
693 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
695 BT_ACL_DEBUG(1, ">> L2CAP Echo Response");
698 /** Internal Bluetooth stack Signal Command processing routine for an Information Request command.
700 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
702 static inline void Bluetooth_Signal_InformationReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
704 BT_Signal_InformationReq_t InformationRequest
;
706 Pipe_Read_Stream_LE(&InformationRequest
, sizeof(InformationRequest
));
708 BT_ACL_DEBUG(1, "<< L2CAP Information Request");
709 BT_ACL_DEBUG(2, "-- Info Type: 0x%04X", InformationRequest
.InfoType
);
716 BT_Signal_Header_t SignalCommandHeader
;
717 BT_Signal_InformationResp_t InformationResponse
;
724 /* Retrieve the requested information and store it in the outgoing packet, if found */
725 switch (InformationRequest
.InfoType
)
728 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_SUCCESSFUL
;
731 *((uint16_t*)&ResponsePacket
.Data
) = MAXIMUM_CHANNEL_MTU
;
733 case BT_INFOREQ_EXTENDEDFEATURES
:
734 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_SUCCESSFUL
;
737 *((uint32_t*)&ResponsePacket
.Data
) = 0;
740 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_NOTSUPPORTED
;
745 /* Fill out the Signal Command header in the response packet */
746 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_INFORMATION_RESPONSE
;
747 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
748 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.InformationResponse
) + DataLen
;
750 /* Fill out the Information Response in the response packet */
751 ResponsePacket
.InformationResponse
.InfoType
= InformationRequest
.InfoType
;
753 Bluetooth_SendPacket(&ResponsePacket
, (sizeof(ResponsePacket
) - sizeof(ResponsePacket
.Data
) + DataLen
), NULL
);
755 BT_ACL_DEBUG(1, ">> L2CAP Information Response");
756 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.InformationResponse
.Result
);