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