Add Bluetooth signalling echo request/response handlers, disconnection request/respon...
[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 == BLUETOOTH_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 BLUETOOTH_SIGNAL_CONNECTION_REQUEST:
67 Bluetooth_SignalPacket_ConnectionRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
68 break;
69 case BLUETOOTH_SIGNAL_CONFIGURATION_REQUEST:
70 Bluetooth_SignalPacket_ConfigurationRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
71 break;
72 case BLUETOOTH_SIGNAL_DISCONNECTION_REQUEST:
73 Bluetooth_SignalPacket_DisconnectionRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
74 break;
75 case BLUETOOTH_SIGNAL_ECHO_REQUEST:
76 Bluetooth_SignalPacket_EchoRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
77 break;
78 case BLUETOOTH_SIGNAL_INFORMATION_REQUEST:
79 BT_ACL_DEBUG("<< Information Request", NULL);
80
81 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
82 Pipe_ClearIN();
83 Pipe_Freeze();
84 break;
85 default:
86 BT_ACL_DEBUG("<< Unknown Signaling Command 0x%02X", SignalCommandHeader.Code);
87
88 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
89 Pipe_ClearIN();
90 Pipe_Freeze();
91 break;
92 }
93 }
94 else
95 {
96 uint8_t DataPayload[DataHeader.PayloadLength];
97 Pipe_Read_Stream_LE(&DataPayload, sizeof(DataPayload));
98 DataHeader.PayloadLength = 0;
99
100 BT_ACL_DEBUG("-- Data Payload: ", NULL);
101 for (uint16_t B = 0; B < sizeof(DataPayload); B++)
102 printf("0x%02X ", DataPayload[B]);
103 printf("\r\n");
104
105 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
106 Pipe_ClearIN();
107 Pipe_Freeze();
108 }
109 }
110
111 static inline void Bluetooth_SignalPacket_ConnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
112 Bluetooth_DataPacket_Header_t* DataHeader,
113 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
114 {
115 Bluetooth_SignalCommand_ConnectionRequest_t ConnectionRequest;
116
117 Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));
118
119 BT_ACL_DEBUG("<< L2CAP Connection Request", NULL);
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 = BLUETOOTH_CHANNEL_SIGNALING;
135 SignalCommandHeader->Code = BLUETOOTH_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) ? BLUETOOTH_CONNECTION_REFUSED_RESOURCES :
141 BLUETOOTH_CONNECTION_SUCCESSFUL;
142 ConnectionResponse.DestinationChannel = ChannelData->LocalNumber;
143 ConnectionResponse.SourceChannel = ChannelData->RemoteNumber;
144 ConnectionResponse.Status = 0x00;
145
146 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
147 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
148 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
149 Pipe_Write_Stream_LE(&ConnectionResponse, sizeof(ConnectionResponse));
150
151 Pipe_ClearOUT();
152 Pipe_Freeze();
153
154 #if (ACL_DEBUG_LEVEL > 1)
155 BT_ACL_DEBUG("Packet Sent", NULL);
156 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
157 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
158 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
159 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
160 #endif
161 BT_ACL_DEBUG(">> L2CAP Connection Response", NULL);
162 #if (ACL_DEBUG_LEVEL > 1)
163 BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);
164 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
165 #endif
166 }
167
168 static inline void Bluetooth_SignalPacket_ConfigurationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
169 Bluetooth_DataPacket_Header_t* DataHeader,
170 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
171 {
172 Bluetooth_SignalCommand_ConfigurationRequest_t ConfigurationRequest;
173
174 Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
175
176 BT_ACL_DEBUG("<< L2CAP Configuration Request", NULL);
177 #if (ACL_DEBUG_LEVEL > 1)
178 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
179 #endif
180
181 Pipe_ClearIN();
182 Pipe_Freeze();
183 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
184 Pipe_Unfreeze();
185
186 Bluetooth_SignalCommand_ConfigurationResponse_t ConfigurationResponse;
187
188 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
189 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
190 DataHeader->DestinationChannel = BLUETOOTH_CHANNEL_SIGNALING;
191 SignalCommandHeader->Code = BLUETOOTH_SIGNAL_CONFIGURATION_RESPONSE;
192 SignalCommandHeader->Length = sizeof(ConfigurationResponse);
193
194 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
195
196 if (ChannelData != NULL)
197 ChannelData->State = Channel_Open;
198
199 // TODO: Add channel config data to the tail of ConfigurationResponse
200
201 ConfigurationResponse.SourceChannel = ChannelData->RemoteNumber;
202 ConfigurationResponse.Flags = 0x00;
203 ConfigurationResponse.Result = (ChannelData != NULL) ? BLUETOOTH_CONFIGURATION_SUCCESSFUL : BLUETOOTH_CONFIGURATION_REJECTED;
204
205 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
206 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
207 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
208 Pipe_Write_Stream_LE(&ConfigurationResponse, sizeof(ConfigurationResponse));
209
210 Pipe_ClearOUT();
211 Pipe_Freeze();
212
213 #if (ACL_DEBUG_LEVEL > 1)
214 BT_ACL_DEBUG("Packet Sent", NULL);
215 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
216 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
217 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
218 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
219 #endif
220 BT_ACL_DEBUG(">> L2CAP Configuration Response", NULL);
221 }
222
223 static inline void Bluetooth_SignalPacket_DisconnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
224 Bluetooth_DataPacket_Header_t* DataHeader,
225 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
226 {
227 Bluetooth_SignalCommand_DisconnectionRequest_t DisconnectionRequest;
228
229 Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest));
230
231 BT_ACL_DEBUG("<< L2CAP Disconnection Request", NULL);
232 #if (ACL_DEBUG_LEVEL > 1)
233 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel);
234 BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel);
235 #endif
236
237 Pipe_ClearIN();
238 Pipe_Freeze();
239 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
240 Pipe_Unfreeze();
241
242 Bluetooth_SignalCommand_DisconnectionResponse_t DisconnectionResponse;
243
244 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
245 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
246 DataHeader->DestinationChannel = BLUETOOTH_CHANNEL_SIGNALING;
247 SignalCommandHeader->Code = BLUETOOTH_SIGNAL_DISCONNECTION_RESPONSE;
248 SignalCommandHeader->Length = sizeof(DisconnectionResponse);
249
250 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);
251
252 if (ChannelData != NULL)
253 ChannelData->State = Channel_Closed;
254
255 DisconnectionResponse.DestinationChannel = ChannelData->LocalNumber;
256 DisconnectionResponse.SourceChannel = ChannelData->RemoteNumber;
257
258 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
259 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
260 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
261 Pipe_Write_Stream_LE(&DisconnectionResponse, sizeof(DisconnectionResponse));
262
263 Pipe_ClearOUT();
264 Pipe_Freeze();
265
266 #if (ACL_DEBUG_LEVEL > 1)
267 BT_ACL_DEBUG("Packet Sent", NULL);
268 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
269 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
270 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
271 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
272 #endif
273 BT_ACL_DEBUG(">> L2CAP Disconnection Response", NULL);
274 #if (ACL_DEBUG_LEVEL > 1)
275 BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel);
276 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel);
277 #endif
278 }
279
280 static inline void Bluetooth_SignalPacket_EchoRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
281 Bluetooth_DataPacket_Header_t* DataHeader,
282 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
283 {
284 BT_ACL_DEBUG("<< L2CAP Echo Request", NULL);
285
286 Pipe_ClearIN();
287 Pipe_Freeze();
288 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
289 Pipe_Unfreeze();
290
291 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader);
292 DataHeader->PayloadLength = sizeof(*SignalCommandHeader);
293 DataHeader->DestinationChannel = BLUETOOTH_CHANNEL_SIGNALING;
294 SignalCommandHeader->Code = BLUETOOTH_SIGNAL_ECHO_RESPONSE;
295 SignalCommandHeader->Length = 0;
296
297 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
298 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
299 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
300
301 Pipe_ClearOUT();
302 Pipe_Freeze();
303
304 #if (ACL_DEBUG_LEVEL > 1)
305 BT_ACL_DEBUG("Packet Sent", NULL);
306 BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
307 BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
308 BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
309 BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);
310 #endif
311 BT_ACL_DEBUG(">> L2CAP Echo Response", NULL);
312 }