xref: /haiku/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp (revision adb0d19d561947362090081e81d90dde59142026)
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 	DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
40 
41 	while (iterator.HasNext()) {
42 		conn = iterator.Next();
43 		kprintf("\tLocalDevice=%lx Destination=%s handle=%#x type=%d outqueue=%ld expected=%ld\n",
44 					conn->Hid, bdaddrUtils::ToString(conn->destination),
45 			conn->handle, conn->type, conn->OutGoingFrames.Count() , conn->ExpectedResponses.Count());
46 
47 			// each channel
48 			DoublyLinkedList<L2capChannel>::Iterator channelIterator = conn->ChannelList.GetIterator();
49 			while (channelIterator.HasNext()) {
50 				chan = channelIterator.Next();
51 				kprintf("\t\tscid=%x dcid=%x state=%x cfg=%x\n", chan->scid,
52 							chan->dcid, chan->state, chan->cfgState);
53 			}
54 
55 	}
56 
57 	return 0;
58 }
59 
60 
61 status_t
62 PostEvent(net_device* ndev, void* event, size_t size)
63 {
64 	struct hci_event_header* outgoingEvent = (struct hci_event_header*) event;
65 	status_t err;
66 
67 	// Take actions on certain type of events.
68 	switch (outgoingEvent->ecode) {
69 		case HCI_EVENT_CONN_COMPLETE:
70 		{
71 			struct hci_ev_conn_complete* data = (struct hci_ev_conn_complete*)(outgoingEvent+1);
72 			//TODO: XXX parse handle field
73 			HciConnection* conn = AddConnection(data->handle, BT_ACL, &data->bdaddr, ndev->index);
74 			if (conn == NULL)
75 				panic("no mem for conn desc");
76 			conn->ndevice = ndev;
77 			debugf("Registered connection handle=%#x\n",data->handle);
78 
79 		} break;
80 
81 		case HCI_EVENT_DISCONNECTION_COMPLETE:
82 		{
83 			struct hci_ev_disconnection_complete_reply* data =
84 					(struct hci_ev_disconnection_complete_reply*)(outgoingEvent+1);
85 			RemoveConnection(data->handle, ndev->index);
86 			debugf("unRegistered connection handle=%#x\n",data->handle);
87 		} break;
88 	}
89 
90 	// forward to bluetooth server
91 	port_id port = find_port(BT_USERLAND_PORT_NAME);
92     if (port != B_NAME_NOT_FOUND) {
93 
94 		err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1),
95 		                     event, size, B_TIMEOUT, 1*1000*1000);
96 
97 		if (err != B_OK)
98 			debugf("Error posting userland %s\n", strerror(err));
99 
100     } else {
101     	flowf("ERROR:bluetooth_server not found for posting\n");
102     	err = B_NAME_NOT_FOUND;
103 	}
104 
105 
106 	return err;
107 }
108 
109 
110 static status_t
111 bcd_std_ops(int32 op, ...)
112 {
113 	status_t status;
114 
115 	switch (op) {
116 		case B_MODULE_INIT:
117 			new (&sConnectionList) DoublyLinkedList<HciConnection>;
118 			add_debugger_command("btConnections", &DumpHciConnections,
119 									"Lists Bluetooth Connections with RemoteDevices & channels");
120 
121 			status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
122 			if (status < B_OK) {
123 				return status;
124 			}
125 
126 			return B_OK;
127 
128 		break;
129 
130 		case B_MODULE_UNINIT:
131 
132 			remove_debugger_command("btConnections", &DumpHciConnections);
133 			put_module(NET_BUFFER_MODULE_NAME);
134 
135 			return B_OK;
136 		break;
137 	}
138 
139 	return B_ERROR;
140 }
141 
142 bluetooth_core_data_module_info sBCDModule = {
143 	{
144 		BT_CORE_DATA_MODULE_NAME,
145 		0,
146 		bcd_std_ops
147 	},
148 	PostEvent,
149 	AddConnection,
150 /*	RemoveConnection,*/
151 	RemoveConnection,
152 
153 	RouteConnection,
154 
155 	SetAclBuffer,
156 	SetAclExpectedSize,
157 	AclPutting,
158 	AclComplete,
159 	AclOverFlowed,
160 
161 	ConnectionByHandle,
162 	ConnectionByDestination,
163 
164 	AddChannel,
165 	RemoveChannel,
166 	ChannelBySourceID,
167 	ChannelAllocateCid,
168 	ChannelAllocateIdent,
169 
170 	SignalByIdent,
171 	TimeoutSignal,
172 	unTimeoutSignal,
173 	SpawmFrame,
174 	SpawmSignal,
175 	AcknowledgeSignal
176 
177 };
178 
179 
180 module_info *modules[] = {
181 	(module_info *)&sBCDModule,
182 	NULL
183 };
184