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