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
);
100 memset(&Bluetooth_Connection
, 0x00, sizeof(Bluetooth_Connection
));
102 Bluetooth_HCIProcessingState
= Bluetooth_Init_Reset
;
104 case Bluetooth_Init_Reset
:
105 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
107 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_RESET
},
111 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_Reset", NULL
);
113 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
117 while (!(Bluetooth_GetNextHCIEventHeader()));
118 Bluetooth_DiscardRemainingHCIEventParameters();
119 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
121 Bluetooth_HCIProcessingState
= Bluetooth_Init_ReadBufferSize
;
123 case Bluetooth_Init_ReadBufferSize
:
124 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
126 OpCode
: {OGF
: OGF_CTRLR_INFORMATIONAL
, OCF
: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE
},
130 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL
);
132 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
136 while (!(Bluetooth_GetNextHCIEventHeader()));
137 Bluetooth_DiscardRemainingHCIEventParameters();
138 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
140 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetEventMask
;
142 case Bluetooth_Init_SetEventMask
:
143 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
145 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_SET_EVENT_MASK
},
149 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetEventMask", NULL
);
151 uint8_t EventMask
[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
152 ErrorCode
= Bluetooth_SendHCICommand(&EventMask
, 8);
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]);
158 while (!(Bluetooth_GetNextHCIEventHeader()));
159 Bluetooth_DiscardRemainingHCIEventParameters();
160 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
163 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetLocalName
;
165 case Bluetooth_Init_SetLocalName
:
166 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
168 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME
},
169 ParameterLength
: 248,
172 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL
);
173 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration
.Name
);
175 ErrorCode
= Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration
.Name
, strlen(Bluetooth_DeviceConfiguration
.Name
));
179 while (!(Bluetooth_GetNextHCIEventHeader()));
180 Bluetooth_DiscardRemainingHCIEventParameters();
181 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
183 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetDeviceClass
;
185 case Bluetooth_Init_SetDeviceClass
:
186 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
188 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE
},
192 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL
);
194 ErrorCode
= Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration
.Class
, 3);
198 while (!(Bluetooth_GetNextHCIEventHeader()));
199 Bluetooth_DiscardRemainingHCIEventParameters();
200 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
202 Bluetooth_HCIProcessingState
= Bluetooth_Init_WriteScanEnable
;
204 case Bluetooth_Init_WriteScanEnable
:
205 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
207 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE
},
211 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_WriteScanEnable", NULL
);
213 uint8_t Interval
= InquiryAndPageScans
;
214 ErrorCode
= Bluetooth_SendHCICommand(&Interval
, 1);
218 while (!(Bluetooth_GetNextHCIEventHeader()));
219 Bluetooth_DiscardRemainingHCIEventParameters();
220 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
222 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
224 case Bluetooth_PrepareToProcessEvents
:
225 BT_DEBUG("(HCI) Enter State: Bluetooth_ProcessEvents", NULL
);
227 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
229 case Bluetooth_ProcessEvents
:
230 if (Bluetooth_GetNextHCIEventHeader())
232 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader
.EventCode
);
234 if (HCIEventHeader
.EventCode
== EVENT_COMMAND_STATUS
)
236 Bluetooth_HCIEvent_CommandStatus_Header_t CommandStatusHeader
;
238 Pipe_Read_Stream_LE(&CommandStatusHeader
, sizeof(CommandStatusHeader
));
239 HCIEventHeader
.ParameterLength
-= sizeof(CommandStatusHeader
);
241 BT_DEBUG("(HCI) >> Command status: 0x%02X", CommandStatusHeader
.CommandStatus
);
243 if (CommandStatusHeader
.CommandStatus
)
244 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
246 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_REQUEST
)
248 Bluetooth_HCIEvent_ConnectionRequest_Header_t ConnectionRequestParams
;
250 Pipe_Read_Stream_LE(&ConnectionRequestParams
, sizeof(ConnectionRequestParams
));
251 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionRequestParams
);
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
);
261 memcpy(Bluetooth_TempDeviceAddress
, ConnectionRequestParams
.RemoteAddress
,
262 sizeof(Bluetooth_TempDeviceAddress
));
264 Bluetooth_HCIProcessingState
= (Bluetooth_Connection
.IsConnected
) ? Bluetooth_Conn_RejectConnection
:
265 Bluetooth_Conn_AcceptConnection
;
267 else if (HCIEventHeader
.EventCode
== EVENT_DISCONNECTION_COMPLETE
)
269 BT_DEBUG("(HCI) >> Disconnection from device complete.", NULL
);
270 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
272 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_COMPLETE
)
274 Bluetooth_HCIEvent_ConnectionComplete_Header_t ConnectionCompleteParams
;
276 Pipe_Read_Stream_LE(&ConnectionCompleteParams
, sizeof(ConnectionCompleteParams
));
277 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionCompleteParams
);
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
);
283 if (ConnectionCompleteParams
.Status
== 0x00)
285 memcpy(Bluetooth_Connection
.DeviceAddress
, ConnectionCompleteParams
.RemoteAddress
,
286 sizeof(Bluetooth_Connection
.DeviceAddress
));
287 Bluetooth_Connection
.ConnectionHandle
= ConnectionCompleteParams
.ConnectionHandle
;
288 Bluetooth_Connection
.IsConnected
= true;
291 else if (HCIEventHeader
.EventCode
== EVENT_PIN_CODE_REQUEST
)
293 Pipe_Read_Stream_LE(&Bluetooth_TempDeviceAddress
, sizeof(Bluetooth_TempDeviceAddress
));
294 HCIEventHeader
.ParameterLength
-= sizeof(Bluetooth_TempDeviceAddress
);
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]);
300 Bluetooth_HCIProcessingState
= Bluetooth_Conn_SendPINCode
;
303 BT_DEBUG("(HCI) -- Unread Event Param Length: %d", HCIEventHeader
.ParameterLength
);
305 Bluetooth_DiscardRemainingHCIEventParameters();
309 case Bluetooth_Conn_AcceptConnection
:
310 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
312 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
313 ParameterLength
: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_Params_t
),
316 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL
);
318 Bluetooth_HCICommand_AcceptConnectionRequest_Params_t AcceptConnectionParams
;
320 memcpy(AcceptConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
321 sizeof(Bluetooth_TempDeviceAddress
));
322 AcceptConnectionParams
.SlaveRole
= true;
324 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
326 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
328 case Bluetooth_Conn_RejectConnection
:
329 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
331 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
332 ParameterLength
: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_Params_t
),
335 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL
);
337 Bluetooth_HCICommand_RejectConnectionRequest_Params_t RejectConnectionParams
;
339 memcpy(RejectConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
340 sizeof(Bluetooth_TempDeviceAddress
));
341 RejectConnectionParams
.Reason
= ERROR_LIMITED_RESOURCES
;
343 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
345 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
347 case Bluetooth_Conn_SendPINCode
:
348 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
350 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY
},
351 ParameterLength
: sizeof(Bluetooth_HCICommand_PinCodeResponse_Params_t
),
354 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL
);
355 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration
.PINCode
);
357 Bluetooth_HCICommand_PinCodeResponse_Params_t PINCodeRequestParams
;
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
));
365 Bluetooth_SendHCICommand(&PINCodeRequestParams
, sizeof(PINCodeRequestParams
));
369 while (!(Bluetooth_GetNextHCIEventHeader()));
370 Bluetooth_DiscardRemainingHCIEventParameters();
371 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
373 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;