Changed stream wait timeout counter to be 16-bit, so that very long timeout periods...
[pub/USBasp.git] / Demos / BluetoothHost / BluetoothACLPackets.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2009.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
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.
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 #define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C
32 #include "BluetoothACLPackets.h"
33
34 void Bluetooth_ProcessACLPackets(void)
35 {
36 Bluetooth_ACL_Header_t ACLPacketHeader;
37
38 Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
39 Pipe_SetToken(PIPE_TOKEN_IN);
40 Pipe_Unfreeze();
41
42 if (!(Pipe_ReadWriteAllowed()))
43 {
44 Pipe_Freeze();
45 return;
46 }
47
48 Pipe_Read_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
49
50 Bluetooth_DataPacket_Header_t DataHeader;
51 Pipe_Read_Stream_LE(&DataHeader, sizeof(DataHeader));
52
53 BT_DEBUG("(ACL) Packet Received", NULL);
54 BT_DEBUG("(ACL) -- Connection Handle: 0x%04X", ACLPacketHeader.ConnectionHandle);
55 BT_DEBUG("(ACL) -- Data Length: 0x%04X", ACLPacketHeader.DataLength);
56 BT_DEBUG("(ACL) -- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
57 BT_DEBUG("(ACL) -- Payload Length: 0x%04X", DataHeader.PayloadLength);
58
59 if (DataHeader.DestinationChannel == BLUETOOTH_CHANNEL_SIGNALING)
60 {
61 Bluetooth_SignalCommand_Header_t SignalCommandHeader;
62 Pipe_Read_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader));
63
64 switch (SignalCommandHeader.Code)
65 {
66 case BLUETOOTH_SIGNAL_CONNECTION_REQUEST:
67 Bluetooth_ProcessSignalPacket_ConnectionRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
68 break;
69 case BLUETOOTH_SIGNAL_CONFIGURATION_REQUEST:
70 Bluetooth_ProcessSignalPacket_ConfigurationRequest(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
71 break;
72 default:
73 BT_DEBUG("(ACL) >> Unknown Signalling Command 0x%02X", SignalCommandHeader.Code);
74
75 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
76 Pipe_ClearCurrentBank();
77 Pipe_Freeze();
78 break;
79 }
80 }
81 else
82 {
83 uint8_t DataPayload[DataHeader.PayloadLength];
84 Pipe_Read_Stream_LE(&DataPayload, sizeof(DataPayload));
85 DataHeader.PayloadLength = 0;
86
87 BT_DEBUG("(ACL) -- Data Payload: ", NULL);
88 for (uint16_t B = 0; B < sizeof(DataPayload); B++)
89 printf("0x%02X ", DataPayload[B]);
90 BT_DEBUG("", NULL);
91
92 Pipe_Discard_Stream(ACLPacketHeader.DataLength);
93 Pipe_ClearCurrentBank();
94 Pipe_Freeze();
95 }
96 }
97
98 static inline void Bluetooth_ProcessSignalPacket_ConnectionRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
99 Bluetooth_DataPacket_Header_t* DataHeader,
100 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
101 {
102 Bluetooth_SignalCommand_ConnectionRequest_t ConnectionRequest;
103
104 Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));
105
106 BT_DEBUG("(ACL) >> L2CAP Connection Request", NULL);
107 BT_DEBUG("(ACL) -- PSM: 0x%04X", ConnectionRequest.PSM);
108 BT_DEBUG("(ACL) -- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
109
110 Pipe_ClearCurrentBank();
111 Pipe_Freeze();
112 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
113 Pipe_SetToken(PIPE_TOKEN_OUT);
114 Pipe_Unfreeze();
115
116 Bluetooth_SignalCommand_ConnectionResponse_t ConnectionResponse;
117
118 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
119 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
120 DataHeader->DestinationChannel = BLUETOOTH_CHANNEL_SIGNALING;
121 SignalCommandHeader->Code = BLUETOOTH_SIGNAL_CONNECTION_RESPONSE;
122 SignalCommandHeader->Length = sizeof(ConnectionResponse);
123
124 Bluetooth_Channel_t* ChannelData = Bluetooth_InitChannelData(ConnectionRequest.SourceChannel, ConnectionRequest.PSM);
125
126 ConnectionResponse.Result = (ChannelData == NULL) ? BLUETOOTH_CONNECTION_REFUSED_RESOURCES :
127 BLUETOOTH_CONNECTION_SUCCESSFUL;
128 ConnectionResponse.DestinationChannel = ChannelData->LocalNumber;
129 ConnectionResponse.SourceChannel = ChannelData->RemoteNumber;
130 ConnectionResponse.Status = 0x00;
131
132 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
133 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
134 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
135 Pipe_Write_Stream_LE(&ConnectionResponse, sizeof(ConnectionResponse));
136
137 Pipe_ClearCurrentBank();
138 Pipe_Freeze();
139
140 BT_DEBUG("(ACL) Packet Sent", NULL);
141 BT_DEBUG("(ACL) -- Connection Handle: 0x%04X", ACLPacketHeader->ConnectionHandle);
142 BT_DEBUG("(ACL) -- Data Length: 0x%04X", ACLPacketHeader->DataLength);
143 BT_DEBUG("(ACL) -- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
144 BT_DEBUG("(ACL) -- Payload Length: 0x%04X", DataHeader->PayloadLength);
145 BT_DEBUG("(ACL) >> L2CAP Connection Response", NULL);
146 BT_DEBUG("(ACL) -- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);
147 BT_DEBUG("(ACL) -- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
148 }
149
150 static inline void Bluetooth_ProcessSignalPacket_ConfigurationRequest(Bluetooth_ACL_Header_t* ACLPacketHeader,
151 Bluetooth_DataPacket_Header_t* DataHeader,
152 Bluetooth_SignalCommand_Header_t* SignalCommandHeader)
153 {
154 Bluetooth_SignalCommand_ConfigurationRequest_t ConfigurationRequest;
155
156 Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
157
158 BT_DEBUG("(ACL) >> L2CAP Configuration Request", NULL);
159 BT_DEBUG("(ACL) -- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
160
161 Pipe_ClearCurrentBank();
162 Pipe_Freeze();
163 Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
164 Pipe_SetToken(PIPE_TOKEN_OUT);
165 Pipe_Unfreeze();
166
167 Bluetooth_SignalCommand_ConfigurationResponse_t ConfigurationResponse;
168
169 ACLPacketHeader->DataLength = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
170 DataHeader->PayloadLength = sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
171 DataHeader->DestinationChannel = BLUETOOTH_CHANNEL_SIGNALING;
172 SignalCommandHeader->Code = BLUETOOTH_SIGNAL_CONFIGURATION_RESPONSE;
173 SignalCommandHeader->Length = sizeof(ConfigurationResponse);
174
175 Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, CHANNEL_LOOKUP_BY_DESTINATION);
176
177 if (ChannelData != NULL)
178 ChannelData->State = Channel_Open;
179
180 // TODO: Add channel config data to the tail of ConfigurationResponse
181
182 ConfigurationResponse.SourceChannel = ChannelData->RemoteNumber;
183 ConfigurationResponse.Flags = 0x00;
184 ConfigurationResponse.Result = (ChannelData != NULL) ? BLUETOOTH_CONFIGURATION_SUCCESSFUL : BLUETOOTH_CONFIGURATION_REJECTED;
185
186 Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
187 Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
188 Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
189 Pipe_Write_Stream_LE(&ConfigurationResponse, sizeof(ConfigurationResponse));
190
191 Pipe_ClearCurrentBank();
192 Pipe_Freeze();
193
194 BT_DEBUG("(ACL) Packet Sent", NULL);
195 BT_DEBUG("(ACL) -- Connection Handle: 0x%04X", ACLPacketHeader->ConnectionHandle);
196 BT_DEBUG("(ACL) -- Data Length: 0x%04X", ACLPacketHeader->DataLength);
197 BT_DEBUG("(ACL) -- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
198 BT_DEBUG("(ACL) -- Payload Length: 0x%04X", DataHeader->PayloadLength);
199 BT_DEBUG("(ACL) >> L2CAP Configuration Response", NULL);
200 }