Add packet reception and send routines to the ACL layer of the incomplete Bluetooth...
[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_ProcessACLPackets(void)
35 {
36 Bluetooth_ACL_Header_t ACLPacketHeader;
37 Bluetooth_DataPacket_Header_t DataHeader;
38
39 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
40 Pipe_Unfreeze();
41
42 if (!(Pipe_IsReadWriteAllowed()))
43 {
44 Pipe_Freeze();
45 return;
46 }
47
48 Pipe_Read_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
49 Pipe_Read_Stream_LE(&DataHeader, sizeof(DataHeader));
50
51 #if (ACL_DEBUG_LEVEL > 1)
52 BT_ACL_DEBUG("Packet Received", NULL);
53 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
54 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
55 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
56 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader.PayloadLength);
57 #endif
58
59 if (DataHeader.DestinationChannel == BT_CHANNEL_SIGNALING)
60 {
61 Bluetooth_SignalCommand_Header_t SignalCommandHeader;
62 Pipe_Read_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader));
63
64 switch (SignalCommandHeader.Code)
65 {
66 case BT_SIGNAL_CONNECTION_REQUEST:
67 Bluetooth_SignalPacket_ConnectionRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
68 break;
69 case BT_SIGNAL_CONFIGURATION_REQUEST:
70 Bluetooth_SignalPacket_ConfigurationRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
71 break;
72 case BT_SIGNAL_DISCONNECTION_REQUEST:
73 Bluetooth_SignalPacket_DisconnectionRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
74 break;
75 case BT_SIGNAL_ECHO_REQUEST:
76 Bluetooth_SignalPacket_EchoRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
77 break;
78 case BT_SIGNAL_INFORMATION_REQUEST:
79 Bluetooth_SignalPacket_InformationRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
80 break;
81 default:
82 #if (ACL_DEBUG_LEVEL > 0)
83 BT_ACL_DEBUG("<< Unknown Signaling Command 0x%02X", SignalCommandHeader.Code);
84 #endif
85
86 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
87 Pipe_ClearIN();
88 Pipe_Freeze();
89 break;
90 }
91 }
92 else
93 {
94 Bluetooth_PacketReceived(&DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, true));
95
96 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
97 Pipe_Discard_Stream(DataHeader.PayloadLength);
98 Pipe_ClearIN();
99 Pipe_Freeze();
100 }
101 }
102
103 void Bluetooth_SendPacket(uint8_t* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel)
104 {
105 Bluetooth_ACL_Header_t ACLPacketHeader;
106 Bluetooth_DataPacket_Header_t DataHeader;
107
108 ACLPacketHeader.ConnectionHandle = Bluetooth_Connection.ConnectionHandle;
109 ACLPacketHeader.DataLength = sizeof(DataHeader) + DataLen;
110 DataHeader.PayloadLength = DataLen;
111 DataHeader.DestinationChannel = Channel->RemoteNumber;
112
113 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
114 Pipe_Unfreeze();
115
116 Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
117 Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
118 Pipe_Write_Stream_LE(Data, DataLen);
119
120 Pipe_Freeze();
121 }
122
123 static inline void Bluetooth_SignalPacket_ConnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
124 Bluetooth_DataPacket_Header_t* DataHeader,
125 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
126 {
127 Bluetooth_SignalCommand_ConnectionRequest_t ConnectionRequest;
128
129 Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));
130
131 #if (ACL_DEBUG_LEVEL > 0)
132 BT_ACL_DEBUG("<< L2CAP Connection Request", NULL);
133 #endif
134 #if (ACL_DEBUG_LEVEL > 1)
135 BT_ACL_DEBUG("-- PSM: 0x%04X", ConnectionRequest.PSM);
136 BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
137 #endif
138
139 Pipe_ClearIN();
140 Pipe_Freeze();
141 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
142 Pipe_Unfreeze();
143
144 Bluetooth_SignalCommand_ConnectionResponse_t ConnectionResponse;
145
146 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
147 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
148 DataHeader->DestinationChannel = BT_CHANNEL_SIGNALING;
149 SignalCommandHeader->Code = BT_SIGNAL_CONNECTION_RESPONSE;
150 SignalCommandHeader->Length = sizeof(ConnectionResponse);
151
152 Bluetooth_Channel_t* ChannelData = Bluetooth_InitChannelData(ConnectionRequest.SourceChannel, ConnectionRequest.PSM);
153
154 ConnectionResponse.Result = (ChannelData == NULL) ? BT_CONNECTION_REFUSED_RESOURCES : BT_CONNECTION_SUCCESSFUL;
155 ConnectionResponse.DestinationChannel = ChannelData->LocalNumber;
156 ConnectionResponse.SourceChannel = ChannelData->RemoteNumber;
157 ConnectionResponse.Status = 0x00;
158
159 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
160 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
161 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
162 Pipe_Write_Stream_LE(&ConnectionResponse, sizeof(ConnectionResponse));
163
164 Pipe_ClearOUT();
165 Pipe_Freeze();
166
167 #if (ACL_DEBUG_LEVEL > 1)
168 BT_ACL_DEBUG("Packet Sent", NULL);
169 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
170 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
171 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
172 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
173 #endif
174 #if (ACL_DEBUG_LEVEL > 0)
175 BT_ACL_DEBUG(">> L2CAP Connection Response", NULL);
176 #endif
177 #if (ACL_DEBUG_LEVEL > 1)
178 BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);
179 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
180 #endif
181 }
182
183 static inline void Bluetooth_SignalPacket_ConfigurationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
184 Bluetooth_DataPacket_Header_t* DataHeader,
185 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
186 {
187 Bluetooth_SignalCommand_ConfigurationRequest_t ConfigurationRequest;
188 Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
189
190 // TODO: Process/Discard configuration options here
191
192 #if (ACL_DEBUG_LEVEL > 0)
193 BT_ACL_DEBUG("<< L2CAP Configuration Request", NULL);
194 #endif
195 #if (ACL_DEBUG_LEVEL > 1)
196 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
197 #endif
198
199 Pipe_ClearIN();
200 Pipe_Freeze();
201 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
202 Pipe_Unfreeze();
203
204 Bluetooth_SignalCommand_ConfigurationResponse_t ConfigurationResponse;
205
206 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
207 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
208 DataHeader->DestinationChannel = BT_CHANNEL_SIGNALING;
209 SignalCommandHeader->Code = BT_SIGNAL_CONFIGURATION_RESPONSE;
210 SignalCommandHeader->Length = sizeof(ConfigurationResponse);
211
212 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
213
214 if (ChannelData != NULL)
215 ChannelData->State = Channel_Open;
216
217 // TODO: Add channel config data to the tail of ConfigurationResponse
218
219 ConfigurationResponse.SourceChannel = ChannelData->RemoteNumber;
220 ConfigurationResponse.Flags = 0x00;
221 ConfigurationResponse.Result = (ChannelData != NULL) ? BT_CONFIGURATION_SUCCESSFUL : BT_CONFIGURATION_REJECTED;
222
223 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
224 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
225 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
226 Pipe_Write_Stream_LE(&ConfigurationResponse, sizeof(ConfigurationResponse));
227
228 Pipe_ClearOUT();
229 Pipe_Freeze();
230
231 #if (ACL_DEBUG_LEVEL > 1)
232 BT_ACL_DEBUG("Packet Sent", NULL);
233 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
234 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
235 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
236 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
237 #endif
238 #if (ACL_DEBUG_LEVEL > 0)
239 BT_ACL_DEBUG(">> L2CAP Configuration Response", NULL);
240 #endif
241 #if (ACL_DEBUG_LEVEL > 1)
242 BT_ACL_DEBUG("-- Result: 0x%02X", ConfigurationResponse.Result);
243 #endif
244 }
245
246 static inline void Bluetooth_SignalPacket_DisconnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
247 Bluetooth_DataPacket_Header_t* DataHeader,
248 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
249 {
250 Bluetooth_SignalCommand_DisconnectionRequest_t DisconnectionRequest;
251
252 Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest));
253
254 #if (ACL_DEBUG_LEVEL > 0)
255 BT_ACL_DEBUG("<< L2CAP Disconnection Request", NULL);
256 #endif
257 #if (ACL_DEBUG_LEVEL > 1)
258 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel);
259 BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel);
260 #endif
261
262 Pipe_ClearIN();
263 Pipe_Freeze();
264 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
265 Pipe_Unfreeze();
266
267 Bluetooth_SignalCommand_DisconnectionResponse_t DisconnectionResponse;
268
269 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
270 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
271 DataHeader->DestinationChannel = BT_CHANNEL_SIGNALING;
272 SignalCommandHeader->Code = BT_SIGNAL_DISCONNECTION_RESPONSE;
273 SignalCommandHeader->Length = sizeof(DisconnectionResponse);
274
275 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);
276
277 if (ChannelData != NULL)
278 ChannelData->State = Channel_Closed;
279
280 DisconnectionResponse.DestinationChannel = ChannelData->LocalNumber;
281 DisconnectionResponse.SourceChannel = ChannelData->RemoteNumber;
282
283 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
284 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
285 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
286 Pipe_Write_Stream_LE(&DisconnectionResponse, sizeof(DisconnectionResponse));
287
288 Pipe_ClearOUT();
289 Pipe_Freeze();
290
291 #if (ACL_DEBUG_LEVEL > 1)
292 BT_ACL_DEBUG("Packet Sent", NULL);
293 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
294 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
295 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
296 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
297 #endif
298 #if (ACL_DEBUG_LEVEL > 0)
299 BT_ACL_DEBUG(">> L2CAP Disconnection Response", NULL);
300 #endif
301 #if (ACL_DEBUG_LEVEL > 1)
302 BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel);
303 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel);
304 #endif
305 }
306
307 static inline void Bluetooth_SignalPacket_EchoRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
308 Bluetooth_DataPacket_Header_t* DataHeader,
309 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
310 {
311 #if (ACL_DEBUG_LEVEL > 0)
312 BT_ACL_DEBUG("<< L2CAP Echo Request", NULL);
313 #endif
314
315 Pipe_ClearIN();
316 Pipe_Freeze();
317 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
318 Pipe_Unfreeze();
319
320 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader);
321 DataHeader->PayloadLength = sizeof(*SignalCommandHeader);
322 DataHeader->DestinationChannel = BT_CHANNEL_SIGNALING;
323 SignalCommandHeader->Code = BT_SIGNAL_ECHO_RESPONSE;
324 SignalCommandHeader->Length = 0;
325
326 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
327 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
328 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
329
330 Pipe_ClearOUT();
331 Pipe_Freeze();
332
333 #if (ACL_DEBUG_LEVEL > 1)
334 BT_ACL_DEBUG("Packet Sent", NULL);
335 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
336 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
337 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
338 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
339 #endif
340 #if (ACL_DEBUG_LEVEL > 0)
341 BT_ACL_DEBUG(">> L2CAP Echo Response", NULL);
342 #endif
343 }
344
345 static inline void Bluetooth_SignalPacket_InformationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
346 Bluetooth_DataPacket_Header_t* DataHeader,
347 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
348 {
349 Bluetooth_SignalCommand_InformationRequest_t InformationRequest;
350
351 Pipe_Read_Stream_LE(&InformationRequest, sizeof(InformationRequest));
352
353 #if (ACL_DEBUG_LEVEL > 0)
354 BT_ACL_DEBUG("<< Information Request", NULL);
355 #endif
356 #if (ACL_DEBUG_LEVEL > 1)
357 BT_ACL_DEBUG("-- Info Type: 0x%04X", InformationRequest.InfoType);
358 #endif
359
360 Pipe_ClearIN();
361 Pipe_Freeze();
362 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
363 Pipe_Unfreeze();
364
365 Bluetooth_SignalCommand_InformationResponse_t InformationResponse;
366 uint8_t ResponseData[4];
367 uint8_t ResponseLen;
368
369 switch (InformationRequest.InfoType)
370 {
371 case BT_INFOREQ_MTU:
372 InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
373 ResponseLen = 2;
374
375 *((uint16_t*)&ResponseData) = 65533;
376 break;
377 case BT_INFOREQ_EXTENDEDFEATURES:
378 InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
379 ResponseLen = 4;
380
381 *((uint32_t*)&ResponseData) = 0;
382 break;
383 default:
384 InformationResponse.Result = BT_INFORMATION_NOTSUPPORTED;
385 ResponseLen = 0;
386 break;
387 }
388
389 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(InformationResponse) +
390 ResponseLen;
391 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(InformationResponse) + ResponseLen;
392 DataHeader->DestinationChannel = BT_CHANNEL_SIGNALING;
393 SignalCommandHeader->Code = BT_SIGNAL_INFORMATION_RESPONSE;
394 SignalCommandHeader->Length = sizeof(InformationResponse) + ResponseLen;
395
396 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
397 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
398 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
399 Pipe_Write_Stream_LE(&InformationResponse, sizeof(InformationResponse));
400 Pipe_Write_Stream_LE(ResponseData, ResponseLen);
401
402 Pipe_ClearOUT();
403 Pipe_Freeze();
404
405 #if (ACL_DEBUG_LEVEL > 1)
406 BT_ACL_DEBUG("Packet Sent", NULL);
407 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
408 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
409 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
410 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
411 #endif
412 #if (ACL_DEBUG_LEVEL > 0)
413 BT_ACL_DEBUG(">> L2CAP Information Response", NULL);
414 #endif
415 #if (ACL_DEBUG_LEVEL > 1)
416 BT_ACL_DEBUG("-- Result: 0x%02X", InformationResponse.Result);
417 #endif
418 }