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_HostRequest
= (USB_Host_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 return USB_Host_SendControlRequest(CommandBuffer
);
61 static bool Bluetooth_GetNextHCIEventHeader(void)
63 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE
);
66 if (!(Pipe_ReadWriteAllowed()))
69 Pipe_Read_Stream_LE(&HCIEventHeader
, sizeof(HCIEventHeader
));
74 static void Bluetooth_DiscardRemainingHCIEventParameters(void)
76 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE
);
77 Pipe_Discard_Stream(HCIEventHeader
.ParameterLength
);
78 Pipe_ClearCurrentBank();
81 void Bluetooth_ProcessHCICommands(void)
85 switch (Bluetooth_HCIProcessingState
)
88 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE
);
89 Pipe_SetInfiniteINRequests();
91 memset(&Bluetooth_Connection
, 0x00, sizeof(Bluetooth_Connection
));
93 Bluetooth_HCIProcessingState
= Bluetooth_Init_Reset
;
95 case Bluetooth_Init_Reset
:
96 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
98 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_RESET
},
102 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_Reset", NULL
);
104 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
108 while (!(Bluetooth_GetNextHCIEventHeader()));
109 Bluetooth_DiscardRemainingHCIEventParameters();
110 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
112 Bluetooth_HCIProcessingState
= Bluetooth_Init_ReadBufferSize
;
114 case Bluetooth_Init_ReadBufferSize
:
115 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
117 OpCode
: {OGF
: OGF_CTRLR_INFORMATIONAL
, OCF
: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE
},
121 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL
);
123 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
127 while (!(Bluetooth_GetNextHCIEventHeader()));
128 Bluetooth_DiscardRemainingHCIEventParameters();
129 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
131 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetEventMask
;
133 case Bluetooth_Init_SetEventMask
:
134 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
136 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_SET_EVENT_MASK
},
140 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetEventMask", NULL
);
142 uint8_t EventMask
[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
143 ErrorCode
= Bluetooth_SendHCICommand(&EventMask
, 8);
145 BT_DEBUG("(HCI) -- Event mask: 0x%02X%02X%02X%02X%02X%02X%02X%02X", EventMask
[7], EventMask
[6], EventMask
[5], EventMask
[4],
146 EventMask
[3], EventMask
[2], EventMask
[1], EventMask
[0]);
149 while (!(Bluetooth_GetNextHCIEventHeader()));
150 Bluetooth_DiscardRemainingHCIEventParameters();
151 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
154 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetLocalName
;
156 case Bluetooth_Init_SetLocalName
:
157 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
159 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME
},
160 ParameterLength
: 248,
163 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL
);
164 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration
.Name
);
166 ErrorCode
= Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration
.Name
, strlen(Bluetooth_DeviceConfiguration
.Name
));
170 while (!(Bluetooth_GetNextHCIEventHeader()));
171 Bluetooth_DiscardRemainingHCIEventParameters();
172 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
174 Bluetooth_HCIProcessingState
= Bluetooth_Init_SetDeviceClass
;
176 case Bluetooth_Init_SetDeviceClass
:
177 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
179 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE
},
183 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL
);
185 ErrorCode
= Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration
.Class
, 3);
189 while (!(Bluetooth_GetNextHCIEventHeader()));
190 Bluetooth_DiscardRemainingHCIEventParameters();
191 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
193 Bluetooth_HCIProcessingState
= Bluetooth_Init_WriteScanEnable
;
195 case Bluetooth_Init_WriteScanEnable
:
196 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
198 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE
},
202 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_WriteScanEnable", NULL
);
204 uint8_t Interval
= InquiryAndPageScans
;
205 ErrorCode
= Bluetooth_SendHCICommand(&Interval
, 1);
209 while (!(Bluetooth_GetNextHCIEventHeader()));
210 Bluetooth_DiscardRemainingHCIEventParameters();
211 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
213 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
215 case Bluetooth_PrepareToProcessEvents
:
216 BT_DEBUG("(HCI) Enter State: Bluetooth_ProcessEvents", NULL
);
218 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
220 case Bluetooth_ProcessEvents
:
221 if (Bluetooth_GetNextHCIEventHeader())
223 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader
.EventCode
);
225 if (HCIEventHeader
.EventCode
== EVENT_COMMAND_STATUS
)
227 Bluetooth_HCIEvent_CommandStatus_Header_t CommandStatusHeader
;
229 Pipe_Read_Stream_LE(&CommandStatusHeader
, sizeof(CommandStatusHeader
));
230 HCIEventHeader
.ParameterLength
-= sizeof(CommandStatusHeader
);
232 BT_DEBUG("(HCI) >> Command status: 0x%02X", CommandStatusHeader
.CommandStatus
);
234 if (CommandStatusHeader
.CommandStatus
)
235 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
237 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_REQUEST
)
239 Bluetooth_HCIEvent_ConnectionRequest_Header_t ConnectionRequestParams
;
241 Pipe_Read_Stream_LE(&ConnectionRequestParams
, sizeof(ConnectionRequestParams
));
242 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionRequestParams
);
244 BT_DEBUG("(HCI) >> Connection Request from device %02X:%02X:%02X:%02X:%02X:%02X",
245 ConnectionRequestParams
.RemoteAddress
[5], ConnectionRequestParams
.RemoteAddress
[4],
246 ConnectionRequestParams
.RemoteAddress
[3], ConnectionRequestParams
.RemoteAddress
[2],
247 ConnectionRequestParams
.RemoteAddress
[1], ConnectionRequestParams
.RemoteAddress
[0]);
248 BT_DEBUG("(HCI) -- Device Class: 0x%02X%04X", ConnectionRequestParams
.ClassOfDevice_Service
,
249 ConnectionRequestParams
.ClassOfDevice_MajorMinor
);
250 BT_DEBUG("(HCI) -- Link Type: 0x%02x", ConnectionRequestParams
.LinkType
);
252 memcpy(Bluetooth_TempDeviceAddress
, ConnectionRequestParams
.RemoteAddress
,
253 sizeof(Bluetooth_TempDeviceAddress
));
255 Bluetooth_HCIProcessingState
= (Bluetooth_Connection
.IsConnected
) ? Bluetooth_Conn_RejectConnection
:
256 Bluetooth_Conn_AcceptConnection
;
258 else if (HCIEventHeader
.EventCode
== EVENT_DISCONNECTION_COMPLETE
)
260 BT_DEBUG("(HCI) >> Disconnection from device complete.", NULL
);
261 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
263 else if (HCIEventHeader
.EventCode
== EVENT_CONNECTION_COMPLETE
)
265 Bluetooth_HCIEvent_ConnectionComplete_Header_t ConnectionCompleteParams
;
267 Pipe_Read_Stream_LE(&ConnectionCompleteParams
, sizeof(ConnectionCompleteParams
));
268 HCIEventHeader
.ParameterLength
-= sizeof(ConnectionCompleteParams
);
270 BT_DEBUG("(HCI) >> Connection to device complete.", NULL
);
271 BT_DEBUG("(HCI) -- Status: %d", ConnectionCompleteParams
.Status
);
272 BT_DEBUG("(HCI) -- Handle: %d", ConnectionCompleteParams
.ConnectionHandle
);
274 if (ConnectionCompleteParams
.Status
== 0x00)
276 memcpy(Bluetooth_Connection
.DeviceAddress
, ConnectionCompleteParams
.RemoteAddress
,
277 sizeof(Bluetooth_Connection
.DeviceAddress
));
278 Bluetooth_Connection
.ConnectionHandle
= ConnectionCompleteParams
.ConnectionHandle
;
279 Bluetooth_Connection
.IsConnected
= true;
282 else if (HCIEventHeader
.EventCode
== EVENT_PIN_CODE_REQUEST
)
284 Pipe_Read_Stream_LE(&Bluetooth_TempDeviceAddress
, sizeof(Bluetooth_TempDeviceAddress
));
285 HCIEventHeader
.ParameterLength
-= sizeof(Bluetooth_TempDeviceAddress
);
287 BT_DEBUG("(HCI) >> PIN code Request from device %02X:%02X:%02X:%02X:%02X:%02X",
288 Bluetooth_TempDeviceAddress
[5], Bluetooth_TempDeviceAddress
[4], Bluetooth_TempDeviceAddress
[3],
289 Bluetooth_TempDeviceAddress
[2], Bluetooth_TempDeviceAddress
[1], Bluetooth_TempDeviceAddress
[0]);
291 Bluetooth_HCIProcessingState
= Bluetooth_Conn_SendPINCode
;
294 BT_DEBUG("(HCI) -- Unread Event Param Length: %d", HCIEventHeader
.ParameterLength
);
296 Bluetooth_DiscardRemainingHCIEventParameters();
300 case Bluetooth_Conn_AcceptConnection
:
301 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
303 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
304 ParameterLength
: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_Params_t
),
307 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL
);
309 Bluetooth_HCICommand_AcceptConnectionRequest_Params_t AcceptConnectionParams
;
311 memcpy(AcceptConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
312 sizeof(Bluetooth_TempDeviceAddress
));
313 AcceptConnectionParams
.SlaveRole
= true;
315 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
317 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
319 case Bluetooth_Conn_RejectConnection
:
320 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
322 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
323 ParameterLength
: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_Params_t
),
326 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL
);
328 Bluetooth_HCICommand_RejectConnectionRequest_Params_t RejectConnectionParams
;
330 memcpy(RejectConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
331 sizeof(Bluetooth_TempDeviceAddress
));
332 RejectConnectionParams
.Reason
= ERROR_LIMITED_RESOURCES
;
334 Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
336 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;
338 case Bluetooth_Conn_SendPINCode
:
339 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
341 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY
},
342 ParameterLength
: sizeof(Bluetooth_HCICommand_PinCodeResponse_Params_t
),
345 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL
);
346 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration
.PINCode
);
348 Bluetooth_HCICommand_PinCodeResponse_Params_t PINCodeRequestParams
;
350 memcpy(PINCodeRequestParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
,
351 sizeof(Bluetooth_TempDeviceAddress
));
352 PINCodeRequestParams
.PINCodeLength
= strlen(Bluetooth_DeviceConfiguration
.PINCode
);
353 memcpy(PINCodeRequestParams
.PINCode
, Bluetooth_DeviceConfiguration
.PINCode
,
354 sizeof(Bluetooth_DeviceConfiguration
.PINCode
));
356 Bluetooth_SendHCICommand(&PINCodeRequestParams
, sizeof(PINCodeRequestParams
));
360 while (!(Bluetooth_GetNextHCIEventHeader()));
361 Bluetooth_DiscardRemainingHCIEventParameters();
362 } while (HCIEventHeader
.EventCode
!= EVENT_COMMAND_COMPLETE
);
364 Bluetooth_HCIProcessingState
= Bluetooth_PrepareToProcessEvents
;