BluetoothACLPackets.c 19.3 KB
Newer Older
1
2
/*
             LUFA Library
Dean Camera's avatar
Dean Camera committed
3
     Copyright (C) Dean Camera, 2010.
4
5
6
7
8
9
              
  dean [at] fourwalledcubicle [dot] com
      www.fourwalledcubicle.com
*/

/*
Dean Camera's avatar
Dean Camera committed
10
  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
13
14
15
16
17
18
  Permission to use, copy, modify, distribute, and sell this 
  software and its documentation for any purpose is hereby granted
  without fee, provided that the above copyright notice appear in 
  all copies and that both that the copyright notice and this
  permission notice and warranty disclaimer appear in supporting 
  documentation, and that the name of the author not be used in 
  advertising or publicity pertaining to distribution of the 
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  software without specific, written prior permission.

  The author disclaim all warranties with regard to this
  software, including all implied warranties of merchantability
  and fitness.  In no event shall the author be liable for any
  special, indirect or consequential damages or any damages
  whatsoever resulting from loss of use, data or profits, whether
  in an action of contract, negligence or other tortious action,
  arising out of or in connection with the use or performance of
  this software.
*/

#define  INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C
#include "BluetoothACLPackets.h"

34
void Bluetooth_ACLTask(void)
35
{
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
	Bluetooth_ProcessACLPackets();
	
	for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
	{
		Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
	
		bool MustSendConfigReq = true;
	
		switch (ChannelData->State)
		{
			case Channel_Config_WaitConfig:
				ChannelData->State = Channel_Config_WaitReqResp;
				break;
			case Channel_Config_WaitSendConfig:
				ChannelData->State = Channel_Config_WaitResp;
				break;
			default:
				MustSendConfigReq  = false;
				break;
		}
		
		if (MustSendConfigReq)
		{
			BT_ACL_Header_t              ACLPacketHeader;
			BT_DataPacket_Header_t       DataHeader;
			BT_Signal_Header_t           SignalCommandHeader;
			BT_Signal_ConfigurationReq_t ConfigurationRequest;

			ACLPacketHeader.ConnectionHandle     = Bluetooth_Connection.ConnectionHandle;
			ACLPacketHeader.DataLength           = sizeof(DataHeader) + sizeof(SignalCommandHeader) + sizeof(ConfigurationRequest);
			DataHeader.PayloadLength             = sizeof(SignalCommandHeader) + sizeof(ConfigurationRequest);
			DataHeader.DestinationChannel        = BT_CHANNEL_SIGNALING;
			SignalCommandHeader.Code             = BT_SIGNAL_CONFIGURATION_REQUEST;
			SignalCommandHeader.Identifier       = ++Bluetooth_Connection.SignallingIdentifier;
			SignalCommandHeader.Length           = sizeof(ConfigurationRequest);
			
			ConfigurationRequest.DestinationChannel = ChannelData->RemoteNumber;
			ConfigurationRequest.Flags              = 0;

			Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
			Pipe_Unfreeze();
			
			Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
			Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
			Pipe_Write_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader));
			Pipe_Write_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));

			Pipe_Freeze();

			#if (ACL_DEBUG_LEVEL > 1)
			BT_ACL_DEBUG("Packet Sent", NULL);
			BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
			BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
			BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
			BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader.PayloadLength);			
			#endif
			#if (ACL_DEBUG_LEVEL > 0)
			BT_ACL_DEBUG(">> L2CAP Configuration Request", NULL);
			#endif
			#if (ACL_DEBUG_LEVEL > 1)
			BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
			#endif
		}
	}
}

static void Bluetooth_ProcessACLPackets(void)
{
	BT_ACL_Header_t        ACLPacketHeader;
	BT_DataPacket_Header_t DataHeader;
106
107
108
109
110
111
112
113
114
115
116
117
118

	Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
	Pipe_Unfreeze();
	
	if (!(Pipe_IsReadWriteAllowed()))
	{
		Pipe_Freeze();
		return;
	}
	  
	Pipe_Read_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
	Pipe_Read_Stream_LE(&DataHeader, sizeof(DataHeader));

119
	#if (ACL_DEBUG_LEVEL > 1)
120
121
122
123
124
	BT_ACL_DEBUG("Packet Received", NULL);
	BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF));
	BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader.DataLength);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader.DestinationChannel);
	BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader.PayloadLength);
125
	#endif
126

127
	if (DataHeader.DestinationChannel == BT_CHANNEL_SIGNALING)
128
	{
129
		BT_Signal_Header_t SignalCommandHeader;
130
131
132
133
		Pipe_Read_Stream_LE(&SignalCommandHeader, sizeof(SignalCommandHeader));

		switch (SignalCommandHeader.Code)
		{
134
			case BT_SIGNAL_CONNECTION_REQUEST:
135
				Bluetooth_Signal_ConnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
136
				break;
137
			case BT_SIGNAL_CONFIGURATION_REQUEST:
138
				Bluetooth_Signal_ConfigurationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
139
				break;
140
			case BT_SIGNAL_DISCONNECTION_REQUEST:
141
				Bluetooth_Signal_DisconnectionReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
142
				break;			
143
			case BT_SIGNAL_ECHO_REQUEST:
144
				Bluetooth_Signal_EchoReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
145
				break;
146
			case BT_SIGNAL_INFORMATION_REQUEST:
147
				Bluetooth_Signal_InformationReq(&ACLPacketHeader, &DataHeader, &SignalCommandHeader);
148
				break;
149
			default:
150
				#if (ACL_DEBUG_LEVEL > 0)
151
				BT_ACL_DEBUG("<< Unknown Signaling Command 0x%02X", SignalCommandHeader.Code);
152
153
				#endif
	
154
155
156
157
158
159
160
161
				Pipe_Discard_Stream(ACLPacketHeader.DataLength);
				Pipe_ClearIN();		
				Pipe_Freeze();
				break;
		}
	}
	else
	{
162
		Bluetooth_PacketReceived(&DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, true));
163
	
164
165
166
		Pipe_SelectPipe(BLUETOOTH_DATA_IN_PIPE);
		Pipe_Discard_Stream(DataHeader.PayloadLength);
		Pipe_ClearIN();
167
168
169
170
		Pipe_Freeze();
	}
}

171
uint8_t Bluetooth_SendPacket(uint8_t* Data, uint16_t DataLen, Bluetooth_Channel_t* Channel)
172
{
173
174
175
176
177
178
179
180
	BT_ACL_Header_t        ACLPacketHeader;
	BT_DataPacket_Header_t DataHeader;

	if (Bluetooth_Connection.IsConnected)
	  return BT_SENDPACKET_NotConnected;

	if (Channel->State != Channel_Open)
	  return BT_SENDPACKET_ChannelNotOpen;
181
182
183
184

	ACLPacketHeader.ConnectionHandle      = Bluetooth_Connection.ConnectionHandle;
	ACLPacketHeader.DataLength            = sizeof(DataHeader) + DataLen;
	DataHeader.DestinationChannel         = Channel->RemoteNumber;
185
	DataHeader.PayloadLength              = DataLen;
186
187
188
189
190
191
192
193
194

	Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
	Pipe_Unfreeze();
	
	Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader));
	Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader));
	Pipe_Write_Stream_LE(Data, DataLen);

	Pipe_Freeze();
195
196
	
	return BT_SENDPACKET_NoError;
197
198
}

199
200
201
static inline void Bluetooth_Signal_ConnectionReq(BT_ACL_Header_t* ACLPacketHeader,
                                                  BT_DataPacket_Header_t* DataHeader,
                                                  BT_Signal_Header_t* SignalCommandHeader)
202
{
203
	BT_Signal_ConnectionReq_t ConnectionRequest;
204
205
206
	
	Pipe_Read_Stream_LE(&ConnectionRequest, sizeof(ConnectionRequest));

207
	#if (ACL_DEBUG_LEVEL > 0)
208
	BT_ACL_DEBUG("<< L2CAP Connection Request", NULL);
209
210
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
211
212
	BT_ACL_DEBUG("-- PSM: 0x%04X", ConnectionRequest.PSM);
	BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
213
	#endif
214
215
216
217
218
219
	
	Pipe_ClearIN();
	Pipe_Freeze();
	Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
	Pipe_Unfreeze();
	
220
	BT_Signal_ConnectionResp_t ConnectionResponse;
221
222
223

	ACLPacketHeader->DataLength           = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
	DataHeader->PayloadLength             = sizeof(*SignalCommandHeader) + sizeof(ConnectionResponse);
224
225
	DataHeader->DestinationChannel        = BT_CHANNEL_SIGNALING;
	SignalCommandHeader->Code             = BT_SIGNAL_CONNECTION_RESPONSE;
226
227
228
229
	SignalCommandHeader->Length           = sizeof(ConnectionResponse);
	
	Bluetooth_Channel_t* ChannelData      = Bluetooth_InitChannelData(ConnectionRequest.SourceChannel, ConnectionRequest.PSM);
	
230
	ConnectionResponse.Result             = (ChannelData == NULL) ? BT_CONNECTION_REFUSED_RESOURCES : BT_CONNECTION_SUCCESSFUL;
231
232
233
234
235
236
237
238
239
240
241
242
	ConnectionResponse.DestinationChannel = ChannelData->LocalNumber;
	ConnectionResponse.SourceChannel      = ChannelData->RemoteNumber;
	ConnectionResponse.Status             = 0x00;

	Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
	Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
	Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
	Pipe_Write_Stream_LE(&ConnectionResponse, sizeof(ConnectionResponse));
	
	Pipe_ClearOUT();		
	Pipe_Freeze();
	
243
	#if (ACL_DEBUG_LEVEL > 1)
244
245
246
247
248
	BT_ACL_DEBUG("Packet Sent", NULL);
	BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
	BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
	BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);			
249
250
	#endif
	#if (ACL_DEBUG_LEVEL > 0)
251
	BT_ACL_DEBUG(">> L2CAP Connection Response", NULL);
252
253
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
254
255
	BT_ACL_DEBUG("-- Source Channel: 0x%04X", ConnectionResponse.SourceChannel);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
256
	#endif
257
258
}

259
260
261
static inline void Bluetooth_Signal_ConfigurationReq(BT_ACL_Header_t* ACLPacketHeader,
                                                     BT_DataPacket_Header_t* DataHeader,
                                                     BT_Signal_Header_t* SignalCommandHeader)
262
{
263
	BT_Signal_ConfigurationReq_t ConfigurationRequest;
264
	Pipe_Read_Stream_LE(&ConfigurationRequest, sizeof(ConfigurationRequest));
265
266
	
	// TODO: Process/Discard configuration options here
267
	Pipe_Discard_Stream(DataHeader->PayloadLength - sizeof(*SignalCommandHeader));
268

269
	#if (ACL_DEBUG_LEVEL > 0)
270
	BT_ACL_DEBUG("<< L2CAP Configuration Request", NULL);
271
272
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
273
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
274
	#endif
275
276
277
278
279
280
	
	Pipe_ClearIN();
	Pipe_Freeze();
	Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
	Pipe_Unfreeze();
	
281
	BT_Signal_ConfigurationResp_t ConfigurationResponse;
282
283
284

	ACLPacketHeader->DataLength           = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
	DataHeader->PayloadLength             = sizeof(*SignalCommandHeader) + sizeof(ConfigurationResponse);
285
286
	DataHeader->DestinationChannel        = BT_CHANNEL_SIGNALING;
	SignalCommandHeader->Code             = BT_SIGNAL_CONFIGURATION_RESPONSE;
287
288
	SignalCommandHeader->Length           = sizeof(ConfigurationResponse);
	
289
	Bluetooth_Channel_t* ChannelData      = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false);
290
291

	if (ChannelData != NULL)
292
293
294
295
296
297
298
299
300
301
302
303
304
305
	{
		switch (ChannelData->State)
		{
			case Channel_Config_WaitConfig:
				ChannelData->State = Channel_Config_WaitSendConfig;
				break;
			case Channel_Config_WaitReqResp:
				ChannelData->State = Channel_Config_WaitResp;
				break;
			case Channel_Config_WaitReq:
				ChannelData->State = Channel_Open;
				break;
		}
	}
306
	  
307
	// TODO: Add channel config data to the tail of ConfigurationResponse
308
309
310

	ConfigurationResponse.SourceChannel   = ChannelData->RemoteNumber;
	ConfigurationResponse.Flags           = 0x00;
311
	ConfigurationResponse.Result          = (ChannelData != NULL) ? BT_CONFIGURATION_SUCCESSFUL : BT_CONFIGURATION_REJECTED;
312
313
314
315
316
317

	Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
	Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
	Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
	Pipe_Write_Stream_LE(&ConfigurationResponse, sizeof(ConfigurationResponse));
	
318
	Pipe_ClearOUT();
319
320
	Pipe_Freeze();
	
321
	#if (ACL_DEBUG_LEVEL > 1)
322
323
324
325
326
	BT_ACL_DEBUG("Packet Sent", NULL);
	BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
	BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
	BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);			
327
328
	#endif
	#if (ACL_DEBUG_LEVEL > 0)
329
	BT_ACL_DEBUG(">> L2CAP Configuration Response", NULL);
330
331
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
332
	BT_ACL_DEBUG("-- Result: 0x%02X", ConfigurationResponse.Result);
333
	#endif
334
}
335

336
337
338
static inline void Bluetooth_Signal_DisconnectionReq(BT_ACL_Header_t* ACLPacketHeader,
                                                     BT_DataPacket_Header_t* DataHeader,
                                                     BT_Signal_Header_t* SignalCommandHeader)
339
{
340
	BT_Signal_DisconnectionReq_t DisconnectionRequest;
341
342
343
	
	Pipe_Read_Stream_LE(&DisconnectionRequest, sizeof(DisconnectionRequest));

344
	#if (ACL_DEBUG_LEVEL > 0)
345
	BT_ACL_DEBUG("<< L2CAP Disconnection Request", NULL);
346
347
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
348
349
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionRequest.DestinationChannel);
	BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionRequest.SourceChannel);
350
	#endif
351
352
353
354
355
356
	
	Pipe_ClearIN();
	Pipe_Freeze();
	Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
	Pipe_Unfreeze();
	
357
	BT_Signal_DisconnectionResp_t DisconnectionResponse;
358
359
360

	ACLPacketHeader->DataLength           = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
	DataHeader->PayloadLength             = sizeof(*SignalCommandHeader) + sizeof(DisconnectionResponse);
361
362
	DataHeader->DestinationChannel        = BT_CHANNEL_SIGNALING;
	SignalCommandHeader->Code             = BT_SIGNAL_DISCONNECTION_RESPONSE;
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
	SignalCommandHeader->Length           = sizeof(DisconnectionResponse);
	
	Bluetooth_Channel_t* ChannelData      = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true);

	if (ChannelData != NULL)
	  ChannelData->State = Channel_Closed;
	
	DisconnectionResponse.DestinationChannel = ChannelData->LocalNumber;
	DisconnectionResponse.SourceChannel      = ChannelData->RemoteNumber;

	Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
	Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
	Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
	Pipe_Write_Stream_LE(&DisconnectionResponse, sizeof(DisconnectionResponse));
	
	Pipe_ClearOUT();
	Pipe_Freeze();
	
381
	#if (ACL_DEBUG_LEVEL > 1)
382
383
384
385
386
	BT_ACL_DEBUG("Packet Sent", NULL);
	BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
	BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
	BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);			
387
388
	#endif
	#if (ACL_DEBUG_LEVEL > 0)
389
	BT_ACL_DEBUG(">> L2CAP Disconnection Response", NULL);
390
391
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
392
393
	BT_ACL_DEBUG("-- Source Channel: 0x%04X", DisconnectionResponse.SourceChannel);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DisconnectionResponse.DestinationChannel);
394
	#endif
395
396
}

397
398
399
static inline void Bluetooth_Signal_EchoReq(BT_ACL_Header_t* ACLPacketHeader,
                                            BT_DataPacket_Header_t* DataHeader,
                                            BT_Signal_Header_t* SignalCommandHeader)
400
{
401
	#if (ACL_DEBUG_LEVEL > 0)
402
	BT_ACL_DEBUG("<< L2CAP Echo Request", NULL);
403
	#endif
404
405
406
407
408
409
410
411
	
	Pipe_ClearIN();
	Pipe_Freeze();
	Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
	Pipe_Unfreeze();
	
	ACLPacketHeader->DataLength           = sizeof(*DataHeader) + sizeof(*SignalCommandHeader);
	DataHeader->PayloadLength             = sizeof(*SignalCommandHeader);
412
413
	DataHeader->DestinationChannel        = BT_CHANNEL_SIGNALING;
	SignalCommandHeader->Code             = BT_SIGNAL_ECHO_RESPONSE;
414
415
416
417
418
419
420
421
422
	SignalCommandHeader->Length           = 0;
	
	Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
	Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
	Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
	
	Pipe_ClearOUT();		
	Pipe_Freeze();
	
423
	#if (ACL_DEBUG_LEVEL > 1)
424
425
426
427
428
	BT_ACL_DEBUG("Packet Sent", NULL);
	BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
	BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
	BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);			
429
430
	#endif
	#if (ACL_DEBUG_LEVEL > 0)
431
	BT_ACL_DEBUG(">> L2CAP Echo Response", NULL);
432
	#endif
433
434
}

435
436
437
static inline void Bluetooth_Signal_InformationReq(BT_ACL_Header_t* ACLPacketHeader,
                                                   BT_DataPacket_Header_t* DataHeader,
                                                   BT_Signal_Header_t* SignalCommandHeader)
438
{
439
	BT_Signal_InformationReq_t InformationRequest;
440
441
442

	Pipe_Read_Stream_LE(&InformationRequest, sizeof(InformationRequest));

443
	#if (ACL_DEBUG_LEVEL > 0)
444
	BT_ACL_DEBUG("<< Information Request", NULL);
445
446
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
447
	BT_ACL_DEBUG("-- Info Type: 0x%04X", InformationRequest.InfoType);
448
	#endif
449
450
451
452
453
454
	
	Pipe_ClearIN();
	Pipe_Freeze();
	Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE);
	Pipe_Unfreeze();
	
455
	BT_Signal_InformationResp_t InformationResponse;
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
	uint8_t ResponseData[4];
	uint8_t ResponseLen;

	switch (InformationRequest.InfoType)
	{
		case BT_INFOREQ_MTU:		
			InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
			ResponseLen = 2;
			
			*((uint16_t*)&ResponseData) = 65533;
			break;
		case BT_INFOREQ_EXTENDEDFEATURES:
			InformationResponse.Result = BT_INFORMATION_SUCCESSFUL;
			ResponseLen = 4;
			
			*((uint32_t*)&ResponseData) = 0;
			break;
		default:
			InformationResponse.Result = BT_INFORMATION_NOTSUPPORTED;
			ResponseLen = 0;
			break;
	}
	
	ACLPacketHeader->DataLength           = sizeof(*DataHeader) + sizeof(*SignalCommandHeader) + sizeof(InformationResponse) +
	                                        ResponseLen;
	DataHeader->PayloadLength             = sizeof(*SignalCommandHeader) + sizeof(InformationResponse) + ResponseLen;
	DataHeader->DestinationChannel        = BT_CHANNEL_SIGNALING;
	SignalCommandHeader->Code             = BT_SIGNAL_INFORMATION_RESPONSE;
	SignalCommandHeader->Length           = sizeof(InformationResponse) + ResponseLen;
	
	Pipe_Write_Stream_LE(ACLPacketHeader, sizeof(*ACLPacketHeader));
	Pipe_Write_Stream_LE(DataHeader, sizeof(*DataHeader));
	Pipe_Write_Stream_LE(SignalCommandHeader, sizeof(*SignalCommandHeader));
	Pipe_Write_Stream_LE(&InformationResponse, sizeof(InformationResponse));
	Pipe_Write_Stream_LE(ResponseData, ResponseLen);
	
	Pipe_ClearOUT();		
	Pipe_Freeze();

495
	#if (ACL_DEBUG_LEVEL > 1)
496
497
498
499
500
	BT_ACL_DEBUG("Packet Sent", NULL);
	BT_ACL_DEBUG("-- Connection Handle: 0x%04X", (ACLPacketHeader->ConnectionHandle & 0x0FFF));
	BT_ACL_DEBUG("-- Data Length: 0x%04X", ACLPacketHeader->DataLength);
	BT_ACL_DEBUG("-- Destination Channel: 0x%04X", DataHeader->DestinationChannel);
	BT_ACL_DEBUG("-- Payload Length: 0x%04X", DataHeader->PayloadLength);			
501
502
	#endif
	#if (ACL_DEBUG_LEVEL > 0)
503
	BT_ACL_DEBUG(">> L2CAP Information Response", NULL);	
504
505
	#endif
	#if (ACL_DEBUG_LEVEL > 1)
506
	BT_ACL_DEBUG("-- Result: 0x%02X", InformationResponse.Result);
507
	#endif
508
}