xref: /haiku/src/servers/bluetooth/BluetoothServer.cpp (revision b87aa6b6121c91d4a932a0b3f877415f468808fe)
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