Add HCI debugging with verbosity control to the BluetoothHost demo.
[pub/USBasp.git] / Demos / Host / Incomplete / BluetoothHost / Lib / BluetoothACLPackets.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2010.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
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.
20
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
28 this software.
29 */
30
31 #define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C
32 #include "BluetoothACLPackets.h"
33
34 void Bluetooth_ACLTask(void)
35 {
36 Bluetooth_ProcessACLPackets();
37
38 for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
39 {
40 Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
41
42 bool MustSendConfigReq = true;
43
44 switch (ChannelData->State)
45 {
46 case Channel_Config_WaitConfig:
47 ChannelData->State = Channel_Config_WaitReqResp;
48 break;
49 case Channel_Config_WaitSendConfig:
50 ChannelData->State = Channel_Config_WaitResp;
51 break;
52 default:
53 MustSendConfigReq = false;
54 break;
55 }
56
57 if (MustSendConfigReq)
58 {
59 struct
60 {
61 BT_Signal_Header_t SignalCommandHeader;
62 BT_Signal_ConfigurationReq_t ConfigurationRequest;
63
64 struct
65 {
66 BT_Config_Option_Header_t Header;
67 uint16_t Value;
68 } Option_LocalMTU;
69 } PacketData;
70
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;
80
81 Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);
82
83 BT_ACL_DEBUG(1, ">> L2CAP Configuration Request", NULL);
84 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData.ConfigurationRequest.DestinationChannel);
85 }
86 }
87 }
88
89 static void Bluetooth_ProcessACLPackets(void)
90 {
91 BT_ACL_Header_t ACLPacketHeader;
92 BT_DataPacket_Header_t DataHeader;
93
94 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
95 Pipe_Unfreeze();
96
97 if (!(Pipe_IsReadWriteAllowed()))
98 {
99 Pipe_Freeze();
100 return;
101 }
102
103 Pipe_Read_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
104 Pipe_Read_Stream_LE(&DataHeader, sizeof(DataHeader));
105
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);
112
113 if (DataHeader.DestinationChannel == BT_CHANNEL_SIGNALING)
114 {
115 BT_Signal_Header_t SignalCommandHeader;
116 Pipe_Read_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader));
117
118 switch (SignalCommandHeader.Code)
119 {
120 case BT_SIGNAL_CONNECTION_REQUEST:
121 Bluetooth_Signal_ConnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
122 break;
123 case BT_SIGNAL_CONNECTION_RESPONSE:
124 Bluetooth_Signal_ConnectionResp(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
125 break;
126 case BT_SIGNAL_CONFIGURATION_REQUEST:
127 Bluetooth_Signal_ConfigurationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
128 break;
129 case BT_SIGNAL_CONFIGURATION_RESPONSE:
130 Bluetooth_Signal_ConfigurationResp(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
131 break;
132 case BT_SIGNAL_DISCONNECTION_REQUEST:
133 Bluetooth_Signal_DisconnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
134 break;
135 case BT_SIGNAL_DISCONNECTION_RESPONSE:
136 Bluetooth_Signal_DisconnectionResp(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
137 break;
138 case BT_SIGNAL_ECHO_REQUEST:
139 Bluetooth_Signal_EchoReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
140 break;
141 case BT_SIGNAL_INFORMATION_REQUEST:
142 Bluetooth_Signal_InformationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
143 break;
144 default:
145 BT_ACL_DEBUG(1, "<< Unknown Signaling Command 0x%02X", SignalCommandHeader.Code);
146
147 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
148 Pipe_ClearIN();
149 Pipe_Freeze();
150 break;
151 }
152 }
153 else
154 {
155 Bluetooth_PacketReceived(&DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, false));
156
157 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
158 Pipe_Discard_Stream(DataHeader.PayloadLength);
159 Pipe_ClearIN();
160 Pipe_Freeze();
161 }
162 }
163
164 uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel)
165 {
166 BT_ACL_Header_t ACLPacketHeader;
167 BT_DataPacket_Header_t DataHeader;
168
169 if (!(Bluetooth_Connection.IsConnected))
170 return BT_SENDPACKET_NotConnected;
171
172 if ((Channel != NULL) && (Channel->State != Channel_Open))
173 return BT_SENDPACKET_ChannelNotOpen;
174
175 // TODO: Add packet fragmentation here after retrieving the device's signal channel MTU
176
177 ACLPacketHeader.ConnectionHandle = (Bluetooth_Connection.ConnectionHandle | BT_ACL_FIRST_AUTOFLUSH);
178 ACLPacketHeader.DataLength = sizeof(DataHeader) + DataLen;
179 DataHeader.PayloadLength = DataLen;
180 DataHeader.DestinationChannel = (Channel == NULL) ? BT_CHANNEL_SIGNALING : Channel->RemoteNumber;
181
182 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
183 Pipe_Unfreeze();
184
185 Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
186 Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
187 Pipe_Write_Stream_LE(Data, DataLen);
188 Pipe_ClearOUT();
189
190 Pipe_Freeze();
191
192 BT_ACL_DEBUG(2, "", NULL);
193 BT_ACL_DEBUG(2, "Packet Sent", NULL);
194 BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
195 BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
196 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
197 BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader.PayloadLength);
198
199 return BT_SENDPACKET_NoError;
200 }
201
202 Bluetooth_Channel_t* Bluetooth_OpenChannel(uint16_t PSM)
203 {
204 Bluetooth_Channel_t* ChannelData = NULL;
205
206 for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
207 {
208 if (Bluetooth_Connection.Channels[i].State == Channel_Closed)
209 {
210 ChannelData = &Bluetooth_Connection.Channels[i];
211 ChannelData->LocalNumber = (BT_CHANNELNUMBER_BASEOFFSET + i);
212 break;
213 }
214 }
215
216 if (ChannelData == NULL)
217 return NULL;
218
219 ChannelData->RemoteNumber = 0;
220 ChannelData->PSM = PSM;
221 ChannelData->LocalMTU = MAXIMUM_CHANNEL_MTU;
222 ChannelData->State = Channel_Config_WaitConfig;
223
224 struct
225 {
226 BT_Signal_Header_t SignalCommandHeader;
227 BT_Signal_ConnectionReq_t ConnectionRequest;
228 } PacketData;
229
230 PacketData.SignalCommandHeader.Code = BT_SIGNAL_CONNECTION_REQUEST;
231 PacketData.SignalCommandHeader.Identifier = ++Bluetooth_Connection.SignallingIdentifier;
232 PacketData.SignalCommandHeader.Length = sizeof(PacketData.ConnectionRequest);
233 PacketData.ConnectionRequest.PSM = PSM;
234 PacketData.ConnectionRequest.SourceChannel = ChannelData->LocalNumber;
235
236 Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);
237
238 BT_ACL_DEBUG(1, ">> L2CAP Connection Request", NULL);
239 BT_ACL_DEBUG(2, "-- PSM 0x%04X", PacketData.ConnectionRequest.PSM);
240 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.ConnectionRequest.SourceChannel);
241
242 return ChannelData;
243 }
244
245 void Bluetooth_CloseChannel(Bluetooth_Channel_t* Channel)
246 {
247 if ((Channel == NULL) || (Channel->State == Channel_Closed))
248 return;
249
250 Channel->State = Channel_WaitDisconnect;
251
252 struct
253 {
254 BT_Signal_Header_t SignalCommandHeader;
255 BT_Signal_DisconnectionReq_t DisconnectionRequest;
256 } PacketData;
257
258 PacketData.SignalCommandHeader.Code = BT_SIGNAL_DISCONNECTION_REQUEST;
259 PacketData.SignalCommandHeader.Identifier = ++Bluetooth_Connection.SignallingIdentifier;
260 PacketData.SignalCommandHeader.Length = sizeof(PacketData.DisconnectionRequest);
261 PacketData.DisconnectionRequest.DestinationChannel = Channel->RemoteNumber;
262 PacketData.DisconnectionRequest.SourceChannel = Channel->LocalNumber;
263
264 Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);
265
266 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Request", NULL);
267 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData.DisconnectionRequest.DestinationChannel);
268 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.DisconnectionRequest.SourceChannel);
269 }
270
271 static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t* ACLPacketHeader,
272 BT_DataPacket_Header_t* DataHeader,
273 BT_Signal_Header_t* SignalCommandHeader)
274 {
275 BT_Signal_ConnectionReq_t ConnectionRequest;
276
277 Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));
278
279 Pipe_ClearIN();
280 Pipe_Freeze();
281
282 BT_ACL_DEBUG(1, "<< L2CAP Connection Request", NULL);
283 BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest.PSM);
284 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
285
286 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, true);
287
288 if (ChannelData == NULL)
289 {
290 for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
291 {
292 if (Bluetooth_Connection.Channels[i].State == Channel_Closed)
293 {
294 ChannelData = &Bluetooth_Connection.Channels[i];
295 ChannelData->LocalNumber = (BT_CHANNELNUMBER_BASEOFFSET + i);
296 break;
297 }
298 }
299 }
300
301 if (ChannelData != NULL)
302 {
303 ChannelData->RemoteNumber = ConnectionRequest.SourceChannel;
304 ChannelData->PSM = ConnectionRequest.PSM;
305 ChannelData->LocalMTU = MAXIMUM_CHANNEL_MTU;
306 ChannelData->State = Channel_Config_WaitConfig;
307 }
308
309 struct
310 {
311 BT_Signal_Header_t SignalCommandHeader;
312 BT_Signal_ConnectionResp_t ConnectionResponse;
313 } ResponsePacket;
314
315 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_CONNECTION_RESPONSE;
316 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
317 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.ConnectionResponse);
318 ResponsePacket.ConnectionResponse.Result = (ChannelData == NULL) ? BT_CONNECTION_REFUSED_RESOURCES : BT_CONNECTION_SUCCESSFUL;
319 ResponsePacket.ConnectionResponse.DestinationChannel = ChannelData->RemoteNumber;
320 ResponsePacket.ConnectionResponse.SourceChannel = ChannelData->LocalNumber;
321 ResponsePacket.ConnectionResponse.Status = 0x00;
322
323 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
324
325 BT_ACL_DEBUG(1, ">> L2CAP Connection Response", NULL);
326 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.ConnectionResponse.Result);
327 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.ConnectionResponse.DestinationChannel);
328 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConnectionResponse.SourceChannel);
329 }
330
331 static inline void Bluetooth_Signal_ConnectionResp(BT_ACL_Header_t* ACLPacketHeader,
332 BT_DataPacket_Header_t* DataHeader,
333 BT_Signal_Header_t* SignalCommandHeader)
334 {
335 BT_Signal_ConnectionResp_t ConnectionResponse;
336
337 Pipe_Read_Stream_LE(&ConnectionResponse, sizeof(ConnectionResponse));
338
339 Pipe_ClearIN();
340 Pipe_Freeze();
341
342 BT_ACL_DEBUG(1, "<< L2CAP Connection Response", NULL);
343 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConnectionResponse.Result);
344 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);
345 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
346
347 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.DestinationChannel, false);
348
349 if (ChannelData != NULL)
350 {
351 ChannelData->RemoteNumber = ConnectionResponse.SourceChannel;
352 ChannelData->State = (ConnectionResponse.Result == BT_CONNECTION_SUCCESSFUL) ?
353 Channel_Config_WaitConfig : Channel_Closed;
354 }
355 }
356
357
358 static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t* ACLPacketHeader,
359 BT_DataPacket_Header_t* DataHeader,
360 BT_Signal_Header_t* SignalCommandHeader)
361 {
362 BT_Signal_ConfigurationReq_t ConfigurationRequest;
363 uint8_t OptionsLen = (SignalCommandHeader->Length - sizeof(ConfigurationRequest));
364 uint8_t Options[OptionsLen];
365
366 Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
367 Pipe_Read_Stream_LE(&Options, sizeof(Options));
368
369 Pipe_ClearIN();
370 Pipe_Freeze();
371
372 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
373
374 BT_ACL_DEBUG(1, "<< L2CAP Configuration Request", NULL);
375 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
376 BT_ACL_DEBUG(2, "-- Remote MTU: 0x%04X", ChannelData->RemoteMTU);
377 BT_ACL_DEBUG(2, "-- Options Len: 0x%04X", OptionsLen);
378
379 uint8_t OptionPos = 0;
380 while (OptionPos < OptionsLen)
381 {
382 BT_Config_Option_Header_t* OptionHeader = (BT_Config_Option_Header_t*)&Options[OptionPos];
383
384 BT_ACL_DEBUG(2, "-- Option Type: 0x%04X", OptionHeader->Type);
385 BT_ACL_DEBUG(2, "-- Option Length: 0x%04X", (sizeof(*OptionHeader) + OptionHeader->Length));
386
387 if ((OptionHeader->Type == BT_CONFIG_OPTION_MTU) && (ChannelData != NULL))
388 ChannelData->RemoteMTU = *((uint16_t*)&Options[OptionPos + sizeof(*OptionHeader)]);
389
390 OptionPos += (sizeof(*OptionHeader) + OptionHeader->Length);
391 }
392
393 struct
394 {
395 BT_Signal_Header_t SignalCommandHeader;
396 BT_Signal_ConfigurationResp_t ConfigurationResponse;
397 } ResponsePacket;
398
399 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_CONFIGURATION_RESPONSE;
400 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
401 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.ConfigurationResponse);
402 ResponsePacket.ConfigurationResponse.SourceChannel = ChannelData->RemoteNumber;
403 ResponsePacket.ConfigurationResponse.Flags = 0x00;
404 ResponsePacket.ConfigurationResponse.Result = (ChannelData != NULL) ? BT_CONFIGURATION_SUCCESSFUL : BT_CONFIGURATION_REJECTED;
405
406 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
407
408 if (ChannelData != NULL)
409 {
410 switch (ChannelData->State)
411 {
412 case Channel_Config_WaitConfig:
413 ChannelData->State = Channel_Config_WaitSendConfig;
414 break;
415 case Channel_Config_WaitReqResp:
416 ChannelData->State = Channel_Config_WaitResp;
417 break;
418 case Channel_Config_WaitReq:
419 ChannelData->State = Channel_Open;
420 break;
421 }
422 }
423
424 BT_ACL_DEBUG(1, ">> L2CAP Configuration Response", NULL);
425 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConfigurationResponse.SourceChannel);
426 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.ConfigurationResponse.Result);
427 }
428
429 static inline void Bluetooth_Signal_ConfigurationResp(BT_ACL_Header_t* ACLPacketHeader,
430 BT_DataPacket_Header_t* DataHeader,
431 BT_Signal_Header_t* SignalCommandHeader)
432 {
433 BT_Signal_ConfigurationResp_t ConfigurationResponse;
434
435 Pipe_Read_Stream_LE(&ConfigurationResponse, sizeof(ConfigurationResponse));
436
437 Pipe_ClearIN();
438 Pipe_Freeze();
439
440 BT_ACL_DEBUG(1, "<< L2CAP Configuration Response", NULL);
441 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConfigurationResponse.SourceChannel);
442 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse.Result);
443
444 if (ConfigurationResponse.Result == BT_CONFIGURATION_SUCCESSFUL)
445 {
446 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, true);
447
448 if (ChannelData != NULL)
449 {
450 switch (ChannelData->State)
451 {
452 case Channel_Config_WaitReqResp:
453 ChannelData->State = Channel_Config_WaitReq;
454 break;
455 case Channel_Config_WaitResp:
456 ChannelData->State = Channel_Open;
457 break;
458 }
459 }
460 }
461 }
462
463 static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t* ACLPacketHeader,
464 BT_DataPacket_Header_t* DataHeader,
465 BT_Signal_Header_t* SignalCommandHeader)
466 {
467 BT_Signal_DisconnectionReq_t DisconnectionRequest;
468
469 Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest));
470
471 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Request", NULL);
472 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel);
473 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel);
474
475 Pipe_ClearIN();
476 Pipe_Freeze();
477
478 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);
479
480 struct
481 {
482 BT_Signal_Header_t SignalCommandHeader;
483 BT_Signal_DisconnectionResp_t DisconnectionResponse;
484 } ResponsePacket;
485
486 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_DISCONNECTION_RESPONSE;
487 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
488 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.DisconnectionResponse);
489 ResponsePacket.DisconnectionResponse.DestinationChannel = ChannelData->RemoteNumber;
490 ResponsePacket.DisconnectionResponse.SourceChannel = ChannelData->LocalNumber;
491
492 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
493
494 if (ChannelData != NULL)
495 ChannelData->State = Channel_Closed;
496
497 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Response", NULL);
498 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.DisconnectionResponse.SourceChannel);
499 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.DisconnectionResponse.DestinationChannel);
500 }
501
502 static inline void Bluetooth_Signal_DisconnectionResp(BT_ACL_Header_t* ACLPacketHeader,
503 BT_DataPacket_Header_t* DataHeader,
504 BT_Signal_Header_t* SignalCommandHeader)
505 {
506 BT_Signal_DisconnectionResp_t DisconnectionResponse;
507
508 Pipe_Read_Stream_LE(&DisconnectionResponse, sizeof(DisconnectionResponse));
509
510 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Response", NULL);
511 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel);
512 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel);
513
514 Pipe_ClearIN();
515 Pipe_Freeze();
516
517 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, true);
518
519 if (ChannelData->State == Channel_WaitDisconnect)
520 ChannelData->State = Channel_Closed;
521 }
522
523 static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
524 BT_DataPacket_Header_t* DataHeader,
525 BT_Signal_Header_t* SignalCommandHeader)
526 {
527 BT_ACL_DEBUG(1, "<< L2CAP Echo Request", NULL);
528
529 Pipe_ClearIN();
530 Pipe_Freeze();
531
532 struct
533 {
534 BT_Signal_Header_t SignalCommandHeader;
535 } ResponsePacket;
536
537 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_ECHO_RESPONSE;
538 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
539 ResponsePacket.SignalCommandHeader.Length = 0;
540
541 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
542
543 BT_ACL_DEBUG(1, ">> L2CAP Echo Response", NULL);
544 }
545
546 static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t* ACLPacketHeader,
547 BT_DataPacket_Header_t* DataHeader,
548 BT_Signal_Header_t* SignalCommandHeader)
549 {
550 BT_Signal_InformationReq_t InformationRequest;
551
552 Pipe_Read_Stream_LE(&InformationRequest, sizeof(InformationRequest));
553
554 BT_ACL_DEBUG(1, "<< L2CAP Information Request", NULL);
555 BT_ACL_DEBUG(2, "-- Info Type: 0x%04X", InformationRequest.InfoType);
556
557 Pipe_ClearIN();
558 Pipe_Freeze();
559
560 struct
561 {
562 BT_Signal_Header_t SignalCommandHeader;
563 BT_Signal_InformationResp_t InformationResponse;
564
565 uint8_t Data[4];
566 } ResponsePacket;
567
568 uint8_t DataLen = 0;
569
570 switch (InformationRequest.InfoType)
571 {
572 case BT_INFOREQ_MTU:
573 ResponsePacket.InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
574 DataLen = 2;
575
576 *((uint16_t*)&ResponsePacket.Data) = MAXIMUM_CHANNEL_MTU;
577 break;
578 case BT_INFOREQ_EXTENDEDFEATURES:
579 ResponsePacket.InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
580 DataLen = 4;
581
582 *((uint32_t*)&ResponsePacket.Data) = 0;
583 break;
584 default:
585 ResponsePacket.InformationResponse.Result = BT_INFORMATION_NOTSUPPORTED;
586 DataLen = 0;
587 break;
588 }
589
590 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_INFORMATION_RESPONSE;
591 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
592 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.InformationResponse) + DataLen;
593
594 Bluetooth_SendPacket(&ResponsePacket, (sizeof(ResponsePacket) - sizeof(ResponsePacket.Data) + DataLen), NULL);
595
596 BT_ACL_DEBUG(1, ">> L2CAP Information Response", NULL);
597 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.InformationResponse.Result);
598 }