diff --git a/headers/private/bluetooth/PortListener.h b/headers/private/bluetooth/PortListener.h new file mode 100644 index 0000000000..00978b4506 --- /dev/null +++ b/headers/private/bluetooth/PortListener.h @@ -0,0 +1,160 @@ +#ifndef PORTLISTENER_H_ +#define PORTLISTENER_H_ + +#include + + +template < + typename TYPE, + ssize_t MAX_MESSAGE_SIZE = 256, + size_t MAX_MESSAGE_DEEP = 16, + uint32 PRIORITY = B_URGENT_DISPLAY_PRIORITY> +class PortListener { + + typedef status_t (*port_listener_func)(TYPE*, int32, size_t); + + struct PortListenerInfo { + port_id* port; + port_listener_func func; + } fInformation; + + + public: + PortListener(const char* name, port_listener_func handler) + { + fInformation.func = handler; + fInformation.port = &fPort; + + InitCheck(); + fPortName = strdup(name); + fThreadName = strdup(name); + fThreadName = strcat(fThreadName, " thread"); + } + + + ~PortListener() { + + status_t status; + + close_port(fPort); + // Closing the port should provoke the thread to finish + wait_for_thread(fThread, &status); + + delete fThreadName; + delete fPortName; + + return status; + } + + + status_t TriggerCode(int32 code) { + + return write_port(fPort, code, NULL, 0); + + } + + + status_t InitCheck() { + + // Create Port + fPort = find_port(fPortName); + if (fPort == B_NAME_NOT_FOUND) { + fPort = create_port(MAX_MESSAGE_DEEP, fPortName); + } + + if (fPort < B_OK) + return fPort; + + // Create Thread + + fThread = find_thread(fThreadName); + if (fThread < B_OK) { +#ifdef KERNEL_LAND + fThread = spawn_kernel_thread((thread_func)&PortListener::threadFunction, fThreadName, PRIORITY, &fInformation); +#else + fThread = spawn_thread((thread_func)&PortListener::threadFunction, fThreadName, PRIORITY, &fInformation); +#endif + } + + if (fThread < B_OK) + return fThread; + + return B_OK; + } + + + status_t Launch() { + + status_t check = InitCheck(); + + if (check < B_OK) + return check; + + return resume_thread(fThread); + } + + + status_t Stop() { + status_t status; + + wait_for_thread(fThread, &status); + + return status; + } + + private: + port_id fPort; + thread_id fThread; + char* fThreadName; + char* fPortName; + + static int32 threadFunction(void* data) + { + ssize_t ssizePort; + ssize_t ssizeRead; + status_t status = B_OK; + int32 code; + + port_id* port = ((struct PortListenerInfo*)data)->port; + port_listener_func handler = ((struct PortListenerInfo*)data)->func; + + + TYPE* buffer = (TYPE*)malloc(MAX_MESSAGE_SIZE); + + while ((ssizePort = port_buffer_size(*port)) != B_BAD_PORT_ID) { + + if (ssizePort <= 0) { + snooze(500*1000); + continue; + } + + if (ssizePort > MAX_MESSAGE_SIZE) { + snooze(500*1000); + continue; + } + + ssizeRead = read_port(*port, &code, (void*)buffer, ssizePort); + + if (ssizeRead != ssizePort) + continue; + + status = handler(buffer, code, ssizePort); + + if (status != B_OK) + break; + } + + free(buffer); + + if (ssizePort == B_BAD_PORT_ID) // the port dissapeared + return ssizePort; + + return status; + } + +}; // PortListener + + +#endif // PORTLISTENER_H_ diff --git a/src/servers/bluetooth/BPortNot.cpp b/src/servers/bluetooth/BPortNot.cpp deleted file mode 100644 index f38fe4faa2..0000000000 --- a/src/servers/bluetooth/BPortNot.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * - * All rights reserved. Distributed under the terms of the MIT License. - * - */ - -#include "BPortNot.h" -#include "Output.h" - -#include "BluetoothServer.h" -#include "LocalDeviceImpl.h" - -#include -#include - -#include - -BPortNot::BPortNot(BluetoothServer* app, const char* name) { - - ourapp = (BluetoothServer*) app; - - fPort = find_port(name); - if ( fPort == B_NAME_NOT_FOUND ) - { - fPort = create_port(256, name); - Output::Instance()->Post("Event Listener Port Created\n",BLACKBOARD_GENERAL); - } -} - -void -BPortNot::loop() -{ - size_t size; - size_t ssize; - int32 code; - - struct hci_event_header *hdr; - - LocalDeviceImpl* ld; - - while (code != HCI_HAIKU_EVENT_SERVER_QUITTING) { - - size = port_buffer_size(fPort); - - /* TODO: Consider using snb_buff like structure here or - max event size to prevent mallocs & frees */ - hdr = (struct hci_event_header *) malloc(size); - ssize = read_port(fPort, &code, hdr, size); - - if (size != ssize) { - Output::Instance()->Post("Event size not matching", BLACKBOARD_GENERAL); - continue; - } - - if (size <= 0) { - Output::Instance()->Post("Suspicious empty event", BLACKBOARD_GENERAL); - continue; - } - - // we only handle events - if (GET_PORTCODE_TYPE(code)!= BT_EVENT) { - Output::Instance()->Post("Wrong type frame code", BLACKBOARD_GENERAL); - continue; - } - - ld = ourapp->LocateLocalDeviceImpl(GET_PORTCODE_HID(code)); - if (ld == NULL) { - Output::Instance()->Post("LocalDevice could not be fetched", BLACKBOARD_GENERAL); - continue; - } - - - ld->HandleEvent(hdr); - - - // free the event - free(hdr); - } - -} diff --git a/src/servers/bluetooth/BPortNot.h b/src/servers/bluetooth/BPortNot.h deleted file mode 100644 index 4d96fda6dd..0000000000 --- a/src/servers/bluetooth/BPortNot.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * - * All rights reserved. Distributed under the terms of the MIT License. - * - */ - -#ifndef _BT_PORT_NOTIFICATION -#define _BT_PORT_NOTIFICATION - -#include - -class BluetoothServer; - -class BPortNot { - -public: - BPortNot(BluetoothServer* app, const char* name) ; - void loop(); - - port_id fPort; - port_id sdp_request_port; - thread_id sdp_server_thread; - - BluetoothServer* ourapp; -}; - -#endif diff --git a/src/servers/bluetooth/BluetoothServer.cpp b/src/servers/bluetooth/BluetoothServer.cpp index d63ace0514..c0e1c9c26f 100644 --- a/src/servers/bluetooth/BluetoothServer.cpp +++ b/src/servers/bluetooth/BluetoothServer.cpp @@ -2,7 +2,6 @@ * Copyright 2007-2009 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com * All rights reserved. Distributed under the terms of the MIT License. - * */ #include @@ -28,6 +27,28 @@ #include "Output.h" +status_t +DispatchEvent(struct hci_event_header* header, int32 code, size_t size) +{ + // we only handle events + if (GET_PORTCODE_TYPE(code)!= BT_EVENT) { + Output::Instance()->Post("Wrong type frame code", BLACKBOARD_GENERAL); + return B_OK; + } + + // fetch the LocalDevice who belongs this event + LocalDeviceImpl* lDeviceImplementation = ((BluetoothServer*)be_app)->LocateLocalDeviceImpl(GET_PORTCODE_HID(code)); + if (lDeviceImplementation == NULL) { + Output::Instance()->Post("LocalDevice could not be fetched", BLACKBOARD_GENERAL); + return B_OK; + } + + lDeviceImplementation->HandleEvent(header); + + return B_OK; +} + + BluetoothServer::BluetoothServer() : BApplication(BLUETOOTH_SIGNATURE) { Output::Instance()->Run(); @@ -42,9 +63,9 @@ BluetoothServer::BluetoothServer() : BApplication(BLUETOOTH_SIGNATURE) fDeviceManager = new DeviceManager(); fLocalDevicesList.MakeEmpty(); - // TODO: Some events should be handled faster than in KL... - fEventListener = spawn_thread(notification_Thread, "BT port listener" , - B_URGENT_DISPLAY_PRIORITY , this); + fEventListener2 = new BluetoothPortListener(BT_USERLAND_PORT_NAME, + (BluetoothPortListener::port_listener_func)&DispatchEvent); + } @@ -80,13 +101,12 @@ void BluetoothServer::ReadyToRun(void) fDeviceManager->StartMonitoringDevice("bluetooth/h3"); fDeviceManager->StartMonitoringDevice("bluetooth/h4"); fDeviceManager->StartMonitoringDevice("bluetooth/h5"); - // Launch the notifier thread - if ( resume_thread(fEventListener) != B_OK ) - { - Output::Instance()->Post("Bluetooth port listener failed\n", BLACKBOARD_GENERAL); - } - Output::Instance()->Post("Bluetooth server Ready\n", BLACKBOARD_GENERAL); + if (fEventListener2->Launch() != B_OK) + Output::Instance()->Post("Bluetooth port listener failed\n", BLACKBOARD_GENERAL); + else + Output::Instance()->Post("Bluetooth server Ready\n", BLACKBOARD_GENERAL); + } @@ -175,6 +195,7 @@ void BluetoothServer::MessageReceived(BMessage *message) #pragma mark - #endif + LocalDeviceImpl* BluetoothServer::LocateDelegateFromMessage(BMessage* message) { @@ -369,16 +390,6 @@ BluetoothServer::HandleGetProperty(BMessage* message, BMessage* reply) #pragma mark - #endif - -int32 -BluetoothServer::notification_Thread(void* data) -{ - BPortNot notifierd((BluetoothServer*)data, BT_USERLAND_PORT_NAME); - - notifierd.loop(); - return B_NO_ERROR; -} - int32 BluetoothServer::sdp_server_Thread(void* data) { diff --git a/src/servers/bluetooth/BluetoothServer.h b/src/servers/bluetooth/BluetoothServer.h index cf757bf728..5d4b373ecb 100644 --- a/src/servers/bluetooth/BluetoothServer.h +++ b/src/servers/bluetooth/BluetoothServer.h @@ -9,20 +9,21 @@ #define _BLUETOOTH_SERVER_APP_H #include -#include -#include -#include -#include "BPortNot.h" -#include "HCIDelegate.h" -#include "DeviceManager.h" -#include "LocalDeviceImpl.h" +#include +#include +#include #include #include #include #include +#include "HCIDelegate.h" +#include "DeviceManager.h" +#include "LocalDeviceImpl.h" + +#include #define BT "bluetooth_server: " @@ -37,7 +38,7 @@ typedef enum { #define BLACKBOARD_LD(X) (BLACKBOARD_END+X-HCI_DEVICE_INDEX_OFFSET) typedef BObjectList LocalDevicesList; - +typedef PortListener BluetoothPortListener; class BluetoothServer : public BApplication { @@ -52,9 +53,7 @@ public: virtual void AppActivated(bool act); virtual void MessageReceived(BMessage *message); - - - static int32 notification_Thread(void* data); + static int32 sdp_server_Thread(void* data); /* Messages reply */ @@ -66,7 +65,7 @@ public: LocalDeviceImpl* LocateLocalDeviceImpl(hci_id hid); - + private: LocalDeviceImpl* LocateDelegateFromMessage(BMessage* message); @@ -74,12 +73,13 @@ private: void ShowWindow(BWindow* pWindow); LocalDevicesList fLocalDevicesList; - // UI + // Notification system - thread_id fEventListener; + BluetoothPortListener* fEventListener2; + DeviceManager* fDeviceManager; - + BPoint fCenter; }; diff --git a/src/servers/bluetooth/Jamfile b/src/servers/bluetooth/Jamfile index a3972522d4..706a6ca049 100644 --- a/src/servers/bluetooth/Jamfile +++ b/src/servers/bluetooth/Jamfile @@ -8,9 +8,7 @@ AddResources bluetooth_server : server-bluetooth.rdef ; Server bluetooth_server : - BPortNot.cpp BluetoothServer.cpp -# CommandManager.cpp DeviceManager.cpp HCIControllerAccessor.cpp HCITransportAccessor.cpp