3 Copyright (C) Dean Camera, 2010.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all 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 uint8_t Bluetooth_HCINextState
;
38 static uint8_t Bluetooth_TempDeviceAddress
[6];
40 static uint8_t Bluetooth_SendHCICommand(void* Parameters
, uint8_t ParamLength
)
42 uint8_t CommandBuffer
[sizeof(HCICommandHeader
) + HCICommandHeader
.ParameterLength
];
44 USB_ControlRequest
= (USB_Request_Header_t
)
46 .bmRequestType
= (REQDIR_HOSTTODEVICE
| REQTYPE_CLASS
| REQREC_DEVICE
),
50 .wLength
= sizeof(CommandBuffer
)
53 memset(CommandBuffer
, 0x00, sizeof(CommandBuffer
));
54 memcpy(CommandBuffer
, &HCICommandHeader
, sizeof(HCICommandHeader
));
57 memcpy(&CommandBuffer
[sizeof(HCICommandHeader
)], Parameters
, ParamLength
);
59 Pipe_SelectPipe(PIPE_CONTROLPIPE
);
60 return USB_Host_SendControlRequest(CommandBuffer
);
63 void Bluetooth_ProcessHCICommands(void)
67 switch (Bluetooth_HCIProcessingState
)
69 case Bluetooth_ProcessEvents
:
70 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE
);
73 if (Pipe_IsReadWriteAllowed())
75 Pipe_Read_Stream_LE(&HCIEventHeader
, sizeof(HCIEventHeader
));
77 uint8_t EventParams
[HCIEventHeader
.ParameterLength
];
79 Pipe_Read_Stream_LE(&EventParams
, HCIEventHeader
.ParameterLength
);
82 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader
.EventCode
);
84 switch (HCIEventHeader
.EventCode
)
86 case EVENT_COMMAND_COMPLETE
:
87 Bluetooth_HCIProcessingState
= Bluetooth_HCINextState
;
89 BT_DEBUG("(HCI) >> Command Complete (Opcode 0x%04x)",
90 ((Bluetooth_HCIEvent_CommandComplete_t
*)&EventParams
)->Opcode
);
92 case EVENT_COMMAND_STATUS
:
93 if (((Bluetooth_HCIEvent_CommandStatus_t
*)&EventParams
)->Status
)
94 Bluetooth_HCIProcessingState
= Bluetooth_Init
;
96 BT_DEBUG("(HCI) >> Command Status: 0x%02X",
97 ((Bluetooth_HCIEvent_CommandStatus_t
*)&EventParams
)->Status
);
99 case EVENT_CONNECTION_REQUEST
:
100 memcpy(Bluetooth_TempDeviceAddress
,
101 &((Bluetooth_HCIEvent_ConnectionRequest_t
*)&EventParams
)->RemoteAddress
,
102 sizeof(Bluetooth_TempDeviceAddress
));
104 Bluetooth_HCIProcessingState
= (Bluetooth_Connection
.IsConnected
||
105 (((Bluetooth_HCIEvent_ConnectionRequest_t
*)&EventParams
)->LinkType
!= 0x01)) ?
106 Bluetooth_Conn_RejectConnection
: Bluetooth_Conn_AcceptConnection
;
108 BT_DEBUG("(HCI) >> Connection Request from Device %02X:%02X:%02X:%02X:%02X:%02X",
109 Bluetooth_TempDeviceAddress
[5], Bluetooth_TempDeviceAddress
[4], Bluetooth_TempDeviceAddress
[3],
110 Bluetooth_TempDeviceAddress
[2], Bluetooth_TempDeviceAddress
[1], Bluetooth_TempDeviceAddress
[0]);
112 case EVENT_PIN_CODE_REQUEST
:
113 memcpy(Bluetooth_TempDeviceAddress
,
114 &((Bluetooth_HCIEvent_PinCodeRequest_t
*)&EventParams
)->RemoteAddress
,
115 sizeof(Bluetooth_TempDeviceAddress
));
117 Bluetooth_HCIProcessingState
= Bluetooth_Conn_SendPINCode
;
119 BT_DEBUG("(HCI) >> PIN Request from Device %02X:%02X:%02X:%02X:%02X:%02X",
120 Bluetooth_TempDeviceAddress
[5], Bluetooth_TempDeviceAddress
[4], Bluetooth_TempDeviceAddress
[3],
121 Bluetooth_TempDeviceAddress
[2], Bluetooth_TempDeviceAddress
[1], Bluetooth_TempDeviceAddress
[0]);
123 case EVENT_CONNECTION_COMPLETE
:
124 memcpy(Bluetooth_Connection
.RemoteAddress
,
125 &((Bluetooth_HCIEvent_ConnectionComplete_t
*)&EventParams
)->RemoteAddress
,
126 sizeof(Bluetooth_TempDeviceAddress
));
128 Bluetooth_Connection
.ConnectionHandle
= ((Bluetooth_HCIEvent_ConnectionComplete_t
*)&EventParams
)->ConnectionHandle
;
129 Bluetooth_Connection
.IsConnected
= true;
131 BT_DEBUG("(HCI) >> Connection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X, Handle 0x%04x",
132 Bluetooth_Connection
.RemoteAddress
[5], Bluetooth_Connection
.RemoteAddress
[4],
133 Bluetooth_Connection
.RemoteAddress
[3], Bluetooth_Connection
.RemoteAddress
[2],
134 Bluetooth_Connection
.RemoteAddress
[1], Bluetooth_Connection
.RemoteAddress
[0],
135 Bluetooth_Connection
.ConnectionHandle
);
144 memset(&Bluetooth_Connection
, 0x00, sizeof(Bluetooth_Connection
));
146 Bluetooth_HCIProcessingState
= Bluetooth_Init_Reset
;
148 case Bluetooth_Init_Reset
:
149 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
151 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_RESET
},
155 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_Reset", NULL
);
157 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
159 Bluetooth_HCINextState
= Bluetooth_Init_ReadBufferSize
;
160 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
162 case Bluetooth_Init_ReadBufferSize
:
163 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
165 OpCode
: {OGF
: OGF_CTRLR_INFORMATIONAL
, OCF
: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE
},
169 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL
);
171 ErrorCode
= Bluetooth_SendHCICommand(NULL
, 0);
173 Bluetooth_HCINextState
= Bluetooth_Init_SetLocalName
;
174 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
176 case Bluetooth_Init_SetLocalName
:
177 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
179 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME
},
180 ParameterLength
: 248,
183 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL
);
184 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration
.Name
);
186 ErrorCode
= Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration
.Name
, strlen(Bluetooth_DeviceConfiguration
.Name
));
188 Bluetooth_HCINextState
= Bluetooth_Init_SetDeviceClass
;
189 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
191 case Bluetooth_Init_SetDeviceClass
:
192 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
194 OpCode
: {OGF
: OGF_CTRLR_BASEBAND
, OCF
: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE
},
198 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL
);
200 ErrorCode
= Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration
.Class
, 3);
202 Bluetooth_HCINextState
= Bluetooth_Init_WriteScanEnable
;
203 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
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);
217 Bluetooth_HCINextState
= Bluetooth_ProcessEvents
;
218 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
220 case Bluetooth_Conn_AcceptConnection
:
221 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
223 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST
},
224 ParameterLength
: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_t
),
227 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL
);
229 Bluetooth_HCICommand_AcceptConnectionRequest_t AcceptConnectionParams
;
231 memcpy(AcceptConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
, sizeof(Bluetooth_TempDeviceAddress
));
232 AcceptConnectionParams
.SlaveRole
= true;
234 ErrorCode
= Bluetooth_SendHCICommand(&AcceptConnectionParams
, sizeof(AcceptConnectionParams
));
236 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
238 case Bluetooth_Conn_RejectConnection
:
239 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
241 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST
},
242 ParameterLength
: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_t
),
245 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL
);
247 Bluetooth_HCICommand_RejectConnectionRequest_t RejectConnectionParams
;
249 memcpy(RejectConnectionParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
, sizeof(RejectConnectionParams
.RemoteAddress
));
250 RejectConnectionParams
.Reason
= ERROR_LIMITED_RESOURCES
;
252 ErrorCode
= Bluetooth_SendHCICommand(&RejectConnectionParams
, sizeof(RejectConnectionParams
));
254 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;
256 case Bluetooth_Conn_SendPINCode
:
257 HCICommandHeader
= (Bluetooth_HCICommand_Header_t
)
259 OpCode
: {OGF
: OGF_LINK_CONTROL
, OCF
: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY
},
260 ParameterLength
: sizeof(Bluetooth_HCICommand_PinCodeResponse_t
),
263 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL
);
264 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration
.PINCode
);
266 Bluetooth_HCICommand_PinCodeResponse_t PINCodeRequestParams
;
268 memcpy(PINCodeRequestParams
.RemoteAddress
, Bluetooth_TempDeviceAddress
, sizeof(Bluetooth_TempDeviceAddress
));
269 PINCodeRequestParams
.PINCodeLength
= strlen(Bluetooth_DeviceConfiguration
.PINCode
);
270 memcpy(PINCodeRequestParams
.PINCode
, Bluetooth_DeviceConfiguration
.PINCode
, sizeof(PINCodeRequestParams
.PINCode
));
272 ErrorCode
= Bluetooth_SendHCICommand(&PINCodeRequestParams
, sizeof(PINCodeRequestParams
));
274 Bluetooth_HCIProcessingState
= Bluetooth_ProcessEvents
;