130f1d1f3SOliver Ruiz Dorantes /* 2e5da0ec5SOliver Ruiz Dorantes * Copyright 2007-2009 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3e5da0ec5SOliver Ruiz Dorantes * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com 430f1d1f3SOliver Ruiz Dorantes * All rights reserved. Distributed under the terms of the MIT License. 530f1d1f3SOliver Ruiz Dorantes */ 630f1d1f3SOliver Ruiz Dorantes 730f1d1f3SOliver Ruiz Dorantes #include <stdio.h> 830f1d1f3SOliver Ruiz Dorantes #include <fcntl.h> 930f1d1f3SOliver Ruiz Dorantes #include <unistd.h> 1061da62d0SOliver Ruiz Dorantes #include <sys/select.h> 1130f1d1f3SOliver Ruiz Dorantes 1230f1d1f3SOliver Ruiz Dorantes #include <Entry.h> 13111d9460SOliver Ruiz Dorantes #include <Deskbar.h> 1430f1d1f3SOliver Ruiz Dorantes #include <Directory.h> 15e5da0ec5SOliver Ruiz Dorantes #include <Message.h> 16e5da0ec5SOliver Ruiz Dorantes #include <Path.h> 1730f1d1f3SOliver Ruiz Dorantes #include <Roster.h> 18e5da0ec5SOliver Ruiz Dorantes #include <String.h> 195559d51dSAugustin Cavalier #include <Window.h> 2030f1d1f3SOliver Ruiz Dorantes 2130f1d1f3SOliver Ruiz Dorantes #include <TypeConstants.h> 2230f1d1f3SOliver Ruiz Dorantes #include <syslog.h> 2330f1d1f3SOliver Ruiz Dorantes 2430f1d1f3SOliver Ruiz Dorantes #include <bluetoothserver_p.h> 2530f1d1f3SOliver Ruiz Dorantes #include <bluetooth/HCI/btHCI_command.h> 2661da62d0SOliver Ruiz Dorantes #include <bluetooth/L2CAP/btL2CAP.h> 2761da62d0SOliver Ruiz Dorantes #include <bluetooth/bluetooth.h> 2830f1d1f3SOliver Ruiz Dorantes 2930f1d1f3SOliver Ruiz Dorantes #include "BluetoothServer.h" 30111d9460SOliver Ruiz Dorantes #include "DeskbarReplicant.h" 31111d9460SOliver Ruiz Dorantes #include "LocalDeviceImpl.h" 325559d51dSAugustin Cavalier #include "Debug.h" 3330f1d1f3SOliver Ruiz Dorantes 3430f1d1f3SOliver Ruiz Dorantes 35c6083519SOliver Ruiz Dorantes status_t 36c6083519SOliver Ruiz Dorantes DispatchEvent(struct hci_event_header* header, int32 code, size_t size) 37c6083519SOliver Ruiz Dorantes { 38c6083519SOliver Ruiz Dorantes // we only handle events 39c6083519SOliver Ruiz Dorantes if (GET_PORTCODE_TYPE(code)!= BT_EVENT) { 405559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: Wrong type frame code\n"); 41c6083519SOliver Ruiz Dorantes return B_OK; 42c6083519SOliver Ruiz Dorantes } 43c6083519SOliver Ruiz Dorantes 44c6083519SOliver Ruiz Dorantes // fetch the LocalDevice who belongs this event 45a1163de8SOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImplementation = ((BluetoothServer*)be_app)-> 46a1163de8SOliver Ruiz Dorantes LocateLocalDeviceImpl(GET_PORTCODE_HID(code)); 47a1163de8SOliver Ruiz Dorantes 48c6083519SOliver Ruiz Dorantes if (lDeviceImplementation == NULL) { 495559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: LocalDevice could not be fetched\n"); 50c6083519SOliver Ruiz Dorantes return B_OK; 51c6083519SOliver Ruiz Dorantes } 52c6083519SOliver Ruiz Dorantes 53c6083519SOliver Ruiz Dorantes lDeviceImplementation->HandleEvent(header); 54c6083519SOliver Ruiz Dorantes 55c6083519SOliver Ruiz Dorantes return B_OK; 56c6083519SOliver Ruiz Dorantes } 57c6083519SOliver Ruiz Dorantes 58c6083519SOliver Ruiz Dorantes 5961da62d0SOliver Ruiz Dorantes BluetoothServer::BluetoothServer() 60e91079d5SAlexander von Gluck IV : 61e91079d5SAlexander von Gluck IV BApplication(BLUETOOTH_SIGNATURE), 62e91079d5SAlexander von Gluck IV fSDPThreadID(-1), 63e91079d5SAlexander von Gluck IV fIsShuttingDown(false) 6430f1d1f3SOliver Ruiz Dorantes { 6530f1d1f3SOliver Ruiz Dorantes fDeviceManager = new DeviceManager(); 6630f1d1f3SOliver Ruiz Dorantes fLocalDevicesList.MakeEmpty(); 6730f1d1f3SOliver Ruiz Dorantes 68c6083519SOliver Ruiz Dorantes fEventListener2 = new BluetoothPortListener(BT_USERLAND_PORT_NAME, 69c6083519SOliver Ruiz Dorantes (BluetoothPortListener::port_listener_func)&DispatchEvent); 7030f1d1f3SOliver Ruiz Dorantes } 7130f1d1f3SOliver Ruiz Dorantes 72aeb7f216SOliver Ruiz Dorantes 7330f1d1f3SOliver Ruiz Dorantes bool BluetoothServer::QuitRequested(void) 7430f1d1f3SOliver Ruiz Dorantes { 75ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = NULL; 76aeb7f216SOliver Ruiz Dorantes while ((lDeviceImpl = (LocalDeviceImpl*) 77aeb7f216SOliver Ruiz Dorantes fLocalDevicesList.RemoveItem((int32)0)) != NULL) 78ccf28e4dSOliver Ruiz Dorantes delete lDeviceImpl; 7930f1d1f3SOliver Ruiz Dorantes 80111d9460SOliver Ruiz Dorantes _RemoveDeskbarIcon(); 81111d9460SOliver Ruiz Dorantes 82aeb7f216SOliver Ruiz Dorantes // stop the SDP server thread 8361da62d0SOliver Ruiz Dorantes fIsShuttingDown = true; 84e97e2846SOliver Ruiz Dorantes 8561da62d0SOliver Ruiz Dorantes status_t threadReturnStatus; 8661da62d0SOliver Ruiz Dorantes wait_for_thread(fSDPThreadID, &threadReturnStatus); 875559d51dSAugustin Cavalier TRACE_BT("BluetoothServer server thread exited with: %s\n", 885559d51dSAugustin Cavalier strerror(threadReturnStatus)); 89aeb7f216SOliver Ruiz Dorantes 90aeb7f216SOliver Ruiz Dorantes delete fEventListener2; 915559d51dSAugustin Cavalier TRACE_BT("Shutting down bluetooth_server.\n"); 92aeb7f216SOliver Ruiz Dorantes 9330f1d1f3SOliver Ruiz Dorantes return BApplication::QuitRequested(); 9430f1d1f3SOliver Ruiz Dorantes } 9530f1d1f3SOliver Ruiz Dorantes 96e5da0ec5SOliver Ruiz Dorantes 9730f1d1f3SOliver Ruiz Dorantes void BluetoothServer::ArgvReceived(int32 argc, char **argv) 9830f1d1f3SOliver Ruiz Dorantes { 9930f1d1f3SOliver Ruiz Dorantes if (argc > 1) { 10030f1d1f3SOliver Ruiz Dorantes if (strcmp(argv[1], "--finish") == 0) 10130f1d1f3SOliver Ruiz Dorantes PostMessage(B_QUIT_REQUESTED); 10230f1d1f3SOliver Ruiz Dorantes } 10330f1d1f3SOliver Ruiz Dorantes } 10430f1d1f3SOliver Ruiz Dorantes 10530f1d1f3SOliver Ruiz Dorantes 106e5da0ec5SOliver Ruiz Dorantes void BluetoothServer::ReadyToRun(void) 107e5da0ec5SOliver Ruiz Dorantes { 108734ab97cSOliver Ruiz Dorantes fDeviceManager->StartMonitoringDevice("bluetooth/h2"); 109734ab97cSOliver Ruiz Dorantes fDeviceManager->StartMonitoringDevice("bluetooth/h3"); 110734ab97cSOliver Ruiz Dorantes fDeviceManager->StartMonitoringDevice("bluetooth/h4"); 111734ab97cSOliver Ruiz Dorantes fDeviceManager->StartMonitoringDevice("bluetooth/h5"); 11230f1d1f3SOliver Ruiz Dorantes 113c6083519SOliver Ruiz Dorantes if (fEventListener2->Launch() != B_OK) 1145559d51dSAugustin Cavalier TRACE_BT("General: Bluetooth event listener failed\n"); 115c6083519SOliver Ruiz Dorantes else 1165559d51dSAugustin Cavalier TRACE_BT("General: Bluetooth event listener Ready\n"); 117111d9460SOliver Ruiz Dorantes 118111d9460SOliver Ruiz Dorantes _InstallDeskbarIcon(); 11961da62d0SOliver Ruiz Dorantes 12061da62d0SOliver Ruiz Dorantes // Spawn the SDP server thread 12161da62d0SOliver Ruiz Dorantes fSDPThreadID = spawn_thread(SDPServerThread, "SDP server thread", 12261da62d0SOliver Ruiz Dorantes B_NORMAL_PRIORITY, this); 12361da62d0SOliver Ruiz Dorantes 124aeb7f216SOliver Ruiz Dorantes #define _USE_FAKE_SDP_SERVER 125aeb7f216SOliver Ruiz Dorantes #ifdef _USE_FAKE_SDP_SERVER 12661da62d0SOliver Ruiz Dorantes if (fSDPThreadID <= 0 || resume_thread(fSDPThreadID) != B_OK) { 127*88445a43SAugustin Cavalier TRACE_BT("BluetoothServer: Failed launching the SDP server thread\n"); 12861da62d0SOliver Ruiz Dorantes } 129e97e2846SOliver Ruiz Dorantes #endif 13030f1d1f3SOliver Ruiz Dorantes } 13130f1d1f3SOliver Ruiz Dorantes 13230f1d1f3SOliver Ruiz Dorantes 133e5da0ec5SOliver Ruiz Dorantes void BluetoothServer::AppActivated(bool act) 134e5da0ec5SOliver Ruiz Dorantes { 13530f1d1f3SOliver Ruiz Dorantes printf("Activated %d\n",act); 13630f1d1f3SOliver Ruiz Dorantes } 13730f1d1f3SOliver Ruiz Dorantes 13830f1d1f3SOliver Ruiz Dorantes 13930f1d1f3SOliver Ruiz Dorantes void BluetoothServer::MessageReceived(BMessage* message) 14030f1d1f3SOliver Ruiz Dorantes { 14130f1d1f3SOliver Ruiz Dorantes BMessage reply; 142ddac4074SOliver Ruiz Dorantes status_t status = B_WOULD_BLOCK; // mark somehow to do not reply anything 14330f1d1f3SOliver Ruiz Dorantes 14430f1d1f3SOliver Ruiz Dorantes switch (message->what) 14530f1d1f3SOliver Ruiz Dorantes { 14630f1d1f3SOliver Ruiz Dorantes case BT_MSG_ADD_DEVICE: 14730f1d1f3SOliver Ruiz Dorantes { 14830f1d1f3SOliver Ruiz Dorantes BString str; 149aeb7f216SOliver Ruiz Dorantes message->FindString("name", &str); 150aeb7f216SOliver Ruiz Dorantes 1515559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: Requested LocalDevice %s\n", str.String()); 152aeb7f216SOliver Ruiz Dorantes 153ecd60ae8SOliver Ruiz Dorantes BPath path(str.String()); 154ecd60ae8SOliver Ruiz Dorantes 155ecd60ae8SOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl 156ecd60ae8SOliver Ruiz Dorantes = LocalDeviceImpl::CreateTransportAccessor(&path); 15730f1d1f3SOliver Ruiz Dorantes 158ccf28e4dSOliver Ruiz Dorantes if (lDeviceImpl->GetID() >= 0) { 159ccf28e4dSOliver Ruiz Dorantes fLocalDevicesList.AddItem(lDeviceImpl); 160aeb7f216SOliver Ruiz Dorantes 161*88445a43SAugustin Cavalier TRACE_BT("LocalDevice %s id=%" B_PRId32 " added\n", str.String(), 162aeb7f216SOliver Ruiz Dorantes lDeviceImpl->GetID()); 16330f1d1f3SOliver Ruiz Dorantes } else { 1645559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: Adding LocalDevice hci id invalid\n"); 16530f1d1f3SOliver Ruiz Dorantes } 16630f1d1f3SOliver Ruiz Dorantes 16730f1d1f3SOliver Ruiz Dorantes status = B_WOULD_BLOCK; 168d04eb939SOliver Ruiz Dorantes /* TODO: This should be by user request only! */ 169ccf28e4dSOliver Ruiz Dorantes lDeviceImpl->Launch(); 170e5da0ec5SOliver Ruiz Dorantes break; 171ddac4074SOliver Ruiz Dorantes } 172ddac4074SOliver Ruiz Dorantes 173ddac4074SOliver Ruiz Dorantes case BT_MSG_REMOVE_DEVICE: 174ddac4074SOliver Ruiz Dorantes { 175ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message); 1766d8521b1SOliver Ruiz Dorantes if (lDeviceImpl != NULL) { 177ccf28e4dSOliver Ruiz Dorantes fLocalDevicesList.RemoveItem(lDeviceImpl); 178ccf28e4dSOliver Ruiz Dorantes delete lDeviceImpl; 1796d8521b1SOliver Ruiz Dorantes } 180ddac4074SOliver Ruiz Dorantes break; 181ddac4074SOliver Ruiz Dorantes } 182ddac4074SOliver Ruiz Dorantes 18330f1d1f3SOliver Ruiz Dorantes case BT_MSG_COUNT_LOCAL_DEVICES: 18430f1d1f3SOliver Ruiz Dorantes status = HandleLocalDevicesCount(message, &reply); 18530f1d1f3SOliver Ruiz Dorantes break; 186ddac4074SOliver Ruiz Dorantes 187057d0dc0SOliver Ruiz Dorantes case BT_MSG_ACQUIRE_LOCAL_DEVICE: 18830f1d1f3SOliver Ruiz Dorantes status = HandleAcquireLocalDevice(message, &reply); 18930f1d1f3SOliver Ruiz Dorantes break; 19030f1d1f3SOliver Ruiz Dorantes 19130f1d1f3SOliver Ruiz Dorantes case BT_MSG_HANDLE_SIMPLE_REQUEST: 19230f1d1f3SOliver Ruiz Dorantes status = HandleSimpleRequest(message, &reply); 19330f1d1f3SOliver Ruiz Dorantes break; 194ddac4074SOliver Ruiz Dorantes 1953fdaa5bfSOliver Ruiz Dorantes case BT_MSG_GET_PROPERTY: 1963fdaa5bfSOliver Ruiz Dorantes status = HandleGetProperty(message, &reply); 1973fdaa5bfSOliver Ruiz Dorantes break; 1983fdaa5bfSOliver Ruiz Dorantes 199aeb7f216SOliver Ruiz Dorantes // Handle if the bluetooth preferences is running? 20030f1d1f3SOliver Ruiz Dorantes case B_SOME_APP_LAUNCHED: 20130f1d1f3SOliver Ruiz Dorantes { 20230f1d1f3SOliver Ruiz Dorantes const char* signature; 203aeb7f216SOliver Ruiz Dorantes 20430f1d1f3SOliver Ruiz Dorantes if (message->FindString("be:signature", &signature) == B_OK) { 20530f1d1f3SOliver Ruiz Dorantes printf("input_server : %s\n", signature); 20630f1d1f3SOliver Ruiz Dorantes if (strcmp(signature, "application/x-vnd.Be-TSKB") == 0) { 20730f1d1f3SOliver Ruiz Dorantes 20830f1d1f3SOliver Ruiz Dorantes } 20930f1d1f3SOliver Ruiz Dorantes } 21030f1d1f3SOliver Ruiz Dorantes return; 21130f1d1f3SOliver Ruiz Dorantes } 21230f1d1f3SOliver Ruiz Dorantes 21330f1d1f3SOliver Ruiz Dorantes default: 21430f1d1f3SOliver Ruiz Dorantes BApplication::MessageReceived(message); 21530f1d1f3SOliver Ruiz Dorantes break; 21630f1d1f3SOliver Ruiz Dorantes } 21730f1d1f3SOliver Ruiz Dorantes 218009fac99SOliver Ruiz Dorantes // Can we reply right now? 219009fac99SOliver Ruiz Dorantes // TOD: review this condition 22030f1d1f3SOliver Ruiz Dorantes if (status != B_WOULD_BLOCK) { 22130f1d1f3SOliver Ruiz Dorantes reply.AddInt32("status", status); 22230f1d1f3SOliver Ruiz Dorantes message->SendReply(&reply); 2237a74a5dfSFredrik Modéen // printf("Sending reply message for->\n"); 2247a74a5dfSFredrik Modéen // message->PrintToStream(); 22530f1d1f3SOliver Ruiz Dorantes } 22630f1d1f3SOliver Ruiz Dorantes } 22730f1d1f3SOliver Ruiz Dorantes 228aeb7f216SOliver Ruiz Dorantes 22930f1d1f3SOliver Ruiz Dorantes #if 0 23030f1d1f3SOliver Ruiz Dorantes #pragma mark - 23130f1d1f3SOliver Ruiz Dorantes #endif 23230f1d1f3SOliver Ruiz Dorantes 23330f1d1f3SOliver Ruiz Dorantes LocalDeviceImpl* 23430f1d1f3SOliver Ruiz Dorantes BluetoothServer::LocateDelegateFromMessage(BMessage* message) 23530f1d1f3SOliver Ruiz Dorantes { 236ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = NULL; 23730f1d1f3SOliver Ruiz Dorantes hci_id hid; 23830f1d1f3SOliver Ruiz Dorantes 239e5da0ec5SOliver Ruiz Dorantes if (message->FindInt32("hci_id", &hid) == B_OK) { 240aeb7f216SOliver Ruiz Dorantes // Try to find out when a ID was specified 24130f1d1f3SOliver Ruiz Dorantes int index; 24230f1d1f3SOliver Ruiz Dorantes for (index = 0; index < fLocalDevicesList.CountItems(); index ++) { 243ccf28e4dSOliver Ruiz Dorantes lDeviceImpl = fLocalDevicesList.ItemAt(index); 244ccf28e4dSOliver Ruiz Dorantes if (lDeviceImpl->GetID() == hid) 24530f1d1f3SOliver Ruiz Dorantes break; 24630f1d1f3SOliver Ruiz Dorantes } 24730f1d1f3SOliver Ruiz Dorantes } 24830f1d1f3SOliver Ruiz Dorantes 249ccf28e4dSOliver Ruiz Dorantes return lDeviceImpl; 250e5da0ec5SOliver Ruiz Dorantes 25130f1d1f3SOliver Ruiz Dorantes } 25230f1d1f3SOliver Ruiz Dorantes 253aeb7f216SOliver Ruiz Dorantes 25430f1d1f3SOliver Ruiz Dorantes LocalDeviceImpl* 25530f1d1f3SOliver Ruiz Dorantes BluetoothServer::LocateLocalDeviceImpl(hci_id hid) 25630f1d1f3SOliver Ruiz Dorantes { 257aeb7f216SOliver Ruiz Dorantes // Try to find out when a ID was specified 25830f1d1f3SOliver Ruiz Dorantes int index; 25930f1d1f3SOliver Ruiz Dorantes 26030f1d1f3SOliver Ruiz Dorantes for (index = 0; index < fLocalDevicesList.CountItems(); index++) { 261ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = fLocalDevicesList.ItemAt(index); 262ccf28e4dSOliver Ruiz Dorantes if (lDeviceImpl->GetID() == hid) 263ccf28e4dSOliver Ruiz Dorantes return lDeviceImpl; 26430f1d1f3SOliver Ruiz Dorantes } 26530f1d1f3SOliver Ruiz Dorantes 26630f1d1f3SOliver Ruiz Dorantes return NULL; 26730f1d1f3SOliver Ruiz Dorantes } 26830f1d1f3SOliver Ruiz Dorantes 26930f1d1f3SOliver Ruiz Dorantes 27030f1d1f3SOliver Ruiz Dorantes #if 0 27130f1d1f3SOliver Ruiz Dorantes #pragma - Messages reply 27230f1d1f3SOliver Ruiz Dorantes #endif 27330f1d1f3SOliver Ruiz Dorantes 27430f1d1f3SOliver Ruiz Dorantes status_t 27530f1d1f3SOliver Ruiz Dorantes BluetoothServer::HandleLocalDevicesCount(BMessage* message, BMessage* reply) 27630f1d1f3SOliver Ruiz Dorantes { 2775559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: count requested\n"); 278ecd60ae8SOliver Ruiz Dorantes 27930f1d1f3SOliver Ruiz Dorantes return reply->AddInt32("count", fLocalDevicesList.CountItems()); 28030f1d1f3SOliver Ruiz Dorantes } 28130f1d1f3SOliver Ruiz Dorantes 28230f1d1f3SOliver Ruiz Dorantes 28330f1d1f3SOliver Ruiz Dorantes status_t 28430f1d1f3SOliver Ruiz Dorantes BluetoothServer::HandleAcquireLocalDevice(BMessage* message, BMessage* reply) 28530f1d1f3SOliver Ruiz Dorantes { 28630f1d1f3SOliver Ruiz Dorantes hci_id hid; 28730f1d1f3SOliver Ruiz Dorantes ssize_t size; 28830f1d1f3SOliver Ruiz Dorantes bdaddr_t bdaddr; 289ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = NULL; 2909306af4dSOliver Ruiz Dorantes static int32 lastIndex = 0; 29130f1d1f3SOliver Ruiz Dorantes 292aeb7f216SOliver Ruiz Dorantes if (message->FindInt32("hci_id", &hid) == B_OK) { 2935559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: GetLocalDevice requested with id\n"); 294ccf28e4dSOliver Ruiz Dorantes lDeviceImpl = LocateDelegateFromMessage(message); 29530f1d1f3SOliver Ruiz Dorantes 296aeb7f216SOliver Ruiz Dorantes } else if (message->FindData("bdaddr", B_ANY_TYPE, 297aeb7f216SOliver Ruiz Dorantes (const void**)&bdaddr, &size) == B_OK) { 298aeb7f216SOliver Ruiz Dorantes 299aeb7f216SOliver Ruiz Dorantes // Try to find out when the user specified the address 3005559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: GetLocalDevice requested with bdaddr\n"); 301aeb7f216SOliver Ruiz Dorantes for (lastIndex = 0; lastIndex < fLocalDevicesList.CountItems(); 302aeb7f216SOliver Ruiz Dorantes lastIndex ++) { 3039306af4dSOliver Ruiz Dorantes // TODO: Only possible if the property is available 3049306af4dSOliver Ruiz Dorantes // bdaddr_t local; 305ccf28e4dSOliver Ruiz Dorantes // lDeviceImpl = fLocalDevicesList.ItemAt(lastIndex); 306ccf28e4dSOliver Ruiz Dorantes // if ((lDeviceImpl->GetAddress(&local, message) == B_OK) 307e5da0ec5SOliver Ruiz Dorantes // && bacmp(&local, &bdaddr)) { 308fbbf64a4SOliver Ruiz Dorantes // break; 309fbbf64a4SOliver Ruiz Dorantes // } 31030f1d1f3SOliver Ruiz Dorantes } 31130f1d1f3SOliver Ruiz Dorantes 312e5da0ec5SOliver Ruiz Dorantes } else { 3139306af4dSOliver Ruiz Dorantes // Careless, any device not performing operations will be fine 3145559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: GetLocalDevice plain request\n"); 3159306af4dSOliver Ruiz Dorantes // from last assigned till end 316aeb7f216SOliver Ruiz Dorantes for (int index = lastIndex + 1; 317aeb7f216SOliver Ruiz Dorantes index < fLocalDevicesList.CountItems(); index++) { 318ccf28e4dSOliver Ruiz Dorantes lDeviceImpl= fLocalDevicesList.ItemAt(index); 319aeb7f216SOliver Ruiz Dorantes if (lDeviceImpl != NULL && lDeviceImpl->Available()) { 320ebb0fb03SAugustin Cavalier printf("Requested local device %" B_PRId32 "\n", 321ebb0fb03SAugustin Cavalier lDeviceImpl->GetID()); 322*88445a43SAugustin Cavalier TRACE_BT("BluetoothServer: Device available: %" B_PRId32 "\n", lDeviceImpl->GetID()); 3239306af4dSOliver Ruiz Dorantes lastIndex = index; 3249306af4dSOliver Ruiz Dorantes break; 3259306af4dSOliver Ruiz Dorantes } 3269306af4dSOliver Ruiz Dorantes } 3279306af4dSOliver Ruiz Dorantes 3289306af4dSOliver Ruiz Dorantes // from starting till last assigned if not yet found 329ccf28e4dSOliver Ruiz Dorantes if (lDeviceImpl == NULL) { 3309306af4dSOliver Ruiz Dorantes for (int index = 0; index <= lastIndex ; index ++) { 331ccf28e4dSOliver Ruiz Dorantes lDeviceImpl = fLocalDevicesList.ItemAt(index); 332aeb7f216SOliver Ruiz Dorantes if (lDeviceImpl != NULL && lDeviceImpl->Available()) { 333ebb0fb03SAugustin Cavalier printf("Requested local device %" B_PRId32 "\n", 334ebb0fb03SAugustin Cavalier lDeviceImpl->GetID()); 335*88445a43SAugustin Cavalier TRACE_BT("BluetoothServer: Device available: %" B_PRId32 "\n", lDeviceImpl->GetID()); 3369306af4dSOliver Ruiz Dorantes lastIndex = index; 33730f1d1f3SOliver Ruiz Dorantes break; 33830f1d1f3SOliver Ruiz Dorantes } 33930f1d1f3SOliver Ruiz Dorantes } 34030f1d1f3SOliver Ruiz Dorantes } 3419306af4dSOliver Ruiz Dorantes } 34230f1d1f3SOliver Ruiz Dorantes 343aeb7f216SOliver Ruiz Dorantes if (lastIndex <= fLocalDevicesList.CountItems() && lDeviceImpl != NULL 344aeb7f216SOliver Ruiz Dorantes && lDeviceImpl->Available()) { 345aeb7f216SOliver Ruiz Dorantes 346ccf28e4dSOliver Ruiz Dorantes hid = lDeviceImpl->GetID(); 347ccf28e4dSOliver Ruiz Dorantes lDeviceImpl->Acquire(); 3489306af4dSOliver Ruiz Dorantes 349*88445a43SAugustin Cavalier TRACE_BT("BluetoothServer: Device acquired %" B_PRId32 "\n", hid); 35030f1d1f3SOliver Ruiz Dorantes return reply->AddInt32("hci_id", hid); 35130f1d1f3SOliver Ruiz Dorantes } 35230f1d1f3SOliver Ruiz Dorantes 35330f1d1f3SOliver Ruiz Dorantes return B_ERROR; 35430f1d1f3SOliver Ruiz Dorantes 35530f1d1f3SOliver Ruiz Dorantes } 35630f1d1f3SOliver Ruiz Dorantes 35730f1d1f3SOliver Ruiz Dorantes 35830f1d1f3SOliver Ruiz Dorantes status_t 35930f1d1f3SOliver Ruiz Dorantes BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply) 36030f1d1f3SOliver Ruiz Dorantes { 361ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message); 3626d8521b1SOliver Ruiz Dorantes if (lDeviceImpl == NULL) { 3636d8521b1SOliver Ruiz Dorantes return B_ERROR; 3646d8521b1SOliver Ruiz Dorantes } 3656d8521b1SOliver Ruiz Dorantes 3663fdaa5bfSOliver Ruiz Dorantes const char* propertyRequested; 36730f1d1f3SOliver Ruiz Dorantes 36830f1d1f3SOliver Ruiz Dorantes // Find out if there is a property being requested, 36930f1d1f3SOliver Ruiz Dorantes if (message->FindString("property", &propertyRequested) == B_OK) { 37030f1d1f3SOliver Ruiz Dorantes // Check if the property has been already retrieved 371ccf28e4dSOliver Ruiz Dorantes if (lDeviceImpl->IsPropertyAvailable(propertyRequested)) { 37230f1d1f3SOliver Ruiz Dorantes // Dump everything 373ccf28e4dSOliver Ruiz Dorantes reply->AddMessage("properties", lDeviceImpl->GetPropertiesMessage()); 37430f1d1f3SOliver Ruiz Dorantes return B_OK; 37530f1d1f3SOliver Ruiz Dorantes } 37630f1d1f3SOliver Ruiz Dorantes } 37730f1d1f3SOliver Ruiz Dorantes 37830f1d1f3SOliver Ruiz Dorantes // we are gonna need issue the command ... 379ccf28e4dSOliver Ruiz Dorantes if (lDeviceImpl->ProcessSimpleRequest(DetachCurrentMessage()) == B_OK) 38030f1d1f3SOliver Ruiz Dorantes return B_WOULD_BLOCK; 381ccf28e4dSOliver Ruiz Dorantes else { 382ccf28e4dSOliver Ruiz Dorantes lDeviceImpl->Unregister(); 38330f1d1f3SOliver Ruiz Dorantes return B_ERROR; 384ccf28e4dSOliver Ruiz Dorantes } 38530f1d1f3SOliver Ruiz Dorantes 38630f1d1f3SOliver Ruiz Dorantes } 38730f1d1f3SOliver Ruiz Dorantes 38830f1d1f3SOliver Ruiz Dorantes 3893fdaa5bfSOliver Ruiz Dorantes status_t 3903fdaa5bfSOliver Ruiz Dorantes BluetoothServer::HandleGetProperty(BMessage* message, BMessage* reply) 3913fdaa5bfSOliver Ruiz Dorantes { 392ecd60ae8SOliver Ruiz Dorantes // User side will look for the reply in a result field and will 393ecd60ae8SOliver Ruiz Dorantes // not care about status fields, therefore we return OK in all cases 394ecd60ae8SOliver Ruiz Dorantes 395ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message); 3966d8521b1SOliver Ruiz Dorantes if (lDeviceImpl == NULL) { 3976d8521b1SOliver Ruiz Dorantes return B_ERROR; 3986d8521b1SOliver Ruiz Dorantes } 3996d8521b1SOliver Ruiz Dorantes 4003fdaa5bfSOliver Ruiz Dorantes const char* propertyRequested; 4013fdaa5bfSOliver Ruiz Dorantes 4023fdaa5bfSOliver Ruiz Dorantes // Find out if there is a property being requested, 4033fdaa5bfSOliver Ruiz Dorantes if (message->FindString("property", &propertyRequested) == B_OK) { 4043fdaa5bfSOliver Ruiz Dorantes 4055559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: Searching %s property...\n", propertyRequested); 4063fdaa5bfSOliver Ruiz Dorantes 4073fdaa5bfSOliver Ruiz Dorantes // Check if the property has been already retrieved 408ccf28e4dSOliver Ruiz Dorantes if (lDeviceImpl->IsPropertyAvailable(propertyRequested)) { 409040fb3eaSOliver Ruiz Dorantes 410040fb3eaSOliver Ruiz Dorantes // 1 bytes requests 411dd5df905SOliver Ruiz Dorantes if (strcmp(propertyRequested, "hci_version") == 0 412dd5df905SOliver Ruiz Dorantes || strcmp(propertyRequested, "lmp_version") == 0 413dd5df905SOliver Ruiz Dorantes || strcmp(propertyRequested, "sco_mtu") == 0) { 414dd5df905SOliver Ruiz Dorantes 415aeb7f216SOliver Ruiz Dorantes uint8 result = lDeviceImpl->GetPropertiesMessage()-> 416aeb7f216SOliver Ruiz Dorantes FindInt8(propertyRequested); 4173fdaa5bfSOliver Ruiz Dorantes reply->AddInt32("result", result); 418dd5df905SOliver Ruiz Dorantes 419040fb3eaSOliver Ruiz Dorantes // 2 bytes requests 420dd5df905SOliver Ruiz Dorantes } else if (strcmp(propertyRequested, "hci_revision") == 0 421dd5df905SOliver Ruiz Dorantes || strcmp(propertyRequested, "lmp_subversion") == 0 422dd5df905SOliver Ruiz Dorantes || strcmp(propertyRequested, "manufacturer") == 0 423dd5df905SOliver Ruiz Dorantes || strcmp(propertyRequested, "acl_mtu") == 0 424dd5df905SOliver Ruiz Dorantes || strcmp(propertyRequested, "acl_max_pkt") == 0 425040fb3eaSOliver Ruiz Dorantes || strcmp(propertyRequested, "sco_max_pkt") == 0 426040fb3eaSOliver Ruiz Dorantes || strcmp(propertyRequested, "packet_type") == 0 ) { 427dd5df905SOliver Ruiz Dorantes 428aeb7f216SOliver Ruiz Dorantes uint16 result = lDeviceImpl->GetPropertiesMessage()-> 429aeb7f216SOliver Ruiz Dorantes FindInt16(propertyRequested); 4303fdaa5bfSOliver Ruiz Dorantes reply->AddInt32("result", result); 431dd5df905SOliver Ruiz Dorantes 432040fb3eaSOliver Ruiz Dorantes // 1 bit requests 433040fb3eaSOliver Ruiz Dorantes } else if (strcmp(propertyRequested, "role_switch_capable") == 0 434040fb3eaSOliver Ruiz Dorantes || strcmp(propertyRequested, "encrypt_capable") == 0) { 435040fb3eaSOliver Ruiz Dorantes 436040fb3eaSOliver Ruiz Dorantes bool result = lDeviceImpl->GetPropertiesMessage()-> 437040fb3eaSOliver Ruiz Dorantes FindBool(propertyRequested); 438040fb3eaSOliver Ruiz Dorantes 439040fb3eaSOliver Ruiz Dorantes reply->AddInt32("result", result); 440040fb3eaSOliver Ruiz Dorantes 441040fb3eaSOliver Ruiz Dorantes 442040fb3eaSOliver Ruiz Dorantes 4433fdaa5bfSOliver Ruiz Dorantes } else { 4445559d51dSAugustin Cavalier TRACE_BT("BluetoothServer: Property %s could not be satisfied\n", propertyRequested); 4453fdaa5bfSOliver Ruiz Dorantes } 4463fdaa5bfSOliver Ruiz Dorantes } 4473fdaa5bfSOliver Ruiz Dorantes } 4483fdaa5bfSOliver Ruiz Dorantes 4493fdaa5bfSOliver Ruiz Dorantes return B_OK; 4503fdaa5bfSOliver Ruiz Dorantes } 4513fdaa5bfSOliver Ruiz Dorantes 452aeb7f216SOliver Ruiz Dorantes 45330f1d1f3SOliver Ruiz Dorantes #if 0 45430f1d1f3SOliver Ruiz Dorantes #pragma mark - 45530f1d1f3SOliver Ruiz Dorantes #endif 45630f1d1f3SOliver Ruiz Dorantes 45730f1d1f3SOliver Ruiz Dorantes int32 45861da62d0SOliver Ruiz Dorantes BluetoothServer::SDPServerThread(void* data) 45930f1d1f3SOliver Ruiz Dorantes { 46061da62d0SOliver Ruiz Dorantes const BluetoothServer* server = (BluetoothServer*)data; 46161da62d0SOliver Ruiz Dorantes 462aeb7f216SOliver Ruiz Dorantes // Set up the SDP socket 46361da62d0SOliver Ruiz Dorantes struct sockaddr_l2cap loc_addr = { 0 }; 46461da62d0SOliver Ruiz Dorantes int socketServer; 46561da62d0SOliver Ruiz Dorantes int client; 46661da62d0SOliver Ruiz Dorantes status_t status; 467e97e2846SOliver Ruiz Dorantes char buffer[512] = ""; 46861da62d0SOliver Ruiz Dorantes 4695559d51dSAugustin Cavalier TRACE_BT("SDP: SDP server thread up...\n"); 47061da62d0SOliver Ruiz Dorantes 471aeb7f216SOliver Ruiz Dorantes socketServer = socket(PF_BLUETOOTH, SOCK_STREAM, BLUETOOTH_PROTO_L2CAP); 47261da62d0SOliver Ruiz Dorantes 47361da62d0SOliver Ruiz Dorantes if (socketServer < 0) { 4745559d51dSAugustin Cavalier TRACE_BT("SDP: Could not create server socket ...\n"); 47561da62d0SOliver Ruiz Dorantes return B_ERROR; 47661da62d0SOliver Ruiz Dorantes } 47761da62d0SOliver Ruiz Dorantes 47861da62d0SOliver Ruiz Dorantes // bind socket to port 0x1001 of the first available 47961da62d0SOliver Ruiz Dorantes // bluetooth adapter 48061da62d0SOliver Ruiz Dorantes loc_addr.l2cap_family = AF_BLUETOOTH; 481269ebc04SOliver Tappe loc_addr.l2cap_bdaddr = BDADDR_ANY; 482e97e2846SOliver Ruiz Dorantes loc_addr.l2cap_psm = B_HOST_TO_LENDIAN_INT16(1); 48361da62d0SOliver Ruiz Dorantes loc_addr.l2cap_len = sizeof(struct sockaddr_l2cap); 48461da62d0SOliver Ruiz Dorantes 485aeb7f216SOliver Ruiz Dorantes status = bind(socketServer, (struct sockaddr*)&loc_addr, 486aeb7f216SOliver Ruiz Dorantes sizeof(struct sockaddr_l2cap)); 48761da62d0SOliver Ruiz Dorantes 48861da62d0SOliver Ruiz Dorantes if (status < 0) { 4895559d51dSAugustin Cavalier TRACE_BT("SDP: Could not bind server socket (%s)...\n", strerror(status)); 49061da62d0SOliver Ruiz Dorantes return status; 49161da62d0SOliver Ruiz Dorantes } 49261da62d0SOliver Ruiz Dorantes 49361da62d0SOliver Ruiz Dorantes // setsockopt(sock, SOL_L2CAP, SO_L2CAP_OMTU, &omtu, len ); 49461da62d0SOliver Ruiz Dorantes // getsockopt(sock, SOL_L2CAP, SO_L2CAP_IMTU, &omtu, &len ); 49561da62d0SOliver Ruiz Dorantes 496aeb7f216SOliver Ruiz Dorantes // Listen for up to 10 connections 49761da62d0SOliver Ruiz Dorantes status = listen(socketServer, 10); 49861da62d0SOliver Ruiz Dorantes 49961da62d0SOliver Ruiz Dorantes if (status != B_OK) { 5005559d51dSAugustin Cavalier TRACE_BT("SDP: Could not listen server socket (%s)...\n", strerror(status)); 50161da62d0SOliver Ruiz Dorantes return status; 50261da62d0SOliver Ruiz Dorantes } 50361da62d0SOliver Ruiz Dorantes 50461da62d0SOliver Ruiz Dorantes while (!server->fIsShuttingDown) { 50561da62d0SOliver Ruiz Dorantes 5065559d51dSAugustin Cavalier TRACE_BT("SDP: Waiting connection for socket (%s)...\n", strerror(status)); 50761da62d0SOliver Ruiz Dorantes 50861da62d0SOliver Ruiz Dorantes uint len = sizeof(struct sockaddr_l2cap); 50961da62d0SOliver Ruiz Dorantes client = accept(socketServer, (struct sockaddr*)&loc_addr, &len); 51061da62d0SOliver Ruiz Dorantes 5115559d51dSAugustin Cavalier TRACE_BT("SDP: Incomming connection... %d\n", client); 51261da62d0SOliver Ruiz Dorantes 513e97e2846SOliver Ruiz Dorantes ssize_t receivedSize; 514e97e2846SOliver Ruiz Dorantes 515e97e2846SOliver Ruiz Dorantes do { 516e97e2846SOliver Ruiz Dorantes receivedSize = recv(client, buffer, 29 , 0); 517e97e2846SOliver Ruiz Dorantes if (receivedSize < 0) 5185559d51dSAugustin Cavalier TRACE_BT("SDP: Error reading client socket\n"); 519e97e2846SOliver Ruiz Dorantes else { 5205559d51dSAugustin Cavalier TRACE_BT("SDP: Received from SDP client: %ld:\n", receivedSize); 521e97e2846SOliver Ruiz Dorantes for (int i = 0; i < receivedSize ; i++) 5225559d51dSAugustin Cavalier TRACE_BT("SDP: %x:", buffer[i]); 52361da62d0SOliver Ruiz Dorantes 5245559d51dSAugustin Cavalier TRACE_BT("\n"); 525e97e2846SOliver Ruiz Dorantes } 526e97e2846SOliver Ruiz Dorantes } while (receivedSize >= 0); 52761da62d0SOliver Ruiz Dorantes 52861da62d0SOliver Ruiz Dorantes snooze(5000000); 5295559d51dSAugustin Cavalier TRACE_BT("SDP: Waiting for next connection...\n"); 53061da62d0SOliver Ruiz Dorantes } 53161da62d0SOliver Ruiz Dorantes 532aeb7f216SOliver Ruiz Dorantes // Close the socket 53361da62d0SOliver Ruiz Dorantes close(socketServer); 53430f1d1f3SOliver Ruiz Dorantes 53530f1d1f3SOliver Ruiz Dorantes return B_NO_ERROR; 53630f1d1f3SOliver Ruiz Dorantes } 53730f1d1f3SOliver Ruiz Dorantes 53830f1d1f3SOliver Ruiz Dorantes 53930f1d1f3SOliver Ruiz Dorantes void 54030f1d1f3SOliver Ruiz Dorantes BluetoothServer::ShowWindow(BWindow* pWindow) 54130f1d1f3SOliver Ruiz Dorantes { 54230f1d1f3SOliver Ruiz Dorantes pWindow->Lock(); 54330f1d1f3SOliver Ruiz Dorantes if (pWindow->IsHidden()) 54430f1d1f3SOliver Ruiz Dorantes pWindow->Show(); 54530f1d1f3SOliver Ruiz Dorantes else 54630f1d1f3SOliver Ruiz Dorantes pWindow->Activate(); 54730f1d1f3SOliver Ruiz Dorantes pWindow->Unlock(); 54830f1d1f3SOliver Ruiz Dorantes } 54930f1d1f3SOliver Ruiz Dorantes 55030f1d1f3SOliver Ruiz Dorantes 551111d9460SOliver Ruiz Dorantes void 552111d9460SOliver Ruiz Dorantes BluetoothServer::_InstallDeskbarIcon() 553111d9460SOliver Ruiz Dorantes { 554111d9460SOliver Ruiz Dorantes app_info appInfo; 555111d9460SOliver Ruiz Dorantes be_app->GetAppInfo(&appInfo); 556111d9460SOliver Ruiz Dorantes 557111d9460SOliver Ruiz Dorantes BDeskbar deskbar; 558111d9460SOliver Ruiz Dorantes 559111d9460SOliver Ruiz Dorantes if (deskbar.HasItem(kDeskbarItemName)) { 560111d9460SOliver Ruiz Dorantes _RemoveDeskbarIcon(); 561111d9460SOliver Ruiz Dorantes } 562111d9460SOliver Ruiz Dorantes 563111d9460SOliver Ruiz Dorantes status_t res = deskbar.AddItem(&appInfo.ref); 5645559d51dSAugustin Cavalier if (res != B_OK) 5655559d51dSAugustin Cavalier TRACE_BT("Failed adding deskbar icon: %" B_PRId32 "\n", res); 566111d9460SOliver Ruiz Dorantes } 567111d9460SOliver Ruiz Dorantes 568111d9460SOliver Ruiz Dorantes 569111d9460SOliver Ruiz Dorantes void 570111d9460SOliver Ruiz Dorantes BluetoothServer::_RemoveDeskbarIcon() 571111d9460SOliver Ruiz Dorantes { 572111d9460SOliver Ruiz Dorantes BDeskbar deskbar; 573111d9460SOliver Ruiz Dorantes status_t res = deskbar.RemoveItem(kDeskbarItemName); 5745559d51dSAugustin Cavalier if (res != B_OK) 5755559d51dSAugustin Cavalier TRACE_BT("Failed removing Deskbar icon: %" B_PRId32 ": \n", res); 576111d9460SOliver Ruiz Dorantes } 577111d9460SOliver Ruiz Dorantes 578aeb7f216SOliver Ruiz Dorantes 57930f1d1f3SOliver Ruiz Dorantes #if 0 58030f1d1f3SOliver Ruiz Dorantes #pragma mark - 58130f1d1f3SOliver Ruiz Dorantes #endif 58230f1d1f3SOliver Ruiz Dorantes 58330f1d1f3SOliver Ruiz Dorantes int 58430f1d1f3SOliver Ruiz Dorantes main(int /*argc*/, char** /*argv*/) 58530f1d1f3SOliver Ruiz Dorantes { 58630f1d1f3SOliver Ruiz Dorantes BluetoothServer* bluetoothServer = new BluetoothServer; 58730f1d1f3SOliver Ruiz Dorantes 58830f1d1f3SOliver Ruiz Dorantes bluetoothServer->Run(); 58930f1d1f3SOliver Ruiz Dorantes delete bluetoothServer; 59030f1d1f3SOliver Ruiz Dorantes 59130f1d1f3SOliver Ruiz Dorantes return 0; 59230f1d1f3SOliver Ruiz Dorantes } 59330f1d1f3SOliver Ruiz Dorantes 594