xref: /haiku/src/servers/bluetooth/BluetoothServer.cpp (revision e9c4d47ad719d6fd67cd9b75b41ebbec563e7a79)
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(ldi->GetID()));
129 				  	  (Output::Instance()->Post( str.String(), BLACKBOARD_LD(ldi->GetID())));
130 					  (Output::Instance()->Post(" LocalDevice added\n", BLACKBOARD_LD(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             /* TODO: This should be by user request only! */
140             ldi->Launch();
141         }
142 
143 		case BT_MSG_COUNT_LOCAL_DEVICES:
144 			status = HandleLocalDevicesCount(message, &reply);
145     	break;
146 
147 		case BT_MSG_ACQUIRE_LOCAL_DEVICE:
148 			status = HandleAcquireLocalDevice(message, &reply);
149 		break;
150 
151         case BT_MSG_GET_FRIENDLY_NAME:
152             status = HandleGetFriendlyName(message, &reply);
153         break;
154 
155         case BT_MSG_GET_ADDRESS:
156             status = HandleGetAddress(message, &reply);
157         break;
158 
159         case BT_MSG_HANDLE_SIMPLE_REQUEST:
160             status = HandleSimpleRequest(message, &reply);
161         break;
162 
163 
164 		/* Handle if the bluetooth preferences is running?? */
165 		case B_SOME_APP_LAUNCHED:
166    		{
167 			const char *signature;
168 			// TODO: what's this for?
169 			if (message->FindString("be:signature", &signature)==B_OK) {
170 				printf("input_server : %s\n", signature);
171 				if (strcmp(signature, "application/x-vnd.Be-TSKB")==0) {
172 
173 				}
174 			}
175 			return;
176 		}
177 
178 
179 		default:
180 			BApplication::MessageReceived(message);
181 		break;
182 	}
183 
184 	// Can we reply right now?
185 	// TOD: review this condition
186     if (status != B_WOULD_BLOCK) {
187 	    reply.AddInt32("status", status);
188 	    message->SendReply(&reply);
189 	    printf("Sending reply message\n");
190 	}
191 
192 }
193 
194 #if 0
195 #pragma mark -
196 #endif
197 
198 LocalDeviceImpl*
199 BluetoothServer::LocateDelegateFromMessage(BMessage* message)
200 {
201     LocalDeviceImpl* ldi = NULL;
202  	hci_id hid;
203 
204     if (message->FindInt32("hci_id", &hid) == B_OK)
205 	{
206 	    /* Try to find out when a ID was specified */
207 	    int index;
208 
209 	    for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
210 
211 		    ldi = fLocalDevicesList.ItemAt(index);
212 		    if (ldi->GetID() == hid)  {
213 		        break;
214 		    }
215         }
216     }
217 
218     return ldi;
219 }
220 
221 LocalDeviceImpl*
222 BluetoothServer::LocateLocalDeviceImpl(hci_id hid)
223 {
224 
225     /* Try to find out when a ID was specified */
226     int index;
227 
228     for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
229 
230 	    LocalDeviceImpl* ldi = fLocalDevicesList.ItemAt(index);
231 	    if (ldi->GetID() == hid)  {
232 	        return ldi;
233 	    }
234     }
235 
236     return NULL;
237 }
238 
239 
240 #if 0
241 #pragma - Messages reply
242 #endif
243 
244 status_t
245 BluetoothServer::HandleLocalDevicesCount(BMessage* message, BMessage* reply)
246 {
247 	return reply->AddInt32("count", fLocalDevicesList.CountItems());
248 }
249 
250 
251 status_t
252 BluetoothServer::HandleAcquireLocalDevice(BMessage* message, BMessage* reply)
253 {
254 	hci_id hid;
255 	ssize_t size;
256 	bdaddr_t bdaddr;
257 	LocalDeviceImpl* ldi = NULL;
258     int32 index = 0;
259 
260 	if (message->FindInt32("hci_id", &hid) == B_OK)
261 	{
262 	    Output::Instance()->Post("GetLocalDevice requested with id\n", BLACKBOARD_KIT);
263         ldi = LocateDelegateFromMessage(message);
264 
265 	} else if (message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size ) == B_OK)
266 	{
267 	    /* Try to find out when the user specified the address */
268 	    Output::Instance()->Post("GetLocalDevice requested with bdaddr\n", BLACKBOARD_KIT);
269 	    for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
270 
271 	        bdaddr_t local;
272 		    ldi = fLocalDevicesList.ItemAt(index);
273 		    if ((ldi->GetAddress(&local, message) == B_OK) && bacmp(&local, &bdaddr))  {
274 		        break;
275 		    }
276         }
277 
278 	} else
279 	{
280 	    /* Careless, any device not performing operations will be fine */
281 	    Output::Instance()->Post("GetLocalDevice requested\n", BLACKBOARD_KIT);
282 	    for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
283 
284 		    ldi = fLocalDevicesList.ItemAt(index);
285 		    printf("Requesting local device %ld\n", ldi->GetID());
286 		    if (ldi != NULL && ldi->Available())
287 		    {
288   			    printf("dev ours %ld\n", ldi->GetID());
289 		        break;
290 		    }
291 
292         }
293 	}
294 
295     if (index <= fLocalDevicesList.CountItems() && ldi != NULL && ldi->Available())
296 	{
297 	    Output::Instance()->Post("Device acquired\n", BLACKBOARD_KIT);
298 	    ldi->Acquire();
299 	    return reply->AddInt32("hci_id", hid);
300 	}
301 
302 	return B_ERROR;
303 
304 }
305 
306 
307 status_t
308 BluetoothServer::HandleGetFriendlyName(BMessage* message, BMessage* reply)
309 {
310     LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
311     BString name;
312 
313     if (ldi == NULL)
314     	return B_ERROR;
315 
316     /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */
317     if (ldi->GetFriendlyName(name, DetachCurrentMessage()) == B_OK) {
318 
319         return reply->AddString("friendlyname", name);
320 	}
321 
322 	return B_WOULD_BLOCK;
323 }
324 
325 
326 status_t
327 BluetoothServer::HandleGetAddress(BMessage* message, BMessage* reply)
328 {
329     LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
330     bdaddr_t bdaddr;
331 
332     if (ldi == NULL)
333     	return B_ERROR;
334 
335     /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */
336 	status_t status = ldi->GetAddress(&bdaddr, DetachCurrentMessage());
337     if ( status == B_OK) {
338 
339         return reply->AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
340 	}
341 
342 	return status;
343 }
344 
345 
346 status_t
347 BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply)
348 {
349 
350     LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
351 	BString propertyRequested;
352 
353 	// Find out if there is a property being requested,
354     if (message->FindString("property", &propertyRequested) == B_OK) {
355     	// Check if the property has been already retrieved
356 
357     	if (ldi->IsPropertyAvailable(propertyRequested)) {
358 
359     	    // Dump everything
360     		reply->AddMessage("properties",ldi->GetPropertiesMessage());
361     		return B_OK;
362     	}
363 
364     }
365 
366 	// we are gonna need issue the command ...
367 	if (ldi->ProcessSimpleRequest(DetachCurrentMessage()) == B_OK)
368 //	if (ldi->ProcessSimpleRequest(message) == B_OK)
369 		return B_WOULD_BLOCK;
370 	else
371 		return B_ERROR;
372 
373 }
374 
375 
376 #if 0
377 #pragma mark -
378 #endif
379 
380 
381 int32
382 BluetoothServer::notification_Thread(void* data)
383 {
384 	BPortNot notifierd( (BluetoothServer*) data , BT_USERLAND_PORT_NAME);
385 
386 	notifierd.loop();
387 	return B_NO_ERROR;
388 }
389 
390 int32
391 BluetoothServer::sdp_server_Thread(void* data)
392 {
393 
394 	return B_NO_ERROR;
395 }
396 
397 
398 void
399 BluetoothServer::ShowWindow(BWindow* pWindow)
400 {
401 	pWindow->Lock();
402 	if (pWindow->IsHidden())
403 		pWindow->Show();
404 	else
405 		pWindow->Activate();
406 	pWindow->Unlock();
407 }
408 
409 
410 #if 0
411 #pragma mark -
412 #endif
413 
414 int
415 main(int /*argc*/, char** /*argv*/)
416 {
417 	setbuf(stdout,NULL);
418 
419 	BluetoothServer* bluetoothServer = new BluetoothServer;
420 
421 	bluetoothServer->Run();
422 	delete bluetoothServer;
423 
424 	return 0;
425 }
426 
427