3 Copyright (C) Dean Camera, 2009.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
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.
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
31 #include "BluetoothHCICommands.h"
33 static Bluetooth_HCICommand_Header_t HCICommandHeader
;
34 static Bluetooth_HCIEvent_Header_t HCIEventHeader
;
36 uint8_t Bluetooth_HCIProcessingState
;
37 static uint8_t Bluetooth_TempDeviceAddress
[6];
39 static uint8_t Bluetooth_SendHCICommand(void* Parameters
, uint8_t ParamLength
)
41 uint8_t CommandBuffer
[sizeof(HCICommandHeader
) + HCICommandHeader
.ParameterLength
];
43 USB_ControlRequest
= (USB_Request_Header_t
)
45 bmRequestType
: (REQDIR_HOSTTODEVICE
| REQTYPE_CLASS
| REQREC_DEVICE
),
49 wLength
: sizeof(CommandBuffer
)
52 memset(CommandBuffer
, 0x00, sizeof(CommandBuffer
));
53 memcpy(CommandBuffer
, &HCICommandHeader
, sizeof(HCICommandHeader
));
56 memcpy(&CommandBuffer
[sizeof(HCICommandHeader
)], Parameters
, ParamLength
);
58 Pipe_SelectPipe(PIPE_CONTROLPIPE
);
60 return USB_Host_SendControlRequest(CommandBuffer
);
63 static bool Bluetooth_GetNextHCIEventHeader(void)
65 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE
);
68 if (!(Pipe_IsReadWriteAllowed()))
74 Pipe_Read_Stream_LE(&HCIEventHeader
, sizeof(HCIEventHeader
));
81 static void Bluetooth_DiscardRemainingHCIEventParameters(void)
83 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE
);
86 Pipe_Discard_Stream(HCIEventHeader
.ParameterLength
);
91 void Bluetooth_ProcessHCICommands(void)
95 switch (Bluetooth_HCIProcessingState
)
98 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE
);
99 Pipe_SetInfiniteINRequests();
101 memset(&Bluetooth_Connection
, 0x00, sizeof(Bluetooth_Connection
));
103 Bluetooth_HCIProcessingState
= Bluetooth_Init_Reset
;
105 case Bluetooth_Init_Reset
:
106 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
108 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_RESET
},
112 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_Reset", NULL
);
114 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
118 while (!(Bluetooth_GetNextHCIEventHeader()));
119 Bluetooth_DiscardRemainingHCIEventParameters();
120 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
122 Bluetooth_HCIProcessingState
= Bluetooth_Init_ReadBufferSize
;
124 case Bluetooth_Init_ReadBufferSize
:
125 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
127 OpCode
: {OGF
: OGF_CTRLR_INFORMATIONAL
, OCF
: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE
},
131 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL
);
133 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
137 while (!(Bluetooth_GetNextHCIEventHeader()));
138 Bluetooth_DiscardRemainingHCIEventParameters();
139 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
141 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetEventMask
;
143 case Bluetooth_Init_SetEventMask
:
144 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
146 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_SET_EVENT_MASK
},
150 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetEventMask", NULL
);
152 uint8_t EventMask
[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
153 ErrorCode
= Bluetooth_SendHCICommand(&EventMask
, 8);
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]);
159 while (!(Bluetooth_GetNextHCIEventHeader()));
160 Bluetooth_DiscardRemainingHCIEventParameters();
161 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
164 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetLocalName
;
166 case Bluetooth_Init_SetLocalName
:
167 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
169 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME
},
170 ParameterLength
: 248,
173 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL
);
174 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration
.Name
);
176 ErrorCode
= Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration
.Name
, strlen(Bluetooth_DeviceConfiguration
.Name
));
180 while (!(Bluetooth_GetNextHCIEventHeader()));
181 Bluetooth_DiscardRemainingHCIEventParameters();
182 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
184 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetDeviceClass
;
186 case Bluetooth_Init_SetDeviceClass
:
187 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
189 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE
},
193 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL
);
195 ErrorCode
= Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration
.Class
, 3);
199 while (!(Bluetooth_GetNextHCIEventHeader()));
200 Bluetooth_DiscardRemainingHCIEventParameters();
201 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
203 Bluetooth_HCIProcessingState
= Bluetooth_Init_WriteScanEnable
;
205 case Bluetooth_Init_WriteScanEnable
:
206 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
208 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE
},
212 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_WriteScanEnable", NULL
);
214 uint8_t Interval
= InquiryAndPageScans
;
215 ErrorCode
= Bluetooth_SendHCICommand(&Interval
, 1);
219 while (!(Bluetooth_GetNextHCIEventHeader()));
220 Bluetooth_DiscardRemainingHCIEventParameters();
221 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
223 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
225 case Bluetooth_PrepareToProcessEvents
:
226 BT_DEBUG("(HCI) Enter State: Bluetooth_ProcessEvents", NULL
);
228 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
230 case Bluetooth_ProcessEvents
:
231 if (Bluetooth_GetNextHCIEventHeader())
233 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader
.EventCode
);
235 if (HCIEventHeader
.EventCode
== EVENT_COMMAND_STATUS
)
237 Bluetooth_HCIEvent_CommandStatus_Header_t CommandStatusHeader
;
239 Pipe_Read_Stream_LE(&CommandStatusHeader
, sizeof(CommandStatusHeader
));
240 HCIEventHeader
.ParameterLength
-= sizeof(CommandStatusHeader
);
242 BT_DEBUG("(HCI) >> Command status: 0x%02X", CommandStatusHeader
.CommandStatus
);
244 if (CommandStatusHeader
.CommandStatus
)
245 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
247 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_REQUEST
)
249 Bluetooth_HCIEvent_ConnectionRequest_Header_t ConnectionRequestParams
;
251 Pipe_Read_Stream_LE(&ConnectionRequestParams
, sizeof(ConnectionRequestParams
));
252 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionRequestParams
);
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
);
262 memcpy(Bluetooth_TempDeviceAddress
, ConnectionRequestParams
.RemoteAddress
,
263 sizeof(Bluetooth_TempDeviceAddress
));
265 Bluetooth_HCIProcessingState
= (Bluetooth_Connection
.IsConnected
) ? Bluetooth_Conn_RejectConnection
:
266 Bluetooth_Conn_AcceptConnection
;
268 else if (HCIEventHeader
.EventCode
== EVENT_DISCONNECTION_COMPLETE
)
270 BT_DEBUG("(HCI) >> Disconnection from device complete.", NULL
);
271 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
273 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_COMPLETE
)
275 Bluetooth_HCIEvent_ConnectionComplete_Header_t ConnectionCompleteParams
;
277 Pipe_Read_Stream_LE(&ConnectionCompleteParams
, sizeof(ConnectionCompleteParams
));
278 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionCompleteParams
);
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
);
284 if (ConnectionCompleteParams
.Status
== 0x00)
286 memcpy(Bluetooth_Connection
.DeviceAddress
, ConnectionCompleteParams
.RemoteAddress
,
287 sizeof(Bluetooth_Connection
.DeviceAddress
));
288 Bluetooth_Connection
.ConnectionHandle
= ConnectionCompleteParams
.ConnectionHandle
;
289 Bluetooth_Connection
.IsConnected
= true;
292 else if (HCIEventHeader
.EventCode
== EVENT_PIN_CODE_REQUEST
)
294 Pipe_Read_Stream_LE(&Bluetooth_TempDeviceAddress
, sizeof(Bluetooth_TempDeviceAddress
));
295 HCIEventHeader
.ParameterLength
-= sizeof(Bluetooth_TempDeviceAddress
);
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]);
301 Bluetooth_HCIProcessingState
= Bluetooth_Conn_SendPINCode
;
304 BT_DEBUG("(HCI) -- Unread Event Param Length: %d", HCIEventHeader
.ParameterLength
);
306 Bluetooth_DiscardRemainingHCIEventParameters();
310 case Bluetooth_Conn_AcceptConnection
:
311 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
313 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
314 ParameterLength
: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_Params_t
),
317 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL
);
319 Bluetooth_HCICommand_AcceptConnectionRequest_Params_t AcceptConnectionParams
;
321 memcpy(AcceptConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
322 sizeof(Bluetooth_TempDeviceAddress
));
323 AcceptConnectionParams
.SlaveRole
= true;
325 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
327 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
329 case Bluetooth_Conn_RejectConnection
:
330 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
332 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
333 ParameterLength
: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_Params_t
),
336 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL
);
338 Bluetooth_HCICommand_RejectConnectionRequest_Params_t RejectConnectionParams
;
340 memcpy(RejectConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
341 sizeof(Bluetooth_TempDeviceAddress
));
342 RejectConnectionParams
.Reason
= ERROR_LIMITED_RESOURCES
;
344 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
346 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
348 case Bluetooth_Conn_SendPINCode
:
349 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
351 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY
},
352 ParameterLength
: sizeof(Bluetooth_HCICommand_PinCodeResponse_Params_t
),
355 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL
);
356 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration
.PINCode
);
358 Bluetooth_HCICommand_PinCodeResponse_Params_t PINCodeRequestParams
;
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
));
366 Bluetooth_SendHCICommand(&PINCodeRequestParams
, sizeof(PINCodeRequestParams
));
370 while (!(Bluetooth_GetNextHCIEventHeader()));
371 Bluetooth_DiscardRemainingHCIEventParameters();
372 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
374 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;