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
DispatchEvent(struct hci_event_header * header,int32 code,size_t size)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
BluetoothServer()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
QuitRequested(void)7330f1d1f3SOliver Ruiz Dorantes bool BluetoothServer::QuitRequested(void)
7430f1d1f3SOliver Ruiz Dorantes {
75ccf28e4dSOliver Ruiz Dorantes LocalDeviceImpl* lDeviceImpl = NULL;
76aeb7f216SOliver Ruiz Dorantes while ((lDeviceImpl = (LocalDeviceImpl*)
77*b87aa6b6SMurai Takashi fLocalDevicesList.RemoveItemAt(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
ArgvReceived(int32 argc,char ** argv)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
ReadyToRun(void)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) {
12788445a43SAugustin 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
AppActivated(bool act)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
MessageReceived(BMessage * message)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
16188445a43SAugustin 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*
LocateDelegateFromMessage(BMessage * message)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*
LocateLocalDeviceImpl(hci_id hid)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
HandleLocalDevicesCount(BMessage * message,BMessage * reply)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
HandleAcquireLocalDevice(BMessage * message,BMessage * reply)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());
32288445a43SAugustin 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());
33588445a43SAugustin 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
34988445a43SAugustin 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
HandleSimpleRequest(BMessage * message,BMessage * reply)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
HandleGetProperty(BMessage * message,BMessage * reply)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
SDPServerThread(void * data)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
ShowWindow(BWindow * pWindow)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
_InstallDeskbarIcon()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
_RemoveDeskbarIcon()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
main(int,char **)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