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