/* * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com * All rights reserved. Distributed under the terms of the MIT License. */ #include "ConnectionInterface.h" #include #include #include #define BT_DEBUG_THIS_MODULE #include int32 api_version = B_CUR_DRIVER_API_VERSION; mutex sConnectionListLock = MUTEX_INITIALIZER("bt connection list"); DoublyLinkedList sConnectionList; net_buffer_module_info* gBufferModule = NULL; inline bool ExistConnectionByDestination(const bdaddr_t& destination, hci_id hid = -1) { return ConnectionByDestination(destination, hid) != NULL; } inline bool ExistConnectionByHandle(uint16 handle, hci_id hid) { return ConnectionByHandle(handle, hid); } status_t PostEvent(bluetooth_device* ndev, void* event, size_t size) { struct hci_event_header* outgoingEvent = (struct hci_event_header*) event; status_t err; // Take actions on certain type of events. switch (outgoingEvent->ecode) { case HCI_EVENT_CONN_COMPLETE: { struct hci_ev_conn_complete* data = (struct hci_ev_conn_complete*)(outgoingEvent + 1); // TODO: XXX parse handle field HciConnection* conn = AddConnection(data->handle, BT_ACL, data->bdaddr, ndev->index); if (conn == NULL) panic("no mem for conn desc"); conn->ndevice = ndev; TRACE("%s: Registered connection handle=%#x\n", __func__, data->handle); break; } case HCI_EVENT_DISCONNECTION_COMPLETE: { struct hci_ev_disconnection_complete_reply* data; data = (struct hci_ev_disconnection_complete_reply*) (outgoingEvent + 1); RemoveConnection(data->handle, ndev->index); TRACE("%s: unRegistered connection handle=%#x\n", __func__, data->handle); break; } } // forward to bluetooth server port_id port = find_port(BT_USERLAND_PORT_NAME); if (port != B_NAME_NOT_FOUND) { err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1), event, size, B_TIMEOUT, 1 * 1000 * 1000); if (err != B_OK) ERROR("%s: Error posting userland %s\n", __func__, strerror(err)); } else { ERROR("%s: bluetooth_server not found for posting!\n", __func__); err = B_NAME_NOT_FOUND; } return err; } static status_t bcd_std_ops(int32 op, ...) { status_t status; switch (op) { case B_MODULE_INIT: new (&sConnectionList) DoublyLinkedList; status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule); if (status != B_OK) return status; return B_OK; case B_MODULE_UNINIT: put_module(NET_BUFFER_MODULE_NAME); return B_OK; } return B_ERROR; } bluetooth_core_data_module_info sBCDModule = { { BT_CORE_DATA_MODULE_NAME, 0, bcd_std_ops }, PostEvent, AddConnection, // RemoveConnection, RemoveConnection, RouteConnection, ConnectionByHandle, ConnectionByDestination, allocate_command_ident, lookup_command_ident, free_command_ident, }; module_info* modules[] = { (module_info*)&sBCDModule, NULL };