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