7c238e9a6ea8d69e5dfb522dc3ac3f3ffd688e0a
[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_CONFIGURATION_REQUEST:
124 Bluetooth_Signal_ConfigurationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
125 break;
126 case BT_SIGNAL_CONFIGURATION_RESPONSE:
127 Bluetooth_Signal_ConfigurationResp(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
128 break;
129 case BT_SIGNAL_DISCONNECTION_REQUEST:
130 Bluetooth_Signal_DisconnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
131 break;
132 case BT_SIGNAL_ECHO_REQUEST:
133 Bluetooth_Signal_EchoReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
134 break;
135 case BT_SIGNAL_INFORMATION_REQUEST:
136 Bluetooth_Signal_InformationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
137 break;
138 default:
139 BT_ACL_DEBUG(1, "<< Unknown Signaling Command 0x%02X", SignalCommandHeader.Code);
140
141 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
142 Pipe_ClearIN();
143 Pipe_Freeze();
144 break;
145 }
146 }
147 else
148 {
149 Bluetooth_PacketReceived(&DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, false));
150
151 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
152 Pipe_Discard_Stream(DataHeader.PayloadLength);
153 Pipe_ClearIN();
154 Pipe_Freeze();
155 }
156 }
157
158 uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel)
159 {
160 BT_ACL_Header_t ACLPacketHeader;
161 BT_DataPacket_Header_t DataHeader;
162
163 if (!(Bluetooth_Connection.IsConnected))
164 return BT_SENDPACKET_NotConnected;
165
166 if ((Channel != NULL) && (Channel->State != Channel_Open))
167 return BT_SENDPACKET_ChannelNotOpen;
168
169 // TODO: Add packet fragmentation here after retrieving the device's signal channel MTU
170
171 ACLPacketHeader.ConnectionHandle = (Bluetooth_Connection.ConnectionHandle | BT_ACL_FIRST_AUTOFLUSH);
172 ACLPacketHeader.DataLength = sizeof(DataHeader) + DataLen;
173 DataHeader.PayloadLength = DataLen;
174 DataHeader.DestinationChannel = (Channel == NULL) ? BT_CHANNEL_SIGNALING : Channel->RemoteNumber;
175
176 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
177 Pipe_Unfreeze();
178
179 Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
180 Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
181 Pipe_Write_Stream_LE(Data, DataLen);
182 Pipe_ClearOUT();
183
184 Pipe_Freeze();
185
186 BT_ACL_DEBUG(2, "", NULL);
187 BT_ACL_DEBUG(2, "Packet Sent", NULL);
188 BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
189 BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
190 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
191 BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader.PayloadLength);
192
193 return BT_SENDPACKET_NoError;
194 }
195
196 static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t* ACLPacketHeader,
197 BT_DataPacket_Header_t* DataHeader,
198 BT_Signal_Header_t* SignalCommandHeader)
199 {
200 BT_Signal_ConnectionReq_t ConnectionRequest;
201
202 Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));
203
204 Pipe_ClearIN();
205 Pipe_Freeze();
206
207 BT_ACL_DEBUG(1, "<< L2CAP Connection Request", NULL);
208 BT_ACL_DEBUG(2, "-- PSM: 0x%04X", ConnectionRequest.PSM);
209 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
210
211 Bluetooth_Channel_t* ChannelData = Bluetooth_InitChannelData(ConnectionRequest.SourceChannel, ConnectionRequest.PSM);
212
213 struct
214 {
215 BT_Signal_Header_t SignalCommandHeader;
216 BT_Signal_ConnectionResp_t ConnectionResponse;
217 } ResponsePacket;
218
219 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_CONNECTION_RESPONSE;
220 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
221 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.ConnectionResponse);
222 ResponsePacket.ConnectionResponse.Result = (ChannelData == NULL) ? BT_CONNECTION_REFUSED_RESOURCES : BT_CONNECTION_SUCCESSFUL;
223 ResponsePacket.ConnectionResponse.DestinationChannel = ChannelData->RemoteNumber;
224 ResponsePacket.ConnectionResponse.SourceChannel = ChannelData->LocalNumber;
225 ResponsePacket.ConnectionResponse.Status = 0x00;
226
227 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
228
229 BT_ACL_DEBUG(1, ">> L2CAP Connection Response", NULL);
230 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.ConnectionResponse.Result);
231 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConnectionResponse.SourceChannel);
232 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.ConnectionResponse.DestinationChannel);
233 }
234
235 static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t* ACLPacketHeader,
236 BT_DataPacket_Header_t* DataHeader,
237 BT_Signal_Header_t* SignalCommandHeader)
238 {
239 BT_Signal_ConfigurationReq_t ConfigurationRequest;
240 uint8_t OptionsLen;
241
242 Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
243 OptionsLen = (DataHeader->PayloadLength - sizeof(*SignalCommandHeader));
244
245 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
246
247 while (OptionsLen)
248 {
249 BT_Config_Option_Header_t OptionHeader;
250
251 Pipe_Read_Stream_LE(&OptionHeader, sizeof(OptionHeader));
252
253 if ((OptionHeader.Type == BT_CONFIG_OPTION_MTU) && (ChannelData != NULL))
254 Pipe_Read_Stream_LE(&ChannelData->RemoteMTU, sizeof(ChannelData->RemoteMTU));
255 else
256 Pipe_Discard_Stream(OptionHeader.Length);
257
258 OptionsLen -= (sizeof(OptionHeader) + OptionHeader.Length);
259 }
260
261 Pipe_ClearIN();
262 Pipe_Freeze();
263
264 BT_ACL_DEBUG(1, "<< L2CAP Configuration Request", NULL);
265 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
266 BT_ACL_DEBUG(2, "-- Options Len: 0x%04X", (DataHeader->PayloadLength - sizeof(*SignalCommandHeader)));
267 BT_ACL_DEBUG(2, "-- Remote MTU: 0x%04X", ChannelData->RemoteMTU);
268
269 struct
270 {
271 BT_Signal_Header_t SignalCommandHeader;
272 BT_Signal_ConfigurationResp_t ConfigurationResponse;
273 } ResponsePacket;
274
275 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_CONFIGURATION_RESPONSE;
276 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
277 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.ConfigurationResponse);
278 ResponsePacket.ConfigurationResponse.SourceChannel = ChannelData->RemoteNumber;
279 ResponsePacket.ConfigurationResponse.Flags = 0x00;
280 ResponsePacket.ConfigurationResponse.Result = (ChannelData != NULL) ? BT_CONFIGURATION_SUCCESSFUL : BT_CONFIGURATION_REJECTED;
281
282 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
283
284 if (ChannelData != NULL)
285 {
286 switch (ChannelData->State)
287 {
288 case Channel_Config_WaitConfig:
289 ChannelData->State = Channel_Config_WaitSendConfig;
290 break;
291 case Channel_Config_WaitReqResp:
292 ChannelData->State = Channel_Config_WaitResp;
293 break;
294 case Channel_Config_WaitReq:
295 ChannelData->State = Channel_Open;
296 break;
297 }
298 }
299
300 BT_ACL_DEBUG(1, ">> L2CAP Configuration Response", NULL);
301 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.ConfigurationResponse.SourceChannel);
302 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.ConfigurationResponse.Result);
303 }
304
305 static inline void Bluetooth_Signal_ConfigurationResp(BT_ACL_Header_t* ACLPacketHeader,
306 BT_DataPacket_Header_t* DataHeader,
307 BT_Signal_Header_t* SignalCommandHeader)
308 {
309 BT_Signal_ConfigurationResp_t ConfigurationResponse;
310
311 Pipe_Read_Stream_LE(&ConfigurationResponse, sizeof(ConfigurationResponse));
312
313 Pipe_ClearIN();
314 Pipe_Freeze();
315
316 BT_ACL_DEBUG(1, "<< L2CAP Configuration Response", NULL);
317 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConfigurationResponse.SourceChannel);
318 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse.Result);
319
320 if (ConfigurationResponse.Result == BT_CONFIGURATION_SUCCESSFUL)
321 {
322 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, true);
323
324 if (ChannelData != NULL)
325 {
326 switch (ChannelData->State)
327 {
328 case Channel_Config_WaitReqResp:
329 ChannelData->State = Channel_Config_WaitReq;
330 break;
331 case Channel_Config_WaitResp:
332 ChannelData->State = Channel_Open;
333 break;
334 }
335 }
336 }
337 }
338
339 static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t* ACLPacketHeader,
340 BT_DataPacket_Header_t* DataHeader,
341 BT_Signal_Header_t* SignalCommandHeader)
342 {
343 BT_Signal_DisconnectionReq_t DisconnectionRequest;
344
345 Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest));
346
347 BT_ACL_DEBUG(1, "<< L2CAP Disconnection Request", NULL);
348 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel);
349 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel);
350
351 Pipe_ClearIN();
352 Pipe_Freeze();
353
354 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);
355
356 struct
357 {
358 BT_Signal_Header_t SignalCommandHeader;
359 BT_Signal_DisconnectionResp_t DisconnectionResponse;
360 } ResponsePacket;
361
362 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_DISCONNECTION_RESPONSE;
363 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
364 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.DisconnectionResponse);
365 ResponsePacket.DisconnectionResponse.DestinationChannel = ChannelData->RemoteNumber;
366 ResponsePacket.DisconnectionResponse.SourceChannel = ChannelData->LocalNumber;
367
368 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
369
370 if (ChannelData != NULL)
371 ChannelData->State = Channel_Closed;
372
373 BT_ACL_DEBUG(1, ">> L2CAP Disconnection Response", NULL);
374 BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ResponsePacket.DisconnectionResponse.SourceChannel);
375 BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ResponsePacket.DisconnectionResponse.DestinationChannel);
376 }
377
378 static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
379 BT_DataPacket_Header_t* DataHeader,
380 BT_Signal_Header_t* SignalCommandHeader)
381 {
382 BT_ACL_DEBUG(1, "<< L2CAP Echo Request", NULL);
383
384 Pipe_ClearIN();
385 Pipe_Freeze();
386
387 struct
388 {
389 BT_Signal_Header_t SignalCommandHeader;
390 } ResponsePacket;
391
392 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_ECHO_RESPONSE;
393 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
394 ResponsePacket.SignalCommandHeader.Length = 0;
395
396 Bluetooth_SendPacket(&ResponsePacket, sizeof(ResponsePacket), NULL);
397
398 BT_ACL_DEBUG(1, ">> L2CAP Echo Response", NULL);
399 }
400
401 static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t* ACLPacketHeader,
402 BT_DataPacket_Header_t* DataHeader,
403 BT_Signal_Header_t* SignalCommandHeader)
404 {
405 BT_Signal_InformationReq_t InformationRequest;
406
407 Pipe_Read_Stream_LE(&InformationRequest, sizeof(InformationRequest));
408
409 BT_ACL_DEBUG(1, "<< L2CAP Information Request", NULL);
410 BT_ACL_DEBUG(2, "-- Info Type: 0x%04X", InformationRequest.InfoType);
411
412 Pipe_ClearIN();
413 Pipe_Freeze();
414
415 struct
416 {
417 BT_Signal_Header_t SignalCommandHeader;
418 BT_Signal_InformationResp_t InformationResponse;
419
420 uint8_t Data[4];
421 } ResponsePacket;
422
423 uint8_t DataLen = 0;
424
425 switch (InformationRequest.InfoType)
426 {
427 case BT_INFOREQ_MTU:
428 ResponsePacket.InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
429 DataLen = 2;
430
431 *((uint16_t*)&ResponsePacket.Data) = MAXIMUM_CHANNEL_MTU;
432 break;
433 case BT_INFOREQ_EXTENDEDFEATURES:
434 ResponsePacket.InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
435 DataLen = 4;
436
437 *((uint32_t*)&ResponsePacket.Data) = 0;
438 break;
439 default:
440 ResponsePacket.InformationResponse.Result = BT_INFORMATION_NOTSUPPORTED;
441 DataLen = 0;
442 break;
443 }
444
445 ResponsePacket.SignalCommandHeader.Code = BT_SIGNAL_INFORMATION_RESPONSE;
446 ResponsePacket.SignalCommandHeader.Identifier = SignalCommandHeader->Identifier;
447 ResponsePacket.SignalCommandHeader.Length = sizeof(ResponsePacket.InformationResponse) + DataLen;
448
449 Bluetooth_SendPacket(&ResponsePacket, (sizeof(ResponsePacket) - sizeof(ResponsePacket.Data) + DataLen), NULL);
450
451 BT_ACL_DEBUG(1, ">> L2CAP Information Response", NULL);
452 BT_ACL_DEBUG(2, "-- Result: 0x%02X", ResponsePacket.InformationResponse.Result);
453 }