449d57fb2a7e4b6be0a9ddb60ff32a4197d2a7cc
[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 case BT_SIGNAL_COMMAND_REJECT:
145 BT_ACL_DEBUG(1, "<< Command Reject", NULL);
146
147 uint16_t RejectReason;
148 Pipe_Read_Stream_LE(&RejectReason, sizeof(RejectReason));
149 Pipe_Discard_Stream(ACLPacketHeader.DataLength - sizeof(RejectReason));
150 Pipe_ClearIN();
151 Pipe_Freeze();
152
153 BT_ACL_DEBUG(2, "-- Reason: %d", RejectReason);
154 break;
155 default:
156 BT_ACL_DEBUG(1, "<< Unknown Signaling Command 0x%02X", SignalCommandHeader.Code);
157
158 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
159 Pipe_ClearIN();
160 Pipe_Freeze();
161 break;
162 }
163 }
164 else
165 {
166 Bluetooth_PacketReceived(&DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, false));
167
168 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
169 Pipe_Discard_Stream(DataHeader.PayloadLength);
170 Pipe_ClearIN();
171 Pipe_Freeze();
172 }
173 }
174
175 uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel)
176 {
177 BT_ACL_Header_t ACLPacketHeader;
178 BT_DataPacket_Header_t DataHeader;
179
180 if (!(Bluetooth_Connection.IsConnected))
181 return BT_SENDPACKET_NotConnected;
182
183 if ((Channel != NULL) && (Channel->State != Channel_Open))
184 return BT_SENDPACKET_ChannelNotOpen;
185
186 // TODO: Add packet fragmentation here after retrieving the device's signal channel MTU
187
188 ACLPacketHeader.ConnectionHandle = (Bluetooth_Connection.ConnectionHandle | BT_ACL_FIRST_AUTOFLUSH);
189 ACLPacketHeader.DataLength = sizeof(DataHeader) + DataLen;
190 DataHeader.PayloadLength = DataLen;
191 DataHeader.DestinationChannel = (Channel == NULL) ? BT_CHANNEL_SIGNALING : Channel->RemoteNumber;
192
193 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
194 Pipe_Unfreeze();
195
196 Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
197 Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
198 Pipe_Write_Stream_LE(Data, DataLen);
199 Pipe_ClearOUT();
200
201 Pipe_Freeze();
202
203 BT_ACL_DEBUG(2, "", NULL);
204 BT_ACL_DEBUG(2, "Packet Sent", NULL);
205 BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
206 BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
207 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
208 BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader.PayloadLength);
209
210 return BT_SENDPACKET_NoError;
211 }
212
213 Bluetooth_Channel_t* Bluetooth_OpenChannel(uint16_t PSM)
214 {
215 Bluetooth_Channel_t* ChannelData = NULL;
216
217 for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
218 {
219 if (Bluetooth_Connection.Channels[i].State == Channel_Closed)
220 {
221 ChannelData = &Bluetooth_Connection.Channels[i];
222 ChannelData->LocalNumber = (BT_CHANNELNUMBER_BASEOFFSET + i);
223 break;
224 }
225 }
226
227 if (ChannelData == NULL)
228 return NULL;
229
230 ChannelData->RemoteNumber = 0;
231 ChannelData->PSM = PSM;
232 ChannelData->LocalMTU = MAXIMUM_CHANNEL_MTU;
233 ChannelData->State = Channel_Config_WaitConfig;
234
235 struct
236 {
237 BT_Signal_Header_t SignalCommandHeader;
238 BT_Signal_ConnectionReq_t ConnectionRequest;
239 } PacketData;
240
241 PacketData.SignalCommandHeader.Code = BT_SIGNAL_CONNECTION_REQUEST;
242 PacketData.SignalCommandHeader.Identifier = ++Bluetooth_Connection.SignallingIdentifier;
243 PacketData.SignalCommandHeader.Length = sizeof(PacketData.ConnectionRequest);
244 PacketData.ConnectionRequest.PSM = PSM;
245 PacketData.ConnectionRequest.SourceChannel = ChannelData->LocalNumber;
246
247 Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);
248
249 BT_ACL_DEBUG(1, ">> L2CAP Connection Request", NULL);
250 BT_ACL_DEBUG(2, "-- PSM 0x%04X", PacketData.ConnectionRequest.PSM);
251 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.ConnectionRequest.SourceChannel);
252
253 return ChannelData;
254 }
255
256 void Bluetooth_CloseChannel(Bluetooth_Channel_t* Channel)
257 {
258 if ((Channel == NULL) || (Channel->State == Channel_Closed))
259 return;
260
261 Channel->State = Channel_WaitDisconnect;
262
263 struct
264 {
265 BT_Signal_Header_t SignalCommandHeader;
266 BT_Signal_DisconnectionReq_t DisconnectionRequest;
267 } PacketData;
268
269 PacketData.SignalCommandHeader.Code = BT_SIGNAL_DISCONNECTION_REQUEST;
270 PacketData.SignalCommandHeader.Identifier = ++Bluetooth_Connection.SignallingIdentifier;
271 PacketData.SignalCommandHeader.Length = sizeof(PacketData.DisconnectionRequest);
272 PacketData.DisconnectionRequest.DestinationChannel = Channel->RemoteNumber;
273 PacketData.DisconnectionRequest.SourceChannel = Channel->LocalNumber;
274
275 Bluetooth_SendPacket(&PacketData, sizeof(PacketData), NULL);
276
277 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Request", NULL);
278 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", PacketData.DisconnectionRequest.DestinationChannel);
279 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", PacketData.DisconnectionRequest.SourceChannel);
280 }
281
282 static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t* ACLPacketHeader,
283 BT_DataPacket_Header_t* DataHeader,
284 BT_Signal_Header_t* SignalCommandHeader)
285 {
286 BT_Signal_ConnectionReq_t ConnectionRequest;
287
288 Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));
289
290 Pipe_ClearIN();
291 Pipe_Freeze();
292
293 BT_ACL_DEBUG(1, "<< L2CAP Connection Request", NULL);
294 BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest.PSM);
295 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
296
297 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, true);
298
299 if (ChannelData == NULL)
300 {
301 for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
302 {
303 if (Bluetooth_Connection.Channels[i].State == Channel_Closed)
304 {
305 ChannelData = &Bluetooth_Connection.Channels[i];
306 ChannelData->LocalNumber = (BT_CHANNELNUMBER_BASEOFFSET + i);
307 break;
308 }
309 }
310 }
311
312 if (ChannelData != NULL)
313 {
314 ChannelData->RemoteNumber = ConnectionRequest.SourceChannel;
315 ChannelData->PSM = ConnectionRequest.PSM;
316 ChannelData->LocalMTU = MAXIMUM_CHANNEL_MTU;
317 ChannelData->State = Channel_Config_WaitConfig;
318 }
319
320 struct
321 {
322 BT_Signal_Header_t SignalCommandHeader;
323 BT_Signal_ConnectionResp_t ConnectionResponse;
324 } ResponsePacket;
325
326 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_CONNECTION_RESPONSE;
327 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
328 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.ConnectionResponse);
329 ResponsePacket.ConnectionResponse.DestinationChannel = ChannelData->LocalNumber;
330 ResponsePacket.ConnectionResponse.SourceChannel = ChannelData->RemoteNumber;
331 ResponsePacket.ConnectionResponse.Result = (ChannelData == NULL) ? BT_CONNECTION_REFUSED_RESOURCES :
332 BT_CONNECTION_SUCCESSFUL;
333 ResponsePacket.ConnectionResponse.Status = 0x00;
334
335 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
336
337 BT_ACL_DEBUG(1, ">> L2CAP Connection Response", NULL);
338 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.ConnectionResponse.Result);
339 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.ConnectionResponse.DestinationChannel);
340 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConnectionResponse.SourceChannel);
341 }
342
343 static inline void Bluetooth_Signal_ConnectionResp(BT_ACL_Header_t* ACLPacketHeader,
344 BT_DataPacket_Header_t* DataHeader,
345 BT_Signal_Header_t* SignalCommandHeader)
346 {
347 BT_Signal_ConnectionResp_t ConnectionResponse;
348
349 Pipe_Read_Stream_LE(&ConnectionResponse, sizeof(ConnectionResponse));
350
351 Pipe_ClearIN();
352 Pipe_Freeze();
353
354 BT_ACL_DEBUG(1, "<< L2CAP Connection Response", NULL);
355 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConnectionResponse.Result);
356 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);
357 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
358
359 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.DestinationChannel, false);
360
361 if (ChannelData != NULL)
362 {
363 ChannelData->RemoteNumber = ConnectionResponse.SourceChannel;
364 ChannelData->State = (ConnectionResponse.Result == BT_CONNECTION_SUCCESSFUL) ?
365 Channel_Config_WaitConfig : Channel_Closed;
366 }
367 }
368
369
370 static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t* ACLPacketHeader,
371 BT_DataPacket_Header_t* DataHeader,
372 BT_Signal_Header_t* SignalCommandHeader)
373 {
374 BT_Signal_ConfigurationReq_t ConfigurationRequest;
375 uint8_t OptionsLen = (SignalCommandHeader->Length - sizeof(ConfigurationRequest));
376 uint8_t Options[OptionsLen];
377
378 Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
379 Pipe_Read_Stream_LE(&Options, sizeof(Options));
380
381 Pipe_ClearIN();
382 Pipe_Freeze();
383
384 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
385
386 BT_ACL_DEBUG(1, "<< L2CAP Configuration Request", NULL);
387 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
388 BT_ACL_DEBUG(2, "-- Remote MTU: 0x%04X", ChannelData->RemoteMTU);
389 BT_ACL_DEBUG(2, "-- Options Len: 0x%04X", OptionsLen);
390
391 uint8_t OptionPos = 0;
392 while (OptionPos < OptionsLen)
393 {
394 BT_Config_Option_Header_t* OptionHeader = (BT_Config_Option_Header_t*)&Options[OptionPos];
395
396 BT_ACL_DEBUG(2, "-- Option Type: 0x%04X", OptionHeader->Type);
397 BT_ACL_DEBUG(2, "-- Option Length: 0x%04X", (sizeof(*OptionHeader) + OptionHeader->Length));
398
399 if ((OptionHeader->Type == BT_CONFIG_OPTION_MTU) && (ChannelData != NULL))
400 ChannelData->RemoteMTU = *((uint16_t*)&Options[OptionPos + sizeof(*OptionHeader)]);
401
402 OptionPos += (sizeof(*OptionHeader) + OptionHeader->Length);
403 }
404
405 struct
406 {
407 BT_Signal_Header_t SignalCommandHeader;
408 BT_Signal_ConfigurationResp_t ConfigurationResponse;
409 } ResponsePacket;
410
411 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_CONFIGURATION_RESPONSE;
412 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
413 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.ConfigurationResponse);
414 ResponsePacket.ConfigurationResponse.SourceChannel = ChannelData->RemoteNumber;
415 ResponsePacket.ConfigurationResponse.Flags = 0x00;
416 ResponsePacket.ConfigurationResponse.Result = (ChannelData != NULL) ? BT_CONFIGURATION_SUCCESSFUL : BT_CONFIGURATION_REJECTED;
417
418 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
419
420 if (ChannelData != NULL)
421 {
422 switch (ChannelData->State)
423 {
424 case Channel_Config_WaitConfig:
425 ChannelData->State = Channel_Config_WaitSendConfig;
426 break;
427 case Channel_Config_WaitReqResp:
428 ChannelData->State = Channel_Config_WaitResp;
429 break;
430 case Channel_Config_WaitReq:
431 ChannelData->State = Channel_Open;
432 break;
433 }
434 }
435
436 BT_ACL_DEBUG(1, ">> L2CAP Configuration Response", NULL);
437 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConfigurationResponse.SourceChannel);
438 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.ConfigurationResponse.Result);
439 }
440
441 static inline void Bluetooth_Signal_ConfigurationResp(BT_ACL_Header_t* ACLPacketHeader,
442 BT_DataPacket_Header_t* DataHeader,
443 BT_Signal_Header_t* SignalCommandHeader)
444 {
445 BT_Signal_ConfigurationResp_t ConfigurationResponse;
446
447 Pipe_Read_Stream_LE(&ConfigurationResponse, sizeof(ConfigurationResponse));
448
449 Pipe_ClearIN();
450 Pipe_Freeze();
451
452 BT_ACL_DEBUG(1, "<< L2CAP Configuration Response", NULL);
453 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConfigurationResponse.SourceChannel);
454 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse.Result);
455
456 if (ConfigurationResponse.Result == BT_CONFIGURATION_SUCCESSFUL)
457 {
458 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, true);
459
460 if (ChannelData != NULL)
461 {
462 switch (ChannelData->State)
463 {
464 case Channel_Config_WaitReqResp:
465 ChannelData->State = Channel_Config_WaitReq;
466 break;
467 case Channel_Config_WaitResp:
468 ChannelData->State = Channel_Open;
469 break;
470 }
471 }
472 }
473 }
474
475 static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t* ACLPacketHeader,
476 BT_DataPacket_Header_t* DataHeader,
477 BT_Signal_Header_t* SignalCommandHeader)
478 {
479 BT_Signal_DisconnectionReq_t DisconnectionRequest;
480
481 Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest));
482
483 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Request", NULL);
484 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel);
485 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel);
486
487 Pipe_ClearIN();
488 Pipe_Freeze();
489
490 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);
491
492 struct
493 {
494 BT_Signal_Header_t SignalCommandHeader;
495 BT_Signal_DisconnectionResp_t DisconnectionResponse;
496 } ResponsePacket;
497
498 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_DISCONNECTION_RESPONSE;
499 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
500 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.DisconnectionResponse);
501 ResponsePacket.DisconnectionResponse.DestinationChannel = ChannelData->RemoteNumber;
502 ResponsePacket.DisconnectionResponse.SourceChannel = ChannelData->LocalNumber;
503
504 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
505
506 if (ChannelData != NULL)
507 ChannelData->State = Channel_Closed;
508
509 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Response", NULL);
510 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.DisconnectionResponse.SourceChannel);
511 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.DisconnectionResponse.DestinationChannel);
512 }
513
514 static inline void Bluetooth_Signal_DisconnectionResp(BT_ACL_Header_t* ACLPacketHeader,
515 BT_DataPacket_Header_t* DataHeader,
516 BT_Signal_Header_t* SignalCommandHeader)
517 {
518 BT_Signal_DisconnectionResp_t DisconnectionResponse;
519
520 Pipe_Read_Stream_LE(&DisconnectionResponse, sizeof(DisconnectionResponse));
521
522 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Response", NULL);
523 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel);
524 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel);
525
526 Pipe_ClearIN();
527 Pipe_Freeze();
528
529 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, true);
530
531 if (ChannelData->State == Channel_WaitDisconnect)
532 ChannelData->State = Channel_Closed;
533 }
534
535 static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
536 BT_DataPacket_Header_t* DataHeader,
537 BT_Signal_Header_t* SignalCommandHeader)
538 {
539 BT_ACL_DEBUG(1, "<< L2CAP Echo Request", NULL);
540
541 Pipe_ClearIN();
542 Pipe_Freeze();
543
544 struct
545 {
546 BT_Signal_Header_t SignalCommandHeader;
547 } ResponsePacket;
548
549 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_ECHO_RESPONSE;
550 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
551 ResponsePacket.SignalCommandHeader.Length = 0;
552
553 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
554
555 BT_ACL_DEBUG(1, ">> L2CAP Echo Response", NULL);
556 }
557
558 static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t* ACLPacketHeader,
559 BT_DataPacket_Header_t* DataHeader,
560 BT_Signal_Header_t* SignalCommandHeader)
561 {
562 BT_Signal_InformationReq_t InformationRequest;
563
564 Pipe_Read_Stream_LE(&InformationRequest, sizeof(InformationRequest));
565
566 BT_ACL_DEBUG(1, "<< L2CAP Information Request", NULL);
567 BT_ACL_DEBUG(2, "-- Info Type: 0x%04X", InformationRequest.InfoType);
568
569 Pipe_ClearIN();
570 Pipe_Freeze();
571
572 struct
573 {
574 BT_Signal_Header_t SignalCommandHeader;
575 BT_Signal_InformationResp_t InformationResponse;
576
577 uint8_t Data[4];
578 } ResponsePacket;
579
580 uint8_t DataLen = 0;
581
582 switch (InformationRequest.InfoType)
583 {
584 case BT_INFOREQ_MTU:
585 ResponsePacket.InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
586 DataLen = 2;
587
588 *((uint16_t*)&ResponsePacket.Data) = MAXIMUM_CHANNEL_MTU;
589 break;
590 case BT_INFOREQ_EXTENDEDFEATURES:
591 ResponsePacket.InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
592 DataLen = 4;
593
594 *((uint32_t*)&ResponsePacket.Data) = 0;
595 break;
596 default:
597 ResponsePacket.InformationResponse.Result = BT_INFORMATION_NOTSUPPORTED;
598 DataLen = 0;
599 break;
600 }
601
602 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_INFORMATION_RESPONSE;
603 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
604 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.InformationResponse) + DataLen;
605
606 Bluetooth_SendPacket(&ResponsePacket, (sizeof(ResponsePacket) - sizeof(ResponsePacket.Data) + DataLen), NULL);
607
608 BT_ACL_DEBUG(1, ">> L2CAP Information Response", NULL);
609 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.InformationResponse.Result);
610 }