1/*
2 * Copyright 2008, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
7 */
8
9#include <new>
10#include <errno.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include <KernelExport.h>
15#include <lock.h>
16#include <SupportDefs.h>
17#include <util/AutoLock.h>
18#include <util/DoublyLinkedList.h>
19
20#include <net_buffer.h>
21#include <net_device.h>
22#include <net_stack.h>
23#include <NetBufferUtilities.h>
24
25#include <btDebug.h>
26#include <btCoreData.h>
27#include <btModules.h>
28#include <CodeHandler.h>
29#define KERNEL_LAND
30#include <PortListener.h>
31#undef KERNEL_LAND
32
33#include <bluetooth/HCI/btHCI.h>
34#include <bluetooth/HCI/btHCI_acl.h>
35#include <bluetooth/HCI/btHCI_command.h>
36#include <bluetooth/HCI/btHCI_event.h>
37#include <bluetooth/HCI/btHCI_transport.h>
38#include <bluetooth/HCI/btHCI_sco.h>
39#include <bluetooth/bdaddrUtils.h>
40
41#include "acl.h"
42
43
44int32 api_version = B_CUR_DRIVER_API_VERSION;
45
46
47typedef PortListener<void,
48	HCI_MAX_FRAME_SIZE, // Event Body can hold max 255 + 2 header
49	24					// Some devices have sent chunks of 24 events(inquiry result)
50	> BluetoothRawDataPort;
51
52
53// Modules references
54net_buffer_module_info* gBufferModule = NULL;
55struct bluetooth_core_data_module_info* btCoreData = NULL;
56
57static mutex sListLock;
58static sem_id sLinkChangeSemaphore;
59static DoublyLinkedList<bluetooth_device> sDeviceList;
60
61BluetoothRawDataPort* BluetoothRXPort;
62
63// forward declarations
64status_t HciPacketHandler(void* data, int32 code, size_t size);
65
66
67bluetooth_device*
68FindDeviceByID(hci_id hid)
69{
70	bluetooth_device* device;
71
72	DoublyLinkedList<bluetooth_device>::Iterator iterator
73		= sDeviceList.GetIterator();
74
75	while (iterator.HasNext()) {
76		device = iterator.Next();
77		if (device->index == hid)
78			return device;
79	}
80
81	return NULL;
82}
83
84
85status_t
86PostTransportPacket(hci_id hid, bt_packet_t type, void* data, size_t count)
87{
88	uint32 code = 0;
89
90	Bluetooth::CodeHandler::SetDevice(&code, hid);
91	Bluetooth::CodeHandler::SetProtocol(&code, type);
92
93	return BluetoothRXPort->Trigger(code, data, count);
94}
95
96
97status_t
98Assemble(bluetooth_device* bluetoothDevice, bt_packet_t type, void* data,
99	size_t count)
100{
101	net_buffer* nbuf = bluetoothDevice->fBuffersRx[type];
102
103	size_t currentPacketLen = 0;
104
105	while (count) {
106
107		if (nbuf == NULL) {
108			// new buffer incoming
109			switch (type) {
110				case BT_EVENT:
111					if (count >= HCI_EVENT_HDR_SIZE) {
112						struct hci_event_header* headerPacket
113							= (struct hci_event_header*)data;
114						bluetoothDevice->fExpectedPacketSize[type]
115							= HCI_EVENT_HDR_SIZE + headerPacket->elen;
116
117						if (count >= bluetoothDevice->fExpectedPacketSize[type]) {
118							// the whole packet is here so it can be already posted.
119							ERROR("%s: EVENT posted in HCI!!!\n", __func__);
120							btCoreData->PostEvent(bluetoothDevice, data,
121								bluetoothDevice->fExpectedPacketSize[type]);
122
123						} else {
124							nbuf = gBufferModule->create(
125								bluetoothDevice->fExpectedPacketSize[type]);
126							bluetoothDevice->fBuffersRx[type] = nbuf;
127
128							nbuf->protocol = type;
129						}
130
131					} else {
132						panic("EVENT frame corrupted\n");
133						return EILSEQ;
134					}
135					break;
136
137				case BT_ACL:
138					if (count >= HCI_ACL_HDR_SIZE) {
139						struct hci_acl_header* headerPkt = (struct hci_acl_header*)data;
140
141						bluetoothDevice->fExpectedPacketSize[type] = HCI_ACL_HDR_SIZE
142							+ B_LENDIAN_TO_HOST_INT16(headerPkt->alen);
143
144						// Create the buffer -> TODO: this allocation can fail
145						nbuf = gBufferModule->create(
146							bluetoothDevice->fExpectedPacketSize[type]);
147						bluetoothDevice->fBuffersRx[type] = nbuf;
148
149						nbuf->protocol = type;
150					} else {
151						panic("ACL frame corrupted\n");
152						return EILSEQ;
153					}
154					break;
155
156				case BT_SCO:
157
158					break;
159
160				default:
161					panic("unknown packet type in assembly");
162					break;
163			}
164
165			currentPacketLen = bluetoothDevice->fExpectedPacketSize[type];
166
167		} else {
168			// Continuation of a packet
169			currentPacketLen = bluetoothDevice->fExpectedPacketSize[type] - nbuf->size;
170		}
171		if (nbuf != NULL) {
172			currentPacketLen = min_c(currentPacketLen, count);
173
174			gBufferModule->append(nbuf, data, currentPacketLen);
175
176			if ((bluetoothDevice->fExpectedPacketSize[type] - nbuf->size) == 0) {
177
178				switch (nbuf->protocol) {
179					case BT_EVENT:
180						panic("need to send full buffer to btdatacore!\n");
181						btCoreData->PostEvent(bluetoothDevice, data,
182							bluetoothDevice->fExpectedPacketSize[type]);
183
184						break;
185					case BT_ACL:
186						// TODO: device descriptor has been fetched better not
187						// pass id again
188						TRACE("%s: ACL parsed in ACL!\n", __func__);
189						AclAssembly(nbuf, bluetoothDevice->index);
190						break;
191					default:
192
193						break;
194				}
195
196				bluetoothDevice->fBuffersRx[type] = nbuf = NULL;
197				bluetoothDevice->fExpectedPacketSize[type] = 0;
198			} else {
199				if (type == BT_ACL) {
200					TRACE("%s: ACL Packet not filled size %" B_PRIu32
201						" expected=%" B_PRIuSIZE "\n", __func__, nbuf->size,
202						bluetoothDevice->fExpectedPacketSize[type]);
203				}
204			}
205
206		}
207		// in case in the pipe there is info about the next buffer
208		count -= currentPacketLen;
209		data = (void*)((uint8*)data + currentPacketLen);
210	}
211
212	return B_OK;
213}
214
215
216status_t
217HciPacketHandler(void* data, int32 code, size_t size)
218{
219	hci_id deviceId = Bluetooth::CodeHandler::Device(code);
220
221	bluetooth_device* bluetoothDevice = FindDeviceByID(deviceId);
222
223	TRACE("%s: to assemble %" B_PRIuSIZE " bytes of 0x%" B_PRIx32 "\n",
224		__func__, size, deviceId);
225
226	if (bluetoothDevice != NULL) {
227		return Assemble(bluetoothDevice, Bluetooth::CodeHandler::Protocol(code),
228			data, size);
229	} else {
230		ERROR("%s: Device 0x%" B_PRIx32 " could not be matched\n", __func__,
231			deviceId);
232	}
233
234	return B_ERROR;
235}
236
237
238//	#pragma mark -
239
240
241status_t
242RegisterDriver(bt_hci_transport_hooks* hooks, bluetooth_device** _device)
243{
244
245	bluetooth_device* device = new (std::nothrow) bluetooth_device;
246	if (device == NULL)
247		return B_NO_MEMORY;
248
249	for (int index = 0; index < HCI_NUM_PACKET_TYPES; index++) {
250		device->fBuffersRx[index] = NULL;
251		device->fExpectedPacketSize[index] = 0;
252	}
253
254	device->info = NULL; // not yet used
255	device->hooks = hooks;
256	device->supportedPacketTypes = (HCI_DM1 | HCI_DH1 | HCI_HV1);
257	device->linkMode = (HCI_LM_ACCEPT);
258	device->mtu = L2CAP_MTU_MINIMUM; // TODO: ensure specs min value
259
260	MutexLocker _(&sListLock);
261
262	if (sDeviceList.IsEmpty())
263		device->index = HCI_DEVICE_INDEX_OFFSET; // REVIEW: dev index
264	else {
265		device->index = (sDeviceList.Tail())->index + 1; // REVIEW!
266		TRACE("%s: List not empty\n", __func__);
267	}
268
269	sDeviceList.Add(device);
270
271	TRACE("%s: Device %" B_PRIx32 "\n", __func__, device->index);
272
273	*_device = device;
274
275	return B_OK;
276}
277
278
279status_t
280UnregisterDriver(hci_id id)
281{
282	bluetooth_device* device = FindDeviceByID(id);
283
284	if (device == NULL)
285		return B_ERROR;
286
287	if (device->GetDoublyLinkedListLink()->next != NULL
288		|| device->GetDoublyLinkedListLink()->previous != NULL
289		|| device == sDeviceList.Head())
290		sDeviceList.Remove(device);
291
292	delete device;
293
294	return B_OK;
295}
296
297
298// PostACL
299status_t
300PostACL(hci_id hciId, net_buffer* buffer)
301{
302	net_buffer* curr_frame = NULL;
303	net_buffer* next_frame = buffer;
304	uint8 flag = HCI_ACL_PACKET_START;
305
306	if (buffer == NULL)
307		panic("passing null buffer");
308
309	uint16 handle = buffer->type; // TODO: CodeHandler
310
311	bluetooth_device* device = FindDeviceByID(hciId);
312
313	if (device == NULL) {
314		ERROR("%s: No device 0x%" B_PRIx32 "\n", __func__, hciId);
315		return B_ERROR;
316	}
317
318	TRACE("%s: index 0x%" B_PRIx32 " try to send bt packet of %" B_PRIu32
319		" bytes (flags 0x%" B_PRIx32 "):\n", __func__, device->index,
320		buffer->size, buffer->flags);
321
322	// TODO: ATOMIC! any other thread should stop here
323	do {
324		// Divide packet if big enough
325		curr_frame = next_frame;
326
327		if (curr_frame->size > device->mtu) {
328			next_frame = gBufferModule->split(curr_frame, device->mtu);
329		} else {
330			next_frame = NULL;
331		}
332
333		// Attach acl header
334		{
335			NetBufferPrepend<struct hci_acl_header> bufferHeader(curr_frame);
336			status_t status = bufferHeader.Status();
337			if (status < B_OK) {
338				// free the buffer
339				continue;
340			}
341
342			bufferHeader->handle = pack_acl_handle_flags(handle, flag, 0);
343			bufferHeader->alen = curr_frame->size - sizeof(struct hci_acl_header);
344		}
345
346		// Send to driver
347		curr_frame->protocol = BT_ACL;
348
349		TRACE("%s: Tolower nbuf %p!\n", __func__, curr_frame);
350		// We could pass a cookie and avoid the driver fetch the Id
351		device->hooks->SendACL(device->index, curr_frame);
352		flag = HCI_ACL_PACKET_FRAGMENT;
353
354	} while (next_frame != NULL);
355
356	return B_OK;
357}
358
359
360status_t
361PostSCO(hci_id hciId, net_buffer* buffer)
362{
363	return B_ERROR;
364}
365
366
367status_t
368PostESCO(hci_id hciId, net_buffer* buffer)
369{
370	return B_ERROR;
371}
372
373
374static int
375dump_bluetooth_devices(int argc, char** argv)
376{
377	bluetooth_device*	device;
378
379	DoublyLinkedList<bluetooth_device>::Iterator iterator
380		= sDeviceList.GetIterator();
381
382	while (iterator.HasNext()) {
383		device = iterator.Next();
384		kprintf("\tindex=%" B_PRIx32 " @%p hooks=%p\n", device->index,
385			device, device->hooks);
386	}
387
388	return 0;
389}
390
391
392static status_t
393bluetooth_std_ops(int32 op, ...)
394{
395	switch (op) {
396		case B_MODULE_INIT:
397		{
398			status_t status;
399
400			status = get_module(NET_BUFFER_MODULE_NAME,
401				(module_info**)&gBufferModule);
402
403			if (status < B_OK) {
404				panic("no way Dude we need that!");
405				return status;
406			}
407
408			status = get_module(BT_CORE_DATA_MODULE_NAME,
409				(module_info**)&btCoreData);
410			if (status < B_OK) {
411				ERROR("%s: problem getting bt core data module\n", __func__);
412				return status;
413			}
414
415			new (&sDeviceList) DoublyLinkedList<bluetooth_device>;
416				// static C++ objects are not initialized in the module startup
417
418			BluetoothRXPort = new BluetoothRawDataPort(BT_RX_PORT_NAME,
419				(BluetoothRawDataPort::port_listener_func)&HciPacketHandler);
420
421			if (BluetoothRXPort->Launch() != B_OK) {
422				ERROR("%s: RX thread creation failed!\n", __func__);
423				// we Cannot do much here ... avoid registering
424			} else {
425				TRACE("%s: RX thread launched!\n", __func__);
426			}
427
428			sLinkChangeSemaphore = create_sem(0, "bt sem");
429			if (sLinkChangeSemaphore < B_OK) {
430				put_module(NET_STACK_MODULE_NAME);
431				ERROR("%s: Link change semaphore failed\n", __func__);
432				return sLinkChangeSemaphore;
433			}
434
435			mutex_init(&sListLock, "bluetooth devices");
436
437			// status = InitializeAclConnectionThread();
438			ERROR("%s: Connection Thread error\n", __func__);
439
440			add_debugger_command("btLocalDevices", &dump_bluetooth_devices,
441				"Lists Bluetooth LocalDevices registered in the Stack");
442
443			return B_OK;
444		}
445
446		case B_MODULE_UNINIT:
447		{
448			delete_sem(sLinkChangeSemaphore);
449
450			mutex_destroy(&sListLock);
451			put_module(NET_BUFFER_MODULE_NAME);
452			put_module(NET_STACK_MODULE_NAME);
453			put_module(BT_CORE_DATA_MODULE_NAME);
454			remove_debugger_command("btLocalDevices", &dump_bluetooth_devices);
455			// status_t status = QuitAclConnectionThread();
456
457			return B_OK;
458		}
459
460		default:
461			return B_ERROR;
462	}
463}
464
465
466bt_hci_module_info sBluetoothModule = {
467	{
468		BT_HCI_MODULE_NAME,
469		B_KEEP_LOADED,
470		bluetooth_std_ops
471	},
472	RegisterDriver,
473	UnregisterDriver,
474	FindDeviceByID,
475	PostTransportPacket,
476	PostACL,
477	PostSCO,
478	PostESCO
479};
480
481
482module_info* modules[] = {
483	(module_info*)&sBluetoothModule,
484	NULL
485};
486
487