More Doxygen fixes - ensure no undocumented function parameters.
[pub/USBasp.git] / Demos / Host / Incomplete / BluetoothHost / 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 Pipe_SetInfiniteINRequests();
100
101 memset(&Bluetooth_Connection, 0x00, sizeof(Bluetooth_Connection));
102
103 Bluetooth_HCIProcessingState = Bluetooth_Init_Reset;
104 break;
105 case Bluetooth_Init_Reset:
106 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
107 {
108 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET},
109 ParameterLength: 0,
110 };
111
112 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_Reset", NULL);
113
114 ErrorCode = Bluetooth_SendHCICommand(NULL, 0);
115
116 do
117 {
118 while (!(Bluetooth_GetNextHCIEventHeader()));
119 Bluetooth_DiscardRemainingHCIEventParameters();
120 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
121
122 Bluetooth_HCIProcessingState = Bluetooth_Init_ReadBufferSize;
123 break;
124 case Bluetooth_Init_ReadBufferSize:
125 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
126 {
127 OpCode: {OGF: OGF_CTRLR_INFORMATIONAL, OCF: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE},
128 ParameterLength: 0,
129 };
130
131 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL);
132
133 ErrorCode = Bluetooth_SendHCICommand(NULL, 0);
134
135 do
136 {
137 while (!(Bluetooth_GetNextHCIEventHeader()));
138 Bluetooth_DiscardRemainingHCIEventParameters();
139 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
140
141 Bluetooth_HCIProcessingState = Bluetooth_Init_SetEventMask;
142 break;
143 case Bluetooth_Init_SetEventMask:
144 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
145 {
146 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_SET_EVENT_MASK},
147 ParameterLength: 8,
148 };
149
150 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetEventMask", NULL);
151
152 uint8_t EventMask[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
153 ErrorCode = Bluetooth_SendHCICommand(&EventMask, 8);
154
155 BT_DEBUG("(HCI) -- Event mask: 0x%02X%02X%02X%02X%02X%02X%02X%02X", EventMask[7], EventMask[6], EventMask[5], EventMask[4],
156 EventMask[3], EventMask[2], EventMask[1], EventMask[0]);
157 do
158 {
159 while (!(Bluetooth_GetNextHCIEventHeader()));
160 Bluetooth_DiscardRemainingHCIEventParameters();
161 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
162
163
164 Bluetooth_HCIProcessingState = Bluetooth_Init_SetLocalName;
165 break;
166 case Bluetooth_Init_SetLocalName:
167 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
168 {
169 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME},
170 ParameterLength: 248,
171 };
172
173 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL);
174 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration.Name);
175
176 ErrorCode = Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration.Name, strlen(Bluetooth_DeviceConfiguration.Name));
177
178 do
179 {
180 while (!(Bluetooth_GetNextHCIEventHeader()));
181 Bluetooth_DiscardRemainingHCIEventParameters();
182 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
183
184 Bluetooth_HCIProcessingState = Bluetooth_Init_SetDeviceClass;
185 break;
186 case Bluetooth_Init_SetDeviceClass:
187 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
188 {
189 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE},
190 ParameterLength: 3,
191 };
192
193 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL);
194
195 ErrorCode = Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration.Class, 3);
196
197 do
198 {
199 while (!(Bluetooth_GetNextHCIEventHeader()));
200 Bluetooth_DiscardRemainingHCIEventParameters();
201 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
202
203 Bluetooth_HCIProcessingState = Bluetooth_Init_WriteScanEnable;
204 break;
205 case Bluetooth_Init_WriteScanEnable:
206 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
207 {
208 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE},
209 ParameterLength: 1,
210 };
211
212 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_WriteScanEnable", NULL);
213
214 uint8_t Interval = InquiryAndPageScans;
215 ErrorCode = Bluetooth_SendHCICommand(&Interval, 1);
216
217 do
218 {
219 while (!(Bluetooth_GetNextHCIEventHeader()));
220 Bluetooth_DiscardRemainingHCIEventParameters();
221 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
222
223 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
224 break;
225 case Bluetooth_PrepareToProcessEvents:
226 BT_DEBUG("(HCI) Enter State: Bluetooth_ProcessEvents", NULL);
227
228 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
229 break;
230 case Bluetooth_ProcessEvents:
231 if (Bluetooth_GetNextHCIEventHeader())
232 {
233 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader.EventCode);
234
235 if (HCIEventHeader.EventCode == EVENT_COMMAND_STATUS)
236 {
237 Bluetooth_HCIEvent_CommandStatus_Header_t CommandStatusHeader;
238
239 Pipe_Read_Stream_LE(&CommandStatusHeader, sizeof(CommandStatusHeader));
240 HCIEventHeader.ParameterLength -= sizeof(CommandStatusHeader);
241
242 BT_DEBUG("(HCI) >> Command status: 0x%02X", CommandStatusHeader.CommandStatus);
243
244 if (CommandStatusHeader.CommandStatus)
245 Bluetooth_HCIProcessingState = Bluetooth_Init;
246 }
247 else if (HCIEventHeader.EventCode == EVENT_CONNECTION_REQUEST)
248 {
249 Bluetooth_HCIEvent_ConnectionRequest_Header_t ConnectionRequestParams;
250
251 Pipe_Read_Stream_LE(&ConnectionRequestParams, sizeof(ConnectionRequestParams));
252 HCIEventHeader.ParameterLength -= sizeof(ConnectionRequestParams);
253
254 BT_DEBUG("(HCI) >> Connection Request from device %02X:%02X:%02X:%02X:%02X:%02X",
255 ConnectionRequestParams.RemoteAddress[5], ConnectionRequestParams.RemoteAddress[4],
256 ConnectionRequestParams.RemoteAddress[3], ConnectionRequestParams.RemoteAddress[2],
257 ConnectionRequestParams.RemoteAddress[1], ConnectionRequestParams.RemoteAddress[0]);
258 BT_DEBUG("(HCI) -- Device Class: 0x%02X%04X", ConnectionRequestParams.ClassOfDevice_Service,
259 ConnectionRequestParams.ClassOfDevice_MajorMinor);
260 BT_DEBUG("(HCI) -- Link Type: 0x%02x", ConnectionRequestParams.LinkType);
261
262 memcpy(Bluetooth_TempDeviceAddress, ConnectionRequestParams.RemoteAddress,
263 sizeof(Bluetooth_TempDeviceAddress));
264
265 Bluetooth_HCIProcessingState = (Bluetooth_Connection.IsConnected) ? Bluetooth_Conn_RejectConnection :
266 Bluetooth_Conn_AcceptConnection;
267 }
268 else if (HCIEventHeader.EventCode == EVENT_DISCONNECTION_COMPLETE)
269 {
270 BT_DEBUG("(HCI) >> Disconnection from device complete.", NULL);
271 Bluetooth_HCIProcessingState = Bluetooth_Init;
272 }
273 else if (HCIEventHeader.EventCode == EVENT_CONNECTION_COMPLETE)
274 {
275 Bluetooth_HCIEvent_ConnectionComplete_Header_t ConnectionCompleteParams;
276
277 Pipe_Read_Stream_LE(&ConnectionCompleteParams, sizeof(ConnectionCompleteParams));
278 HCIEventHeader.ParameterLength -= sizeof(ConnectionCompleteParams);
279
280 BT_DEBUG("(HCI) >> Connection to device complete.", NULL);
281 BT_DEBUG("(HCI) -- Status: %d", ConnectionCompleteParams.Status);
282 BT_DEBUG("(HCI) -- Handle: %d", ConnectionCompleteParams.ConnectionHandle);
283
284 if (ConnectionCompleteParams.Status == 0x00)
285 {
286 memcpy(Bluetooth_Connection.DeviceAddress, ConnectionCompleteParams.RemoteAddress,
287 sizeof(Bluetooth_Connection.DeviceAddress));
288 Bluetooth_Connection.ConnectionHandle = ConnectionCompleteParams.ConnectionHandle;
289 Bluetooth_Connection.IsConnected = true;
290 }
291 }
292 else if (HCIEventHeader.EventCode == EVENT_PIN_CODE_REQUEST)
293 {
294 Pipe_Read_Stream_LE(&Bluetooth_TempDeviceAddress, sizeof(Bluetooth_TempDeviceAddress));
295 HCIEventHeader.ParameterLength -= sizeof(Bluetooth_TempDeviceAddress);
296
297 BT_DEBUG("(HCI) >> PIN code Request from device %02X:%02X:%02X:%02X:%02X:%02X",
298 Bluetooth_TempDeviceAddress[5], Bluetooth_TempDeviceAddress[4], Bluetooth_TempDeviceAddress[3],
299 Bluetooth_TempDeviceAddress[2], Bluetooth_TempDeviceAddress[1], Bluetooth_TempDeviceAddress[0]);
300
301 Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode;
302 }
303
304 BT_DEBUG("(HCI) -- Unread Event Param Length: %d", HCIEventHeader.ParameterLength);
305
306 Bluetooth_DiscardRemainingHCIEventParameters();
307 }
308
309 break;
310 case Bluetooth_Conn_AcceptConnection:
311 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
312 {
313 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},
314 ParameterLength: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_Params_t),
315 };
316
317 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL);
318
319 Bluetooth_HCICommand_AcceptConnectionRequest_Params_t AcceptConnectionParams;
320
321 memcpy(AcceptConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress,
322 sizeof(Bluetooth_TempDeviceAddress));
323 AcceptConnectionParams.SlaveRole = true;
324
325 Bluetooth_SendHCICommand(&AcceptConnectionParams, sizeof(AcceptConnectionParams));
326
327 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
328 break;
329 case Bluetooth_Conn_RejectConnection:
330 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
331 {
332 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},
333 ParameterLength: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_Params_t),
334 };
335
336 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL);
337
338 Bluetooth_HCICommand_RejectConnectionRequest_Params_t RejectConnectionParams;
339
340 memcpy(RejectConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress,
341 sizeof(Bluetooth_TempDeviceAddress));
342 RejectConnectionParams.Reason = ERROR_LIMITED_RESOURCES;
343
344 Bluetooth_SendHCICommand(&AcceptConnectionParams, sizeof(AcceptConnectionParams));
345
346 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
347 break;
348 case Bluetooth_Conn_SendPINCode:
349 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
350 {
351 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY},
352 ParameterLength: sizeof(Bluetooth_HCICommand_PinCodeResponse_Params_t),
353 };
354
355 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL);
356 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration.PINCode);
357
358 Bluetooth_HCICommand_PinCodeResponse_Params_t PINCodeRequestParams;
359
360 memcpy(PINCodeRequestParams.RemoteAddress, Bluetooth_TempDeviceAddress,
361 sizeof(Bluetooth_TempDeviceAddress));
362 PINCodeRequestParams.PINCodeLength = strlen(Bluetooth_DeviceConfiguration.PINCode);
363 memcpy(PINCodeRequestParams.PINCode, Bluetooth_DeviceConfiguration.PINCode,
364 sizeof(Bluetooth_DeviceConfiguration.PINCode));
365
366 Bluetooth_SendHCICommand(&PINCodeRequestParams, sizeof(PINCodeRequestParams));
367
368 do
369 {
370 while (!(Bluetooth_GetNextHCIEventHeader()));
371 Bluetooth_DiscardRemainingHCIEventParameters();
372 } while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
373
374 Bluetooth_HCIProcessingState = Bluetooth_PrepareToProcessEvents;
375 break;
376 }
377 }