Massive cleanups to the incomplete BluetoothHost demo, to make the HCL layer code...
[pub/USBasp.git] / Demos / Host / Incomplete / BluetoothHost / Lib / BluetoothHCICommands.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2010.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
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.
20
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
28 this software.
29 */
30
31 #include "BluetoothHCICommands.h"
32
33 static Bluetooth_HCICommand_Header_t HCICommandHeader;
34 static Bluetooth_HCIEvent_Header_t HCIEventHeader;
35
36 uint8_t Bluetooth_HCIProcessingState;
37 uint8_t Bluetooth_HCINextState;
38 static uint8_t Bluetooth_TempDeviceAddress[6];
39
40 static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint8_t ParamLength)
41 {
42 uint8_t CommandBuffer[sizeof(HCICommandHeader) + HCICommandHeader.ParameterLength];
43
44 USB_ControlRequest = (USB_Request_Header_t)
45 {
46 .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_DEVICE),
47 .bRequest = 0,
48 .wValue = 0,
49 .wIndex = 0,
50 .wLength = sizeof(CommandBuffer)
51 };
52
53 memset(CommandBuffer, 0x00, sizeof(CommandBuffer));
54 memcpy(CommandBuffer, &HCICommandHeader, sizeof(HCICommandHeader));
55
56 if (ParamLength)
57 memcpy(&CommandBuffer[sizeof(HCICommandHeader)], Parameters, ParamLength);
58
59 Pipe_SelectPipe(PIPE_CONTROLPIPE);
60 return USB_Host_SendControlRequest(CommandBuffer);
61 }
62
63 void Bluetooth_ProcessHCICommands(void)
64 {
65 uint8_t ErrorCode;
66
67 switch (Bluetooth_HCIProcessingState)
68 {
69 case Bluetooth_ProcessEvents:
70 Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
71 Pipe_Unfreeze();
72
73 if (Pipe_IsReadWriteAllowed())
74 {
75 Pipe_Read_Stream_LE(&HCIEventHeader, sizeof(HCIEventHeader));
76
77 uint8_t EventParams[HCIEventHeader.ParameterLength];
78
79 Pipe_Read_Stream_LE(&EventParams, HCIEventHeader.ParameterLength);
80 Pipe_ClearIN();
81
82 BT_DEBUG("(HCI) Event Code: 0x%02X", HCIEventHeader.EventCode);
83
84 switch (HCIEventHeader.EventCode)
85 {
86 case EVENT_COMMAND_COMPLETE:
87 Bluetooth_HCIProcessingState = Bluetooth_HCINextState;
88
89 BT_DEBUG("(HCI) >> Command Complete (Opcode 0x%04x)",
90 ((Bluetooth_HCIEvent_CommandComplete_t*)&EventParams)->Opcode);
91 break;
92 case EVENT_COMMAND_STATUS:
93 if (((Bluetooth_HCIEvent_CommandStatus_t*)&EventParams)->Status)
94 Bluetooth_HCIProcessingState = Bluetooth_Init;
95
96 BT_DEBUG("(HCI) >> Command Status: 0x%02X",
97 ((Bluetooth_HCIEvent_CommandStatus_t*)&EventParams)->Status);
98 break;
99 case EVENT_CONNECTION_REQUEST:
100 memcpy(Bluetooth_TempDeviceAddress,
101 &((Bluetooth_HCIEvent_ConnectionRequest_t*)&EventParams)->RemoteAddress,
102 sizeof(Bluetooth_TempDeviceAddress));
103
104 Bluetooth_HCIProcessingState = (Bluetooth_Connection.IsConnected ||
105 (((Bluetooth_HCIEvent_ConnectionRequest_t*)&EventParams)->LinkType != 0x01)) ?
106 Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;
107
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]);
111 break;
112 case EVENT_PIN_CODE_REQUEST:
113 memcpy(Bluetooth_TempDeviceAddress,
114 &((Bluetooth_HCIEvent_PinCodeRequest_t*)&EventParams)->RemoteAddress,
115 sizeof(Bluetooth_TempDeviceAddress));
116
117 Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode;
118
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]);
122 break;
123 case EVENT_CONNECTION_COMPLETE:
124 memcpy(Bluetooth_Connection.RemoteAddress,
125 &((Bluetooth_HCIEvent_ConnectionComplete_t*)&EventParams)->RemoteAddress,
126 sizeof(Bluetooth_TempDeviceAddress));
127
128 Bluetooth_Connection.ConnectionHandle = ((Bluetooth_HCIEvent_ConnectionComplete_t*)&EventParams)->ConnectionHandle;
129 Bluetooth_Connection.IsConnected = true;
130
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);
136 break;
137 }
138 }
139
140 Pipe_Freeze();
141
142 break;
143 case Bluetooth_Init:
144 memset(&Bluetooth_Connection, 0x00, sizeof(Bluetooth_Connection));
145
146 Bluetooth_HCIProcessingState = Bluetooth_Init_Reset;
147 break;
148 case Bluetooth_Init_Reset:
149 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
150 {
151 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET},
152 ParameterLength: 0,
153 };
154
155 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_Reset", NULL);
156
157 ErrorCode = Bluetooth_SendHCICommand(NULL, 0);
158
159 Bluetooth_HCINextState = Bluetooth_Init_ReadBufferSize;
160 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
161 break;
162 case Bluetooth_Init_ReadBufferSize:
163 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
164 {
165 OpCode: {OGF: OGF_CTRLR_INFORMATIONAL, OCF: OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE},
166 ParameterLength: 0,
167 };
168
169 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_ReadBufferSize", NULL);
170
171 ErrorCode = Bluetooth_SendHCICommand(NULL, 0);
172
173 Bluetooth_HCINextState = Bluetooth_Init_SetLocalName;
174 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
175 break;
176 case Bluetooth_Init_SetLocalName:
177 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
178 {
179 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME},
180 ParameterLength: 248,
181 };
182
183 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetLocalName", NULL);
184 BT_DEBUG("(HCI) -- Name: %s", Bluetooth_DeviceConfiguration.Name);
185
186 ErrorCode = Bluetooth_SendHCICommand(Bluetooth_DeviceConfiguration.Name, strlen(Bluetooth_DeviceConfiguration.Name));
187
188 Bluetooth_HCINextState = Bluetooth_Init_SetDeviceClass;
189 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
190 break;
191 case Bluetooth_Init_SetDeviceClass:
192 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
193 {
194 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE},
195 ParameterLength: 3,
196 };
197
198 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_SetDeviceClass", NULL);
199
200 ErrorCode = Bluetooth_SendHCICommand(&Bluetooth_DeviceConfiguration.Class, 3);
201
202 Bluetooth_HCINextState = Bluetooth_Init_WriteScanEnable;
203 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
204 break;
205 case Bluetooth_Init_WriteScanEnable:
206 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
207 {
208 OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE},
209 ParameterLength: 1,
210 };
211
212 BT_DEBUG("(HCI) Enter State: Bluetooth_Init_WriteScanEnable", NULL);
213
214 uint8_t Interval = InquiryAndPageScans;
215 ErrorCode = Bluetooth_SendHCICommand(&Interval, 1);
216
217 Bluetooth_HCINextState = Bluetooth_ProcessEvents;
218 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
219 break;
220 case Bluetooth_Conn_AcceptConnection:
221 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
222 {
223 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST},
224 ParameterLength: sizeof(Bluetooth_HCICommand_AcceptConnectionRequest_t),
225 };
226
227 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_AcceptConnection", NULL);
228
229 Bluetooth_HCICommand_AcceptConnectionRequest_t AcceptConnectionParams;
230
231 memcpy(AcceptConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(Bluetooth_TempDeviceAddress));
232 AcceptConnectionParams.SlaveRole = true;
233
234 ErrorCode = Bluetooth_SendHCICommand(&AcceptConnectionParams, sizeof(AcceptConnectionParams));
235
236 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
237 break;
238 case Bluetooth_Conn_RejectConnection:
239 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
240 {
241 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST},
242 ParameterLength: sizeof(Bluetooth_HCICommand_RejectConnectionRequest_t),
243 };
244
245 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_RejectConnection", NULL);
246
247 Bluetooth_HCICommand_RejectConnectionRequest_t RejectConnectionParams;
248
249 memcpy(RejectConnectionParams.RemoteAddress, Bluetooth_TempDeviceAddress, sizeof(RejectConnectionParams.RemoteAddress));
250 RejectConnectionParams.Reason = ERROR_LIMITED_RESOURCES;
251
252 ErrorCode = Bluetooth_SendHCICommand(&RejectConnectionParams, sizeof(RejectConnectionParams));
253
254 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
255 break;
256 case Bluetooth_Conn_SendPINCode:
257 HCICommandHeader = (Bluetooth_HCICommand_Header_t)
258 {
259 OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY},
260 ParameterLength: sizeof(Bluetooth_HCICommand_PinCodeResponse_t),
261 };
262
263 BT_DEBUG("(HCI) Enter State: Bluetooth_Conn_SendPINCode", NULL);
264 BT_DEBUG("(HCI) -- PIN: %s", Bluetooth_DeviceConfiguration.PINCode);
265
266 Bluetooth_HCICommand_PinCodeResponse_t PINCodeRequestParams;
267
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));
271
272 ErrorCode = Bluetooth_SendHCICommand(&PINCodeRequestParams, sizeof(PINCodeRequestParams));
273
274 Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents;
275 break;
276 }
277 }