Cleanups to the MassStorage Device demos, and the MassStorage Device Class driver.
[pub/USBasp.git] / Demos / Host / Incomplete / BluetoothHost / Lib / BluetoothHCICommands.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2009.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 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 #include "BluetoothHCICommands.h"
32
33 static Bluetooth_HCICommand_Header_t HCICommandHeader;
34 static Bluetooth_HCIEvent_Header_t HCIEventHeader;
35
36 uint8_t Bluetooth_HCIProcessingState;
37 static uint8_t Bluetooth_TempDeviceAddress[6];
38
39 static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint8_t ParamLength)
40 {
41 uint8_t CommandBuffer[sizeof(HCICommandHeader) + HCICommandHeader.ParameterLength];
42
43 USB_ControlRequest = (USB_Request_Header_t)
44 {
45 bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_DEVICE),
46 bRequest: 0,
47 wValue: 0,
48 wIndex: 0,
49 wLength: sizeof(CommandBuffer)
50 };
51
52 memset(CommandBuffer, 0x00, sizeof(CommandBuffer));
53 memcpy(CommandBuffer, &HCICommandHeader, sizeof(HCICommandHeader));
54
55 if (ParamLength)
56 memcpy(&CommandBuffer[sizeof(HCICommandHeader)], Parameters, ParamLength);
57
58 Pipe_SelectPipe(PIPE_CONTROLPIPE);
59
60 return USB_Host_SendControlRequest(CommandBuffer);
61 }
62
63 static bool Bluetooth_GetNextHCIEventHeader(void)
64 {
65 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
66 Pipe_Unfreeze();
67
68 if (!(Pipe_IsReadWriteAllowed()))
69 {
70 Pipe_Freeze();
71 return false;
72 }
73
74 Pipe_Read_Stream_LE(&HCIEventHeader, sizeof(HCIEventHeader));
75
76 Pipe_Freeze();
77
78 return true;
79 }
80
81 static void Bluetooth_DiscardRemainingHCIEventParameters(void)
82 {
83 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
84
85 Pipe_Unfreeze();
86 Pipe_Discard_Stream(HCIEventHeader.ParameterLength);
87 Pipe_ClearIN();
88 Pipe_Freeze();
89 }
90
91 void Bluetooth_ProcessHCICommands(void)
92 {
93 uint8_t ErrorCode;
94
95 switch (Bluetooth_HCIProcessingState)
96 {
97 case Bluetooth_Init:
98 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
99
100 memset(&Bluetooth_Connection, 0x00, sizeof(Bluetooth_Connection));
101
102 Bluetooth_HCIProcessingState = Bluetooth_Init_Reset;
103 break;
104 case Bluetooth_Init_Reset:
105 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
106 {
107 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET},
108 ParameterLength: 0,
109 };
110
111 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_Reset", NULL);
112
113 ErrorCode = Bluetooth_SendHCICommand(NULL, 0);
114
115 do
116 {
117 while (!(Bluetooth_GetNextHCIEventHeader()))
118 {
119 if (USB_HostState == HOST_STATE_Unattached)
120 return;
121 }
122
123 Bluetooth_DiscardRemainingHCIEventParameters();
124 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
125
126 Bluetooth_HCIProcessingState = Bluetooth_Init_ReadBufferSize;
127 break;
128 case Bluetooth_Init_ReadBufferSize:
129 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
130 {
131 OpCode: {OGF: OGF_CTRLR_INFORMATIONAL, OCF: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE},
132 ParameterLength: 0,
133 };
134
135 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL);
136
137 ErrorCode = Bluetooth_SendHCICommand(NULL, 0);
138
139 do
140 {
141 while (!(Bluetooth_GetNextHCIEventHeader()))
142 {
143 if (USB_HostState == HOST_STATE_Unattached)
144 return;
145 }
146
147 Bluetooth_DiscardRemainingHCIEventParameters();
148 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
149
150 Bluetooth_HCIProcessingState = Bluetooth_Init_SetEventMask;
151 break;
152 case Bluetooth_Init_SetEventMask:
153 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
154 {
155 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_SET_EVENT_MASK},
156 ParameterLength: 8,
157 };
158
159 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetEventMask", NULL);
160
161 uint8_t EventMask[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
162 ErrorCode = Bluetooth_SendHCICommand(&EventMask, 8);
163
164 BT_DEBUG("(HCI) -- Event mask: 0x%02X%02X%02X%02X%02X%02X%02X%02X", EventMask[7], EventMask[6], EventMask[5], EventMask[4],
165 EventMask[3], EventMask[2], EventMask[1], EventMask[0]);
166 do
167 {
168 while (!(Bluetooth_GetNextHCIEventHeader()))
169 {
170 if (USB_HostState == HOST_STATE_Unattached)
171 return;
172 }
173
174 Bluetooth_DiscardRemainingHCIEventParameters();
175 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
176
177
178 Bluetooth_HCIProcessingState = Bluetooth_Init_SetLocalName;
179 break;
180 case Bluetooth_Init_SetLocalName:
181 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
182 {
183 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME},
184 ParameterLength: 248,
185 };
186
187 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL);
188 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration.Name);
189
190 ErrorCode = Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration.Name, strlen(Bluetooth_DeviceConfiguration.Name));
191
192 do
193 {
194 while (!(Bluetooth_GetNextHCIEventHeader()))
195 {
196 if (USB_HostState == HOST_STATE_Unattached)
197 return;
198 }
199
200 Bluetooth_DiscardRemainingHCIEventParameters();
201 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
202
203 Bluetooth_HCIProcessingState = Bluetooth_Init_SetDeviceClass;
204 break;
205 case Bluetooth_Init_SetDeviceClass:
206 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
207 {
208 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE},
209 ParameterLength: 3,
210 };
211
212 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL);
213
214 ErrorCode = Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration.Class, 3);
215
216 do
217 {
218 while (!(Bluetooth_GetNextHCIEventHeader()))
219 {
220 if (USB_HostState == HOST_STATE_Unattached)
221 return;
222 }
223
224 Bluetooth_DiscardRemainingHCIEventParameters();
225 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
226
227 Bluetooth_HCIProcessingState = Bluetooth_Init_WriteScanEnable;
228 break;
229 case Bluetooth_Init_WriteScanEnable:
230 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
231 {
232 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE},
233 ParameterLength: 1,
234 };
235
236 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_WriteScanEnable", NULL);
237
238 uint8_t Interval = InquiryAndPageScans;
239 ErrorCode = Bluetooth_SendHCICommand(&Interval, 1);
240
241 do
242 {
243 while (!(Bluetooth_GetNextHCIEventHeader()))
244 {
245 if (USB_HostState == HOST_STATE_Unattached)
246 return;
247 }
248
249 Bluetooth_DiscardRemainingHCIEventParameters();
250 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
251
252 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
253 break;
254 case Bluetooth_PrepareToProcessEvents:
255 BT_DEBUG("(HCI) Enter State: Bluetooth_ProcessEvents", NULL);
256
257 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
258 break;
259 case Bluetooth_ProcessEvents:
260 if (Bluetooth_GetNextHCIEventHeader())
261 {
262 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader.EventCode);
263
264 if (HCIEventHeader.EventCode == EVENT_COMMAND_STATUS)
265 {
266 Bluetooth_HCIEvent_CommandStatus_Header_t CommandStatusHeader;
267
268 Pipe_Read_Stream_LE(&CommandStatusHeader, sizeof(CommandStatusHeader));
269 HCIEventHeader.ParameterLength -= sizeof(CommandStatusHeader);
270
271 BT_DEBUG("(HCI) >> Command status: 0x%02X", CommandStatusHeader.CommandStatus);
272
273 if (CommandStatusHeader.CommandStatus)
274 Bluetooth_HCIProcessingState = Bluetooth_Init;
275 }
276 else if (HCIEventHeader.EventCode == EVENT_CONNECTION_REQUEST)
277 {
278 Bluetooth_HCIEvent_ConnectionRequest_Header_t ConnectionRequestParams;
279
280 Pipe_Read_Stream_LE(&ConnectionRequestParams, sizeof(ConnectionRequestParams));
281 HCIEventHeader.ParameterLength -= sizeof(ConnectionRequestParams);
282
283 BT_DEBUG("(HCI) >> Connection Request from device %02X:%02X:%02X:%02X:%02X:%02X",
284 ConnectionRequestParams.RemoteAddress[5], ConnectionRequestParams.RemoteAddress[4],
285 ConnectionRequestParams.RemoteAddress[3], ConnectionRequestParams.RemoteAddress[2],
286 ConnectionRequestParams.RemoteAddress[1], ConnectionRequestParams.RemoteAddress[0]);
287 BT_DEBUG("(HCI) -- Device Class: 0x%02X%04X", ConnectionRequestParams.ClassOfDevice_Service,
288 ConnectionRequestParams.ClassOfDevice_MajorMinor);
289 BT_DEBUG("(HCI) -- Link Type: 0x%02x", ConnectionRequestParams.LinkType);
290
291 memcpy(Bluetooth_TempDeviceAddress, ConnectionRequestParams.RemoteAddress,
292 sizeof(Bluetooth_TempDeviceAddress));
293
294 Bluetooth_HCIProcessingState = (Bluetooth_Connection.IsConnected) ? Bluetooth_Conn_RejectConnection :
295 Bluetooth_Conn_AcceptConnection;
296 }
297 else if (HCIEventHeader.EventCode == EVENT_DISCONNECTION_COMPLETE)
298 {
299 BT_DEBUG("(HCI) >> Disconnection from device complete.", NULL);
300 Bluetooth_HCIProcessingState = Bluetooth_Init;
301 }
302 else if (HCIEventHeader.EventCode == EVENT_CONNECTION_COMPLETE)
303 {
304 Bluetooth_HCIEvent_ConnectionComplete_Header_t ConnectionCompleteParams;
305
306 Pipe_Read_Stream_LE(&ConnectionCompleteParams, sizeof(ConnectionCompleteParams));
307 HCIEventHeader.ParameterLength -= sizeof(ConnectionCompleteParams);
308
309 BT_DEBUG("(HCI) >> Connection to device complete.", NULL);
310 BT_DEBUG("(HCI) -- Status: %d", ConnectionCompleteParams.Status);
311 BT_DEBUG("(HCI) -- Handle: %d", ConnectionCompleteParams.ConnectionHandle);
312
313 if (ConnectionCompleteParams.Status == 0x00)
314 {
315 memcpy(Bluetooth_Connection.DeviceAddress, ConnectionCompleteParams.RemoteAddress,
316 sizeof(Bluetooth_Connection.DeviceAddress));
317 Bluetooth_Connection.ConnectionHandle = ConnectionCompleteParams.ConnectionHandle;
318 Bluetooth_Connection.IsConnected = true;
319 }
320 }
321 else if (HCIEventHeader.EventCode == EVENT_PIN_CODE_REQUEST)
322 {
323 Pipe_Read_Stream_LE(&Bluetooth_TempDeviceAddress, sizeof(Bluetooth_TempDeviceAddress));
324 HCIEventHeader.ParameterLength -= sizeof(Bluetooth_TempDeviceAddress);
325
326 BT_DEBUG("(HCI) >> PIN code Request from device %02X:%02X:%02X:%02X:%02X:%02X",
327 Bluetooth_TempDeviceAddress[5], Bluetooth_TempDeviceAddress[4], Bluetooth_TempDeviceAddress[3],
328 Bluetooth_TempDeviceAddress[2], Bluetooth_TempDeviceAddress[1], Bluetooth_TempDeviceAddress[0]);
329
330 Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode;
331 }
332
333 BT_DEBUG("(HCI) -- Unread Event Param Length: %d", HCIEventHeader.ParameterLength);
334
335 Bluetooth_DiscardRemainingHCIEventParameters();
336 }
337
338 break;
339 case Bluetooth_Conn_AcceptConnection:
340 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
341 {
342 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},
343 ParameterLength: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_Params_t),
344 };
345
346 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL);
347
348 Bluetooth_HCICommand_AcceptConnectionRequest_Params_t AcceptConnectionParams;
349
350 memcpy(AcceptConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress,
351 sizeof(Bluetooth_TempDeviceAddress));
352 AcceptConnectionParams.SlaveRole = true;
353
354 Bluetooth_SendHCICommand(&AcceptConnectionParams, sizeof(AcceptConnectionParams));
355
356 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
357 break;
358 case Bluetooth_Conn_RejectConnection:
359 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
360 {
361 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},
362 ParameterLength: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_Params_t),
363 };
364
365 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL);
366
367 Bluetooth_HCICommand_RejectConnectionRequest_Params_t RejectConnectionParams;
368
369 memcpy(RejectConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress,
370 sizeof(Bluetooth_TempDeviceAddress));
371 RejectConnectionParams.Reason = ERROR_LIMITED_RESOURCES;
372
373 Bluetooth_SendHCICommand(&AcceptConnectionParams, sizeof(AcceptConnectionParams));
374
375 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
376 break;
377 case Bluetooth_Conn_SendPINCode:
378 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
379 {
380 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY},
381 ParameterLength: sizeof(Bluetooth_HCICommand_PinCodeResponse_Params_t),
382 };
383
384 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL);
385 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration.PINCode);
386
387 Bluetooth_HCICommand_PinCodeResponse_Params_t PINCodeRequestParams;
388
389 memcpy(PINCodeRequestParams.RemoteAddress, Bluetooth_TempDeviceAddress,
390 sizeof(Bluetooth_TempDeviceAddress));
391 PINCodeRequestParams.PINCodeLength = strlen(Bluetooth_DeviceConfiguration.PINCode);
392 memcpy(PINCodeRequestParams.PINCode, Bluetooth_DeviceConfiguration.PINCode,
393 sizeof(Bluetooth_DeviceConfiguration.PINCode));
394
395 Bluetooth_SendHCICommand(&PINCodeRequestParams, sizeof(PINCodeRequestParams));
396
397 do
398 {
399 while (!(Bluetooth_GetNextHCIEventHeader()))
400 {
401 if (USB_HostState == HOST_STATE_Unattached)
402 return;
403 }
404
405 Bluetooth_DiscardRemainingHCIEventParameters();
406 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
407
408 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
409 break;
410 }
411 }