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
);
232 /* Write the packet contents to the pipe so that it can be sent to the remote device */
233 Pipe_Write_Stream_LE(&ACLPacketHeader
, sizeof(ACLPacketHeader
));
234 Pipe_Write_Stream_LE(&DataHeader
, sizeof(DataHeader
));
235 Pipe_Write_Stream_LE(Data
, DataLen
);
241 BT_ACL_DEBUG(2, "Packet Sent");
242 BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader
.ConnectionHandle
& 0x0FFF));
243 BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader
.DataLength
);
244 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader
.DestinationChannel
);
245 BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader
.PayloadLength
);
247 return BT_SENDPACKET_NoError
;
250 /** Opens a bluetooth channel to the currently connected remote device, so that data can be exchanged.
252 * \note The channel is not immediately opened when this function returns - it must undergo a two way
253 * connection and configuration process first as the main Bluetooth stack processing task is
254 * repeatedly called. The returned channel is unusable by the user application until its State
255 * element has progressed to the Open state.
257 * \param[in] PSM PSM of the service that the channel is to be opened for
259 * \return Pointer to the channel information structure of the opened channel, or NULL if no free channels
261 Bluetooth_Channel_t
* Bluetooth_OpenChannel(const uint16_t PSM
)
263 Bluetooth_Channel_t
* ChannelData
= NULL
;
265 /* Search through the channel information list for a free channel item */
266 for (uint8_t i
= 0; i
< BLUETOOTH_MAX_OPEN_CHANNELS
; i
++)
268 if (Bluetooth_Connection
.Channels
[i
].State
== Channel_Closed
)
270 ChannelData
= &Bluetooth_Connection
.Channels
[i
];
272 /* Set the new channel structure's local channel number to a unique value within the connection orientated
273 channel address space */
274 ChannelData
->LocalNumber
= (BT_CHANNELNUMBER_BASEOFFSET
+ i
);
279 /* If no free channel item was found in the list, all channels are occupied - abort */
280 if (ChannelData
== NULL
)
283 /* Reset and fill out the allocated channel's information structure with defaults */
284 ChannelData
->RemoteNumber
= 0;
285 ChannelData
->PSM
= PSM
;
286 ChannelData
->LocalMTU
= MAXIMUM_CHANNEL_MTU
;
287 ChannelData
->State
= Channel_WaitConnectRsp
;
291 BT_Signal_Header_t SignalCommandHeader
;
292 BT_Signal_ConnectionReq_t ConnectionRequest
;
295 /* Fill out the Signal Command header in the response packet */
296 PacketData
.SignalCommandHeader
.Code
= BT_SIGNAL_CONNECTION_REQUEST
;
297 PacketData
.SignalCommandHeader
.Identifier
= ++Bluetooth_Connection
.SignallingIdentifier
;
298 PacketData
.SignalCommandHeader
.Length
= sizeof(PacketData
.ConnectionRequest
);
300 /* Fill out the Connection Request in the response packet */
301 PacketData
.ConnectionRequest
.PSM
= PSM
;
302 PacketData
.ConnectionRequest
.SourceChannel
= ChannelData
->LocalNumber
;
304 Bluetooth_SendPacket(&PacketData
, sizeof(PacketData
), NULL
);
306 BT_ACL_DEBUG(1, ">> L2CAP Connection Request");
307 BT_ACL_DEBUG(2, "-- PSM 0x%04X", PacketData
.ConnectionRequest
.PSM
);
308 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData
.ConnectionRequest
.SourceChannel
);
313 /** Closes a bluetooth channel that is open to the currently connected remote device, so that no further data
316 * \note The channel is not immediately closed when this function returns - it must undergo an asynchronous
317 * disconnection process first as the main Bluetooth stack processing task is repeatedly called. The
318 * returned channel is unusable by the user application upon return however the channel is not completely
319 * closed until its State element has progressed to the Closed state.
321 * \param[in,out] Channel Channel information structure of the channel to close
323 void Bluetooth_CloseChannel(Bluetooth_Channel_t
* const Channel
)
325 /* Don't try to close a non-existing or already closed channel */
326 if ((Channel
== NULL
) || (Channel
->State
== Channel_Closed
))
329 /* Set the channel's state to the start of the teardown process */
330 Channel
->State
= Channel_WaitDisconnect
;
334 BT_Signal_Header_t SignalCommandHeader
;
335 BT_Signal_DisconnectionReq_t DisconnectionRequest
;
338 /* Fill out the Signal Command header in the response packet */
339 PacketData
.SignalCommandHeader
.Code
= BT_SIGNAL_DISCONNECTION_REQUEST
;
340 PacketData
.SignalCommandHeader
.Identifier
= ++Bluetooth_Connection
.SignallingIdentifier
;
341 PacketData
.SignalCommandHeader
.Length
= sizeof(PacketData
.DisconnectionRequest
);
343 /* Fill out the Disconnection Request in the response packet */
344 PacketData
.DisconnectionRequest
.DestinationChannel
= Channel
->RemoteNumber
;
345 PacketData
.DisconnectionRequest
.SourceChannel
= Channel
->LocalNumber
;
347 Bluetooth_SendPacket(&PacketData
, sizeof(PacketData
), NULL
);
349 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Request");
350 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData
.DisconnectionRequest
.DestinationChannel
);
351 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData
.DisconnectionRequest
.SourceChannel
);
354 /** Internal Bluetooth stack Signal Command processing routine for a Connection Request command.
356 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
358 static inline void Bluetooth_Signal_ConnectionReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
360 BT_Signal_ConnectionReq_t ConnectionRequest
;
362 Pipe_Read_Stream_LE(&ConnectionRequest
, sizeof(ConnectionRequest
));
367 BT_ACL_DEBUG(1, "<< L2CAP Connection Request");
368 BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest
.PSM
);
369 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest
.SourceChannel
);
371 /* Try to retrieve the existing channel's information structure if it exists */
372 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConnectionRequest
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
374 /* If an existing channel item with the correct remote channel number was not found, find a free channel entry */
375 if (ChannelData
== NULL
)
377 /* Look through the channel information list for a free entry */
378 for (uint8_t i
= 0; i
< BLUETOOTH_MAX_OPEN_CHANNELS
; i
++)
380 if (Bluetooth_Connection
.Channels
[i
].State
== Channel_Closed
)
382 ChannelData
= &Bluetooth_Connection
.Channels
[i
];
384 /* Set the new channel structure's local channel number to a unique value within the connection orientated
385 channel address space */
386 ChannelData
->LocalNumber
= (BT_CHANNELNUMBER_BASEOFFSET
+ i
);
392 uint8_t ChannelStatus
= BT_CONNECTION_REFUSED_RESOURCES
;
394 /* Reset the channel item contents only if a channel entry was found for it */
395 if (ChannelData
!= NULL
)
397 /* Check if the user application will allow the connection based on its PSM */
398 if (Bluetooth_ChannelConnectionRequest(ConnectionRequest
.PSM
))
400 ChannelData
->RemoteNumber
= ConnectionRequest
.SourceChannel
;
401 ChannelData
->PSM
= ConnectionRequest
.PSM
;
402 ChannelData
->LocalMTU
= MAXIMUM_CHANNEL_MTU
;
403 ChannelData
->State
= Channel_Config_WaitConfig
;
405 ChannelStatus
= BT_CONNECTION_SUCCESSFUL
;
409 ChannelStatus
= BT_CONNECTION_REFUSED_PSM
;
415 BT_Signal_Header_t SignalCommandHeader
;
416 BT_Signal_ConnectionResp_t ConnectionResponse
;
419 /* Fill out the Signal Command header in the response packet */
420 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_CONNECTION_RESPONSE
;
421 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
422 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.ConnectionResponse
);
424 /* Fill out the Connection Response in the response packet */
425 ResponsePacket
.ConnectionResponse
.DestinationChannel
= ChannelData
->LocalNumber
;
426 ResponsePacket
.ConnectionResponse
.SourceChannel
= ChannelData
->RemoteNumber
;
427 ResponsePacket
.ConnectionResponse
.Result
= ChannelStatus
;
428 ResponsePacket
.ConnectionResponse
.Status
= 0x00;
430 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
432 BT_ACL_DEBUG(1, ">> L2CAP Connection Response");
433 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConnectionResponse
.Result
);
434 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.DestinationChannel
);
435 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConnectionResponse
.SourceChannel
);
438 /** Internal Bluetooth stack Signal Command processing routine for a Connection Response command.
440 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
442 static inline void Bluetooth_Signal_ConnectionResp(const BT_Signal_Header_t
* const SignalCommandHeader
)
444 BT_Signal_ConnectionResp_t ConnectionResponse
;
446 Pipe_Read_Stream_LE(&ConnectionResponse
, sizeof(ConnectionResponse
));
451 BT_ACL_DEBUG(1, "<< L2CAP Connection Response");
452 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConnectionResponse
.Result
);
453 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionResponse
.SourceChannel
);
454 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse
.DestinationChannel
);
456 /* Search for the referenced channel in the channel information list */
457 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConnectionResponse
.SourceChannel
, CHANNEL_SEARCH_LOCALNUMBER
);
459 /* Only progress if the referenced channel data was found */
460 if (ChannelData
!= NULL
)
462 /* Set the channel structure's remote channel number to the channel allocated on the remote device */
463 ChannelData
->RemoteNumber
= ConnectionResponse
.SourceChannel
;
464 ChannelData
->State
= (ConnectionResponse
.Result
== BT_CONNECTION_SUCCESSFUL
) ?
465 Channel_Config_WaitConfig
: Channel_Closed
;
469 /** Internal Bluetooth stack Signal Command processing routine for a Configuration Request command.
471 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
473 static inline void Bluetooth_Signal_ConfigurationReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
475 BT_Signal_ConfigurationReq_t ConfigurationRequest
;
477 /* Allocate a buffer large enough to hold the variable number of configuration options in the request */
478 uint8_t OptionsLen
= (SignalCommandHeader
->Length
- sizeof(ConfigurationRequest
));
479 uint8_t Options
[OptionsLen
];
481 Pipe_Read_Stream_LE(&ConfigurationRequest
, sizeof(ConfigurationRequest
));
482 Pipe_Read_Stream_LE(&Options
, sizeof(Options
));
487 /* Search for the referenced channel in the channel information list */
488 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConfigurationRequest
.DestinationChannel
, CHANNEL_SEARCH_LOCALNUMBER
);
490 BT_ACL_DEBUG(1, "<< L2CAP Configuration Request");
491 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest
.DestinationChannel
);
492 BT_ACL_DEBUG(2, "-- Remote MTU: 0x%04X", ChannelData
->RemoteMTU
);
493 BT_ACL_DEBUG(2, "-- Options Len: 0x%04X", OptionsLen
);
495 /* Only look at the channel configuration options if a valid channel entry for the local channel number was found */
496 if (ChannelData
!= NULL
)
498 /* Iterate through each option in the configuration request to look for ones which can be processed */
499 uint8_t OptionPos
= 0;
500 while (OptionPos
< OptionsLen
)
502 BT_Config_Option_Header_t
* OptionHeader
= (BT_Config_Option_Header_t
*)&Options
[OptionPos
];
503 void* OptionData
= &Options
[OptionPos
+ sizeof(BT_Config_Option_Header_t
)];
505 BT_ACL_DEBUG(2, "-- Option Type: 0x%04X", OptionHeader
->Type
);
506 BT_ACL_DEBUG(2, "-- Option Length: 0x%04X", (sizeof(BT_Config_Option_Header_t
) + OptionHeader
->Length
));
508 /* Store the remote MTU option's value if present */
509 if (OptionHeader
->Type
== BT_CONFIG_OPTION_MTU
)
510 ChannelData
->RemoteMTU
= *((uint16_t*)OptionData
);
512 /* Progress to the next option in the packet */
513 OptionPos
+= (sizeof(BT_Config_Option_Header_t
) + OptionHeader
->Length
);
519 BT_Signal_Header_t SignalCommandHeader
;
520 BT_Signal_ConfigurationResp_t ConfigurationResponse
;
523 /* Fill out the Signal Command header in the response packet */
524 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_CONFIGURATION_RESPONSE
;
525 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
526 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.ConfigurationResponse
);
528 /* Fill out the Configuration Response in the response packet */
529 ResponsePacket
.ConfigurationResponse
.SourceChannel
= ChannelData
->RemoteNumber
;
530 ResponsePacket
.ConfigurationResponse
.Flags
= 0x00;
531 ResponsePacket
.ConfigurationResponse
.Result
= (ChannelData
!= NULL
) ? BT_CONFIGURATION_SUCCESSFUL
: BT_CONFIGURATION_REJECTED
;
533 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
535 if (ChannelData
!= NULL
)
537 switch (ChannelData
->State
)
539 case Channel_Config_WaitConfig
:
540 ChannelData
->State
= Channel_Config_WaitSendConfig
;
542 case Channel_Config_WaitReqResp
:
543 ChannelData
->State
= Channel_Config_WaitResp
;
545 case Channel_Config_WaitReq
:
546 ChannelData
->State
= Channel_Open
;
551 BT_ACL_DEBUG(1, ">> L2CAP Configuration Response");
552 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.ConfigurationResponse
.SourceChannel
);
553 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.ConfigurationResponse
.Result
);
556 /** Internal Bluetooth stack Signal Command processing routine for a Configuration Response command.
558 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
560 static inline void Bluetooth_Signal_ConfigurationResp(const BT_Signal_Header_t
* const SignalCommandHeader
)
562 BT_Signal_ConfigurationResp_t ConfigurationResponse
;
564 Pipe_Read_Stream_LE(&ConfigurationResponse
, sizeof(ConfigurationResponse
));
569 BT_ACL_DEBUG(1, "<< L2CAP Configuration Response");
570 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConfigurationResponse
.SourceChannel
);
571 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse
.Result
);
573 /* Search for the referenced channel in the channel information list */
574 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(ConfigurationResponse
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
576 /* Only update the channel's state if it was found in the channel list */
577 if (ChannelData
!= NULL
)
579 /* Check if the channel configuration completed successfuly */
580 if (ConfigurationResponse
.Result
== BT_CONFIGURATION_SUCCESSFUL
)
582 switch (ChannelData
->State
)
584 case Channel_Config_WaitReqResp
:
585 ChannelData
->State
= Channel_Config_WaitReq
;
587 case Channel_Config_WaitResp
:
588 ChannelData
->State
= Channel_Open
;
594 /* Configuration failed - close the channel */
595 ChannelData
->State
= Channel_Closed
;
600 /** Internal Bluetooth stack Signal Command processing routine for a Disconnection Request command.
602 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
604 static inline void Bluetooth_Signal_DisconnectionReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
606 BT_Signal_DisconnectionReq_t DisconnectionRequest
;
608 Pipe_Read_Stream_LE(&DisconnectionRequest
, sizeof(DisconnectionRequest
));
610 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Request");
611 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionRequest
.DestinationChannel
);
612 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionRequest
.SourceChannel
);
617 /* Search for the referenced channel in the channel information list */
618 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(DisconnectionRequest
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
622 BT_Signal_Header_t SignalCommandHeader
;
623 BT_Signal_DisconnectionResp_t DisconnectionResponse
;
626 /* Fill out the Signal Command header in the response packet */
627 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_DISCONNECTION_RESPONSE
;
628 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
629 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.DisconnectionResponse
);
631 /* Fill out the Disconnection Response in the response packet */
632 ResponsePacket
.DisconnectionResponse
.DestinationChannel
= ChannelData
->RemoteNumber
;
633 ResponsePacket
.DisconnectionResponse
.SourceChannel
= ChannelData
->LocalNumber
;
635 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
637 /* If the channel was found in the channel list, close it */
638 if (ChannelData
!= NULL
)
639 ChannelData
->State
= Channel_Closed
;
641 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Response");
642 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.SourceChannel
);
643 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket
.DisconnectionResponse
.DestinationChannel
);
646 /** Internal Bluetooth stack Signal Command processing routine for a Disconnection Response command.
648 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
650 static inline void Bluetooth_Signal_DisconnectionResp(const BT_Signal_Header_t
* const SignalCommandHeader
)
652 BT_Signal_DisconnectionResp_t DisconnectionResponse
;
654 Pipe_Read_Stream_LE(&DisconnectionResponse
, sizeof(DisconnectionResponse
));
656 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Response");
657 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionResponse
.DestinationChannel
);
658 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionResponse
.SourceChannel
);
663 /* Search for the referenced channel in the channel information list */
664 Bluetooth_Channel_t
* ChannelData
= Bluetooth_GetChannelData(DisconnectionResponse
.SourceChannel
, CHANNEL_SEARCH_REMOTENUMBER
);
666 /* If the channel was found in the channel list, close it */
667 if (ChannelData
!= NULL
)
668 ChannelData
->State
= Channel_Closed
;
671 /** Internal Bluetooth stack Signal Command processing routine for an Echo Request command.
673 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
675 static inline void Bluetooth_Signal_EchoReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
677 BT_ACL_DEBUG(1, "<< L2CAP Echo Request");
684 BT_Signal_Header_t SignalCommandHeader
;
687 /* Fill out the Signal Command header in the response packet */
688 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_ECHO_RESPONSE
;
689 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
690 ResponsePacket
.SignalCommandHeader
.Length
= 0;
692 Bluetooth_SendPacket(&ResponsePacket
, sizeof(ResponsePacket
), NULL
);
694 BT_ACL_DEBUG(1, ">> L2CAP Echo Response");
697 /** Internal Bluetooth stack Signal Command processing routine for an Information Request command.
699 * \param[in] SignalCommandHeader Pointer to the start of the received packet's Signal Command header
701 static inline void Bluetooth_Signal_InformationReq(const BT_Signal_Header_t
* const SignalCommandHeader
)
703 BT_Signal_InformationReq_t InformationRequest
;
705 Pipe_Read_Stream_LE(&InformationRequest
, sizeof(InformationRequest
));
707 BT_ACL_DEBUG(1, "<< L2CAP Information Request");
708 BT_ACL_DEBUG(2, "-- Info Type: 0x%04X", InformationRequest
.InfoType
);
715 BT_Signal_Header_t SignalCommandHeader
;
716 BT_Signal_InformationResp_t InformationResponse
;
723 /* Retrieve the requested information and store it in the outgoing packet, if found */
724 switch (InformationRequest
.InfoType
)
727 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_SUCCESSFUL
;
730 *((uint16_t*)&ResponsePacket
.Data
) = MAXIMUM_CHANNEL_MTU
;
732 case BT_INFOREQ_EXTENDEDFEATURES
:
733 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_SUCCESSFUL
;
736 *((uint32_t*)&ResponsePacket
.Data
) = 0;
739 ResponsePacket
.InformationResponse
.Result
= BT_INFORMATION_NOTSUPPORTED
;
744 /* Fill out the Signal Command header in the response packet */
745 ResponsePacket
.SignalCommandHeader
.Code
= BT_SIGNAL_INFORMATION_RESPONSE
;
746 ResponsePacket
.SignalCommandHeader
.Identifier
= SignalCommandHeader
->Identifier
;
747 ResponsePacket
.SignalCommandHeader
.Length
= sizeof(ResponsePacket
.InformationResponse
) + DataLen
;
749 /* Fill out the Information Response in the response packet */
750 ResponsePacket
.InformationResponse
.InfoType
= InformationRequest
.InfoType
;
752 Bluetooth_SendPacket(&ResponsePacket
, (sizeof(ResponsePacket
) - sizeof(ResponsePacket
.Data
) + DataLen
), NULL
);
754 BT_ACL_DEBUG(1, ">> L2CAP Information Response");
755 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket
.InformationResponse
.Result
);