xref: /haiku/src/servers/bluetooth/BluetoothServer.cpp (revision 4b3b81da9e459443d75329cfd08bc9a57ad02653)
1 /*
2  * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  *
4  * All rights reserved. Distributed under the terms of the MIT License.
5  *
6  */
7 
8 #include <stdio.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 
12 
13 #include <Entry.h>
14 #include <Path.h>
15 #include <Message.h>
16 #include <Directory.h>
17 #include <String.h>
18 #include <Roster.h>
19 
20 
21 #include <TypeConstants.h>
22 #include <syslog.h>
23 
24 #include <bluetoothserver_p.h>
25 #include <bluetooth/HCI/btHCI_command.h>
26 #include <bluetooth/bluetooth_util.h>
27 
28 #include "LocalDeviceImpl.h"
29 #include "BluetoothServer.h"
30 #include "Output.h"
31 
32 
33 BluetoothServer::BluetoothServer() : BApplication(BLUETOOTH_SIGNATURE)
34 {
35 	Output::Instance()->Run();
36 	Output::Instance()->SetTitle("Bluetooth message gathering");
37 
38 	Output::Instance()->AddTab("General", BLACKBOARD_GENERAL);
39 	Output::Instance()->AddTab("Device Manager", BLACKBOARD_DEVICEMANAGER);
40 	Output::Instance()->AddTab("Events", BLACKBOARD_EVENTS);
41 	Output::Instance()->AddTab("Kit", BLACKBOARD_KIT);
42 
43 
44 	ShowWindow(Output::Instance());
45 
46     fDeviceManager = new DeviceManager();
47 	fLocalDevicesList.MakeEmpty();
48 
49 	fEventListener = spawn_thread(notification_Thread, "BT port listener" , B_DISPLAY_PRIORITY , this);
50 
51 
52 }
53 
54 bool BluetoothServer::QuitRequested(void)
55 {
56 	// Finish quitting
57 	Output::Instance()->Lock();
58 	Output::Instance()->Quit();
59 
60 
61 /*	HCIDelegate *hd = NULL;
62 	while ((hd = (HCIDelegate *)fDelegatesList.RemoveItem((int32)0)) !=NULL)
63 		delete hd;
64 */
65 
66 	printf("Accepting quitting of the application\n");
67 	return BApplication::QuitRequested();
68 }
69 
70 void BluetoothServer::ArgvReceived(int32 argc, char **argv)
71 {
72 	if (argc>1) {
73 		if (strcmp(argv[1], "--finish") == 0)
74 			PostMessage(B_QUIT_REQUESTED);
75 
76 	    else {
77 
78 
79 	    }
80 	}
81 
82 }
83 
84 
85 void BluetoothServer::ReadyToRun(void) {
86 
87     fDeviceManager->StartMonitoringDevice("bluetooth/h2generic");
88 
89 
90 	// Launch the notifier thread
91 	if ( resume_thread(fEventListener) != B_OK )
92 	{
93 		Output::Instance()->Post("Bluetooth port listener failed\n", BLACKBOARD_GENERAL);
94 	}
95 
96     Output::Instance()->Post("Bluetooth server Ready\n", BLACKBOARD_GENERAL);
97 }
98 
99 void BluetoothServer::AppActivated(bool act) {
100 
101 	printf("Activated %d\n",act);
102 
103 }
104 
105 
106 
107 void BluetoothServer::MessageReceived(BMessage *message)
108 {
109 	BMessage reply;
110 	status_t status = B_WOULD_BLOCK; // mark somehow.. do not reply anything
111 
112 	switch(message->what)
113 	{
114 
115 		case BT_MSG_ADD_DEVICE:
116 		{
117 			BString str;
118 	        message->FindString("name", &str);
119 			BPath path(str.String());
120 
121 	  	    (Output::Instance()->Post( str.String(), BLACKBOARD_GENERAL));
122      	    (Output::Instance()->Post(" requested LocalDevice\n", BLACKBOARD_GENERAL));
123 
124 	        LocalDeviceImpl* ldi = LocalDeviceImpl::CreateTransportAccessor(&path);
125 
126 	        if (ldi->GetID() >= 0) {
127                       fLocalDevicesList.AddItem(ldi);
128 					  Output::Instance()->AddTab("Local Device", BLACKBOARD_LD_OFFSET + ldi->GetID());
129 				  	  (Output::Instance()->Post( str.String(), BLACKBOARD_LD_OFFSET + ldi->GetID()));
130 					  (Output::Instance()->Post(" LocalDevice added\n", BLACKBOARD_LD_OFFSET + ldi->GetID()));
131 
132 
133             } else {
134 					  (Output::Instance()->Post("Adding LocalDevice failed\n", BLACKBOARD_GENERAL));
135             }
136 
137             status = B_WOULD_BLOCK;
138         }
139 
140 		case BT_MSG_COUNT_LOCAL_DEVICES:
141 			status = HandleLocalDevicesCount(message, &reply);
142     	break;
143 
144 		case BT_MSG_ACQUIRE_LOCAL_DEVICE:
145 			status = HandleAcquireLocalDevice(message, &reply);
146 		break;
147 
148         case BT_MSG_GET_FRIENDLY_NAME:
149             status = HandleGetFriendlyName(message, &reply);
150         break;
151 
152         case BT_MSG_GET_ADDRESS:
153             status = HandleGetAddress(message, &reply);
154         break;
155 
156         case BT_MSG_HANDLE_SIMPLE_REQUEST:
157             status = HandleSimpleRequest(message, &reply);
158         break;
159 
160 
161 		/* Handle if the bluetooth preferences is running?? */
162 		case B_SOME_APP_LAUNCHED:
163    		{
164 			const char *signature;
165 			// TODO: what's this for?
166 			if (message->FindString("be:signature", &signature)==B_OK) {
167 				printf("input_server : %s\n", signature);
168 				if (strcmp(signature, "application/x-vnd.Be-TSKB")==0) {
169 
170 				}
171 			}
172 			return;
173 		}
174 
175 
176 		default:
177 			BApplication::MessageReceived(message);
178 		break;
179 	}
180 
181 	// Can we reply right now?
182 	// TOD: review this condition
183     if (status != B_WOULD_BLOCK) {
184 	    reply.AddInt32("status", status);
185 	    message->SendReply(&reply);
186 	    printf("Sending reply message\n");
187 	}
188 
189 }
190 
191 #if 0
192 #pragma mark -
193 #endif
194 
195 LocalDeviceImpl*
196 BluetoothServer::LocateDelegateFromMessage(BMessage* message)
197 {
198     LocalDeviceImpl* ldi = NULL;
199  	hci_id hid;
200 
201     if (message->FindInt32("hci_id", &hid) == B_OK)
202 	{
203 	    /* Try to find out when a ID was specified */
204 	    int index;
205 
206 	    for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
207 
208 		    ldi = fLocalDevicesList.ItemAt(index);
209 		    if (ldi->GetID() == hid)  {
210 		        break;
211 		    }
212         }
213     }
214 
215     return ldi;
216 }
217 
218 LocalDeviceImpl*
219 BluetoothServer::LocateLocalDeviceImpl(hci_id hid)
220 {
221 
222     /* Try to find out when a ID was specified */
223     int index;
224 
225     for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
226 
227 	    LocalDeviceImpl* ldi = fLocalDevicesList.ItemAt(index);
228 	    if (ldi->GetID() == hid)  {
229 	        return ldi;
230 	    }
231     }
232 
233     return NULL;
234 }
235 
236 
237 #if 0
238 #pragma - Messages reply
239 #endif
240 
241 status_t
242 BluetoothServer::HandleLocalDevicesCount(BMessage* message, BMessage* reply)
243 {
244 	return reply->AddInt32("count", fLocalDevicesList.CountItems());
245 }
246 
247 
248 status_t
249 BluetoothServer::HandleAcquireLocalDevice(BMessage* message, BMessage* reply)
250 {
251 	hci_id hid;
252 	ssize_t size;
253 	bdaddr_t bdaddr;
254 	LocalDeviceImpl* ldi = NULL;
255     int32 index = 0;
256 
257 	if (message->FindInt32("hci_id", &hid) == B_OK)
258 	{
259 	    Output::Instance()->Post("GetLocalDevice requested with id\n", BLACKBOARD_KIT);
260         ldi = LocateDelegateFromMessage(message);
261 
262 	} else if (message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size ) == B_OK)
263 	{
264 	    /* Try to find out when the user specified the address */
265 	    Output::Instance()->Post("GetLocalDevice requested with bdaddr\n", BLACKBOARD_KIT);
266 	    for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
267 
268 	        bdaddr_t local;
269 		    ldi = fLocalDevicesList.ItemAt(index);
270 		    if ((ldi->GetAddress(&local, message) == B_OK) && bacmp(&local, &bdaddr))  {
271 		        break;
272 		    }
273         }
274 
275 	} else
276 	{
277 	    /* Careless, any device not performing operations will be fine */
278 	    Output::Instance()->Post("GetLocalDevice requested\n", BLACKBOARD_KIT);
279 	    for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
280 
281 		    ldi = fLocalDevicesList.ItemAt(index);
282 		    printf("Requesting local device %ld\n", ldi->GetID());
283 		    if (ldi != NULL && ldi->Available())
284 		    {
285   			    printf("dev ours %ld\n", ldi->GetID());
286 		        break;
287 		    }
288 
289         }
290 	}
291 
292     if (index <= fLocalDevicesList.CountItems() && ldi != NULL && ldi->Available())
293 	{
294 	    Output::Instance()->Post("Device acquired\n", BLACKBOARD_KIT);
295 	    ldi->Acquire();
296 	    return reply->AddInt32("hci_id", hid);
297 	}
298 
299 	return B_ERROR;
300 
301 }
302 
303 
304 status_t
305 BluetoothServer::HandleGetFriendlyName(BMessage* message, BMessage* reply)
306 {
307     LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
308     BString name;
309 
310     if (ldi == NULL)
311     	return B_ERROR;
312 
313     /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */
314     if (ldi->GetFriendlyName(name, DetachCurrentMessage()) == B_OK) {
315 
316         return reply->AddString("friendlyname", name);
317 	}
318 
319 	return B_WOULD_BLOCK;
320 }
321 
322 
323 status_t
324 BluetoothServer::HandleGetAddress(BMessage* message, BMessage* reply)
325 {
326     LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
327     bdaddr_t bdaddr;
328 
329     if (ldi == NULL)
330     	return B_ERROR;
331 
332     /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */
333 	status_t status = ldi->GetAddress(&bdaddr, DetachCurrentMessage());
334     if ( status == B_OK) {
335 
336         return reply->AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
337 	}
338 
339 	return status;
340 }
341 
342 
343 status_t
344 BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply)
345 {
346 
347     LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
348 	BString propertyRequested;
349 
350 	// Find out if there is a property being requested,
351     if (message->FindString("property", &propertyRequested) == B_OK) {
352     	// Check if the property has been already retrieved
353 
354     	if (ldi->IsPropertyAvailable(propertyRequested)) {
355 
356     	    // Dump everything
357     		reply->AddMessage("properties",ldi->GetPropertiesMessage());
358     		return B_OK;
359     	}
360 
361     }
362 
363 	// we are gonna need issue the command ...
364 	if (ldi->ProcessSimpleRequest(DetachCurrentMessage()) == B_OK)
365 		return B_WOULD_BLOCK;
366 	else
367 		return B_ERROR;
368 
369 }
370 
371 
372 #if 0
373 #pragma mark -
374 #endif
375 
376 
377 int32
378 BluetoothServer::notification_Thread(void* data)
379 {
380 	BPortNot notifierd( (BluetoothServer*) data , BT_USERLAND_PORT_NAME);
381 
382 	notifierd.loop();
383 	return B_NO_ERROR;
384 }
385 
386 int32
387 BluetoothServer::sdp_server_Thread(void* data)
388 {
389 
390 	return B_NO_ERROR;
391 }
392 
393 
394 void
395 BluetoothServer::ShowWindow(BWindow* pWindow)
396 {
397 	pWindow->Lock();
398 	if (pWindow->IsHidden())
399 		pWindow->Show();
400 	else
401 		pWindow->Activate();
402 	pWindow->Unlock();
403 }
404 
405 
406 #if 0
407 #pragma mark -
408 #endif
409 
410 int
411 main(int /*argc*/, char** /*argv*/)
412 {
413 	setbuf(stdout,NULL);
414 
415 	BluetoothServer* bluetoothServer = new BluetoothServer;
416 
417 	bluetoothServer->Run();
418 	delete bluetoothServer;
419 
420 	return 0;
421 }
422 
423