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()))
119 if (USB_HostState
== HOST_STATE_Unattached
)
123 Bluetooth_DiscardRemainingHCIEventParameters();
124 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
126 Bluetooth_HCIProcessingState
= Bluetooth_Init_ReadBufferSize
;
128 case Bluetooth_Init_ReadBufferSize
:
129 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
131 OpCode
: {OGF
: OGF_CTRLR_INFORMATIONAL
, OCF
: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE
},
135 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL
);
137 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
141 while (!(Bluetooth_GetNextHCIEventHeader()))
143 if (USB_HostState
== HOST_STATE_Unattached
)
147 Bluetooth_DiscardRemainingHCIEventParameters();
148 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
150 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetEventMask
;
152 case Bluetooth_Init_SetEventMask
:
153 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
155 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_SET_EVENT_MASK
},
159 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetEventMask", NULL
);
161 uint8_t EventMask
[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
162 ErrorCode
= Bluetooth_SendHCICommand(&EventMask
, 8);
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]);
168 while (!(Bluetooth_GetNextHCIEventHeader()))
170 if (USB_HostState
== HOST_STATE_Unattached
)
174 Bluetooth_DiscardRemainingHCIEventParameters();
175 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
178 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetLocalName
;
180 case Bluetooth_Init_SetLocalName
:
181 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
183 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME
},
184 ParameterLength
: 248,
187 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL
);
188 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration
.Name
);
190 ErrorCode
= Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration
.Name
, strlen(Bluetooth_DeviceConfiguration
.Name
));
194 while (!(Bluetooth_GetNextHCIEventHeader()))
196 if (USB_HostState
== HOST_STATE_Unattached
)
200 Bluetooth_DiscardRemainingHCIEventParameters();
201 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
203 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetDeviceClass
;
205 case Bluetooth_Init_SetDeviceClass
:
206 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
208 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE
},
212 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL
);
214 ErrorCode
= Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration
.Class
, 3);
218 while (!(Bluetooth_GetNextHCIEventHeader()))
220 if (USB_HostState
== HOST_STATE_Unattached
)
224 Bluetooth_DiscardRemainingHCIEventParameters();
225 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
227 Bluetooth_HCIProcessingState
= Bluetooth_Init_WriteScanEnable
;
229 case Bluetooth_Init_WriteScanEnable
:
230 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
232 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE
},
236 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_WriteScanEnable", NULL
);
238 uint8_t Interval
= InquiryAndPageScans
;
239 ErrorCode
= Bluetooth_SendHCICommand(&Interval
, 1);
243 while (!(Bluetooth_GetNextHCIEventHeader()))
245 if (USB_HostState
== HOST_STATE_Unattached
)
249 Bluetooth_DiscardRemainingHCIEventParameters();
250 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
252 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
254 case Bluetooth_PrepareToProcessEvents
:
255 BT_DEBUG("(HCI) Enter State: Bluetooth_ProcessEvents", NULL
);
257 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
259 case Bluetooth_ProcessEvents
:
260 if (Bluetooth_GetNextHCIEventHeader())
262 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader
.EventCode
);
264 if (HCIEventHeader
.EventCode
== EVENT_COMMAND_STATUS
)
266 Bluetooth_HCIEvent_CommandStatus_Header_t CommandStatusHeader
;
268 Pipe_Read_Stream_LE(&CommandStatusHeader
, sizeof(CommandStatusHeader
));
269 HCIEventHeader
.ParameterLength
-= sizeof(CommandStatusHeader
);
271 BT_DEBUG("(HCI) >> Command status: 0x%02X", CommandStatusHeader
.CommandStatus
);
273 if (CommandStatusHeader
.CommandStatus
)
274 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
276 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_REQUEST
)
278 Bluetooth_HCIEvent_ConnectionRequest_Header_t ConnectionRequestParams
;
280 Pipe_Read_Stream_LE(&ConnectionRequestParams
, sizeof(ConnectionRequestParams
));
281 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionRequestParams
);
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
);
291 memcpy(Bluetooth_TempDeviceAddress
, ConnectionRequestParams
.RemoteAddress
,
292 sizeof(Bluetooth_TempDeviceAddress
));
294 Bluetooth_HCIProcessingState
= (Bluetooth_Connection
.IsConnected
) ? Bluetooth_Conn_RejectConnection
:
295 Bluetooth_Conn_AcceptConnection
;
297 else if (HCIEventHeader
.EventCode
== EVENT_DISCONNECTION_COMPLETE
)
299 BT_DEBUG("(HCI) >> Disconnection from device complete.", NULL
);
300 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
302 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_COMPLETE
)
304 Bluetooth_HCIEvent_ConnectionComplete_Header_t ConnectionCompleteParams
;
306 Pipe_Read_Stream_LE(&ConnectionCompleteParams
, sizeof(ConnectionCompleteParams
));
307 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionCompleteParams
);
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
);
313 if (ConnectionCompleteParams
.Status
== 0x00)
315 memcpy(Bluetooth_Connection
.DeviceAddress
, ConnectionCompleteParams
.RemoteAddress
,
316 sizeof(Bluetooth_Connection
.DeviceAddress
));
317 Bluetooth_Connection
.ConnectionHandle
= ConnectionCompleteParams
.ConnectionHandle
;
318 Bluetooth_Connection
.IsConnected
= true;
321 else if (HCIEventHeader
.EventCode
== EVENT_PIN_CODE_REQUEST
)
323 Pipe_Read_Stream_LE(&Bluetooth_TempDeviceAddress
, sizeof(Bluetooth_TempDeviceAddress
));
324 HCIEventHeader
.ParameterLength
-= sizeof(Bluetooth_TempDeviceAddress
);
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]);
330 Bluetooth_HCIProcessingState
= Bluetooth_Conn_SendPINCode
;
333 BT_DEBUG("(HCI) -- Unread Event Param Length: %d", HCIEventHeader
.ParameterLength
);
335 Bluetooth_DiscardRemainingHCIEventParameters();
339 case Bluetooth_Conn_AcceptConnection
:
340 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
342 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
343 ParameterLength
: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_Params_t
),
346 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL
);
348 Bluetooth_HCICommand_AcceptConnectionRequest_Params_t AcceptConnectionParams
;
350 memcpy(AcceptConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
351 sizeof(Bluetooth_TempDeviceAddress
));
352 AcceptConnectionParams
.SlaveRole
= true;
354 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
356 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
358 case Bluetooth_Conn_RejectConnection
:
359 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
361 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
362 ParameterLength
: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_Params_t
),
365 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL
);
367 Bluetooth_HCICommand_RejectConnectionRequest_Params_t RejectConnectionParams
;
369 memcpy(RejectConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
370 sizeof(Bluetooth_TempDeviceAddress
));
371 RejectConnectionParams
.Reason
= ERROR_LIMITED_RESOURCES
;
373 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
375 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
377 case Bluetooth_Conn_SendPINCode
:
378 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
380 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY
},
381 ParameterLength
: sizeof(Bluetooth_HCICommand_PinCodeResponse_Params_t
),
384 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL
);
385 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration
.PINCode
);
387 Bluetooth_HCICommand_PinCodeResponse_Params_t PINCodeRequestParams
;
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
));
395 Bluetooth_SendHCICommand(&PINCodeRequestParams
, sizeof(PINCodeRequestParams
));
399 while (!(Bluetooth_GetNextHCIEventHeader()))
401 if (USB_HostState
== HOST_STATE_Unattached
)
405 Bluetooth_DiscardRemainingHCIEventParameters();
406 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
408 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;