xref: /haiku/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp (revision 3c6e2dd68577c34d93e17f19711f6245bf6d0915)
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 #include "ChannelInterface.h"
7 #include "FrameInterface.h"
8 
9 
10 #include <bluetooth/bdaddrUtils.h>
11 #include <bluetooth/HCI/btHCI_transport.h>
12 #include <bluetooth/HCI/btHCI_event.h>
13 
14 #define BT_DEBUG_THIS_MODULE
15 #include <btDebug.h>
16 
17 DoublyLinkedList<HciConnection> sConnectionList;
18 net_buffer_module_info *gBufferModule = NULL;
19 
20 inline bool
21 ExistConnectionByDestination(bdaddr_t *destination, hci_id hid = -1)
22 {
23 	return (ConnectionByDestination(destination, hid) != NULL);
24 }
25 
26 
27 inline bool
28 ExistConnectionByHandle(uint16 handle, hci_id hid)
29 {
30 	return (ConnectionByHandle(handle,hid));
31 }
32 
33 
34 static int
35 DumpHciConnections(int argc, char** argv)
36 {
37 	HciConnection* conn;
38 	L2capChannel* chan;
39 	L2capFrame* frame;
40 	DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
41 
42 	while (iterator.HasNext()) {
43 		conn = iterator.Next();
44 		kprintf("LocalDevice=%lx Destination=%s handle=%#x type=%d outqueue=%ld expected=%ld\n",
45 					conn->Hid, bdaddrUtils::ToString(conn->destination),
46 			conn->handle, conn->type, conn->OutGoingFrames.Count() , conn->ExpectedResponses.Count());
47 
48 			// each channel
49 			kprintf("\tChannels\n");
50 			DoublyLinkedList<L2capChannel>::Iterator channelIterator = conn->ChannelList.GetIterator();
51 			while (channelIterator.HasNext()) {
52 				chan = channelIterator.Next();
53 				kprintf("\t\tscid=%x dcid=%x state=%x cfg=%x\n", chan->scid,
54 							chan->dcid, chan->state, chan->cfgState);
55 			}
56 
57 			// Each outgoing
58 			kprintf("\n\tOutGoingFrames\n");
59 			DoublyLinkedList<L2capFrame>::Iterator frameIterator = conn->OutGoingFrames.GetIterator();
60 			while (frameIterator.HasNext()) {
61 				frame = frameIterator.Next();
62 				kprintf("\t\tscid=%x code=%x ident=%x type=%x, buffer=%p\n", frame->channel->scid,
63 							frame->code, frame->ident, frame->type, frame->buffer);
64 			}
65 
66 			// Each expected
67 			kprintf("\n\tExpectedFrames\n");
68 			DoublyLinkedList<L2capFrame>::Iterator frameExpectedIterator = conn->ExpectedResponses.GetIterator();
69 			while (frameExpectedIterator.HasNext()) {
70 				frame = frameExpectedIterator.Next();
71 				kprintf("\t\tscid=%x code=%x ident=%x type=%x, buffer=%p\n", frame->channel->scid,
72 							frame->code, frame->ident, frame->type, frame->buffer);
73 			}
74 	}
75 
76 	return 0;
77 }
78 
79 
80 
81 status_t
82 PostEvent(net_device* ndev, void* event, size_t size)
83 {
84 	struct hci_event_header* outgoingEvent = (struct hci_event_header*) event;
85 	status_t err;
86 
87 	// Take actions on certain type of events.
88 	switch (outgoingEvent->ecode) {
89 		case HCI_EVENT_CONN_COMPLETE:
90 		{
91 			struct hci_ev_conn_complete* data = (struct hci_ev_conn_complete*)(outgoingEvent+1);
92 			//TODO: XXX parse handle field
93 			HciConnection* conn = AddConnection(data->handle, BT_ACL, &data->bdaddr, ndev->index);
94 			if (conn == NULL)
95 				panic("no mem for conn desc");
96 			conn->ndevice = ndev;
97 			debugf("Registered connection handle=%#x\n",data->handle);
98 
99 		} break;
100 
101 		case HCI_EVENT_DISCONNECTION_COMPLETE:
102 		{
103 			struct hci_ev_disconnection_complete_reply* data =
104 					(struct hci_ev_disconnection_complete_reply*)(outgoingEvent+1);
105 			RemoveConnection(data->handle, ndev->index);
106 			debugf("unRegistered connection handle=%#x\n",data->handle);
107 		} break;
108 	}
109 
110 	// forward to bluetooth server
111 	port_id port = find_port(BT_USERLAND_PORT_NAME);
112     if (port != B_NAME_NOT_FOUND) {
113 
114 		err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1),
115 		                     event, size, B_TIMEOUT, 1*1000*1000);
116 
117 		if (err != B_OK)
118 			debugf("Error posting userland %s\n", strerror(err));
119 
120     } else {
121     	flowf("ERROR:bluetooth_server not found for posting\n");
122     	err = B_NAME_NOT_FOUND;
123 	}
124 
125 
126 	return err;
127 }
128 
129 
130 static status_t
131 bcd_std_ops(int32 op, ...)
132 {
133 	status_t status;
134 
135 	switch (op) {
136 		case B_MODULE_INIT:
137 			new (&sConnectionList) DoublyLinkedList<HciConnection>;
138 			add_debugger_command("btConnections", &DumpHciConnections,
139 									"Lists Bluetooth Connections with RemoteDevices & channels");
140 
141 			status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
142 			if (status < B_OK) {
143 				return status;
144 			}
145 
146 			return B_OK;
147 
148 		break;
149 
150 		case B_MODULE_UNINIT:
151 
152 			remove_debugger_command("btConnections", &DumpHciConnections);
153 			put_module(NET_BUFFER_MODULE_NAME);
154 
155 			return B_OK;
156 		break;
157 	}
158 
159 	return B_ERROR;
160 }
161 
162 bluetooth_core_data_module_info sBCDModule = {
163 	{
164 		BT_CORE_DATA_MODULE_NAME,
165 		0,
166 		bcd_std_ops
167 	},
168 	PostEvent,
169 	AddConnection,
170 /*	RemoveConnection,*/
171 	RemoveConnection,
172 
173 	RouteConnection,
174 
175 	SetAclBuffer,
176 	SetAclExpectedSize,
177 	AclPutting,
178 	AclComplete,
179 	AclOverFlowed,
180 
181 	ConnectionByHandle,
182 	ConnectionByDestination,
183 
184 	AddChannel,
185 	RemoveChannel,
186 	ChannelBySourceID,
187 	ChannelAllocateCid,
188 	ChannelAllocateIdent,
189 
190 	SignalByIdent,
191 	TimeoutSignal,
192 	unTimeoutSignal,
193 	SpawmFrame,
194 	SpawmSignal,
195 	AcknowledgeSignal,
196 	QueueSignal,
197 
198 };
199 
200 
201 module_info *modules[] = {
202 	(module_info *)&sBCDModule,
203 	NULL
204 };
205