xref: /haiku/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
1 /*
2  * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 #include "ConnectionInterface.h"
6 
7 
8 #include <bluetooth/bdaddrUtils.h>
9 #include <bluetooth/HCI/btHCI_transport.h>
10 #include <bluetooth/HCI/btHCI_event.h>
11 
12 #define BT_DEBUG_THIS_MODULE
13 #include <btDebug.h>
14 
15 
16 int32 api_version = B_CUR_DRIVER_API_VERSION;
17 
18 
19 mutex sConnectionListLock = MUTEX_INITIALIZER("bt connection list");
20 DoublyLinkedList<HciConnection> sConnectionList;
21 net_buffer_module_info* gBufferModule = NULL;
22 
23 
24 inline bool
25 ExistConnectionByDestination(const bdaddr_t& destination, hci_id hid = -1)
26 {
27 	return ConnectionByDestination(destination, hid) != NULL;
28 }
29 
30 
31 inline bool
32 ExistConnectionByHandle(uint16 handle, hci_id hid)
33 {
34 	return ConnectionByHandle(handle, hid);
35 }
36 
37 
38 status_t
39 PostEvent(bluetooth_device* ndev, void* event, size_t size)
40 {
41 	struct hci_event_header* outgoingEvent = (struct hci_event_header*) event;
42 	status_t err;
43 
44 	// Take actions on certain type of events.
45 	switch (outgoingEvent->ecode) {
46 		case HCI_EVENT_CONN_COMPLETE:
47 		{
48 			struct hci_ev_conn_complete* data
49 				= (struct hci_ev_conn_complete*)(outgoingEvent + 1);
50 
51 			// TODO: XXX parse handle field
52 			HciConnection* conn = AddConnection(data->handle, BT_ACL,
53 				data->bdaddr, ndev->index);
54 
55 			if (conn == NULL)
56 				panic("no mem for conn desc");
57 			conn->ndevice = ndev;
58 			TRACE("%s: Registered connection handle=%#x\n", __func__,
59 				data->handle);
60 			break;
61 		}
62 
63 		case HCI_EVENT_DISCONNECTION_COMPLETE:
64 		{
65 			struct hci_ev_disconnection_complete_reply* data;
66 
67 			data = (struct hci_ev_disconnection_complete_reply*)
68 				(outgoingEvent + 1);
69 
70 			RemoveConnection(data->handle, ndev->index);
71 			TRACE("%s: unRegistered connection handle=%#x\n", __func__,
72 				data->handle);
73 			break;
74 		}
75 
76 	}
77 
78 	// forward to bluetooth server
79 	port_id port = find_port(BT_USERLAND_PORT_NAME);
80 	if (port != B_NAME_NOT_FOUND) {
81 
82 		err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1),
83 			event, size, B_TIMEOUT, 1 * 1000 * 1000);
84 
85 		if (err != B_OK)
86 			ERROR("%s: Error posting userland %s\n", __func__, strerror(err));
87 
88 	} else {
89 		ERROR("%s: bluetooth_server not found for posting!\n", __func__);
90 		err = B_NAME_NOT_FOUND;
91 	}
92 
93 	return err;
94 }
95 
96 
97 static status_t
98 bcd_std_ops(int32 op, ...)
99 {
100 	status_t status;
101 
102 	switch (op) {
103 		case B_MODULE_INIT:
104 			new (&sConnectionList) DoublyLinkedList<HciConnection>;
105 
106 			status = get_module(NET_BUFFER_MODULE_NAME,
107 				(module_info **)&gBufferModule);
108 			if (status != B_OK)
109 				return status;
110 
111 			return B_OK;
112 
113 		case B_MODULE_UNINIT:
114 			put_module(NET_BUFFER_MODULE_NAME);
115 			return B_OK;
116 	}
117 
118 	return B_ERROR;
119 }
120 
121 
122 bluetooth_core_data_module_info sBCDModule = {
123 	{
124 		BT_CORE_DATA_MODULE_NAME,
125 		0,
126 		bcd_std_ops
127 	},
128 	PostEvent,
129 	AddConnection,
130 	// RemoveConnection,
131 	RemoveConnection,
132 
133 	RouteConnection,
134 
135 	ConnectionByHandle,
136 	ConnectionByDestination,
137 
138 	allocate_command_ident,
139 	lookup_command_ident,
140 	free_command_ident,
141 };
142 
143 
144 module_info* modules[] = {
145 	(module_info*)&sBCDModule,
146 	NULL
147 };
148