xref: /haiku/src/servers/bluetooth/LocalDeviceImpl.cpp (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
1 /*
2  * Copyright 2008 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 
9 #include "BluetoothServer.h"
10 
11 #include "LocalDeviceImpl.h"
12 #include "CommandManager.h"
13 #include "Output.h"
14 
15 #include <bluetooth/bdaddrUtils.h>
16 #include <bluetooth/RemoteDevice.h>
17 #include <bluetooth/bluetooth_error.h>
18 #include <bluetooth/HCI/btHCI_event.h>
19 
20 #include <bluetoothserver_p.h>
21 #include <ConnectionIncoming.h>
22 #include <PincodeWindow.h>
23 
24 #include <stdio.h>
25 
26 
27 #if 0
28 #pragma mark - Class methods -
29 #endif
30 
31 
32 // Factory methods
33 LocalDeviceImpl*
34 LocalDeviceImpl::CreateControllerAccessor(BPath* path)
35 {
36     HCIDelegate* hd = new HCIControllerAccessor(path);
37 
38     if ( hd != NULL)
39         return new LocalDeviceImpl(hd);
40     else
41         return NULL;
42 }
43 
44 
45 LocalDeviceImpl*
46 LocalDeviceImpl::CreateTransportAccessor(BPath* path)
47 {
48     HCIDelegate* hd = new HCITransportAccessor(path);
49 
50     if ( hd != NULL)
51         return new LocalDeviceImpl(hd);
52     else
53         return NULL;
54 }
55 
56 
57 LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd)
58 {
59 
60 }
61 
62 #if 0
63 #pragma mark - Event handling methods -
64 #endif
65 
66 void
67 LocalDeviceImpl::HandleEvent(struct hci_event_header* event)
68 {
69 
70 printf("### Incoming event: len = %d\n", event->elen);
71 for (int16 index = 0 ; index < event->elen + 2; index++ ) {
72 	printf("%x:",((uint8*)event)[index]);
73 }
74 printf("### \n");
75 
76 	// Events here might have not been initated by us
77 	// TODO: ML mark as handled pass a reply by parameter and reply in common
78     switch (event->ecode) {
79 	        case HCI_EVENT_HARDWARE_ERROR:
80    				//HardwareError(event);
81    			return;
82 			case HCI_EVENT_CONN_REQUEST:
83 				ConnectionRequest((struct hci_ev_conn_request*)(event+1), NULL); // incoming request
84 				return;
85 			break;
86 
87 			case HCI_EVENT_CONN_COMPLETE:
88 				ConnectionComplete((struct hci_ev_conn_complete*)(event+1), NULL); // should belong to a request?
89 				return;  														   // can be sporadic or initiated by us¿?...
90 			break;
91 
92 			case HCI_EVENT_PIN_CODE_REQ:
93 				PinCodeRequest((struct hci_ev_pin_code_req*)(event+1), NULL);
94 				return;
95 			break;
96 
97 
98    		default:
99    			// lets go on
100    		break;
101 	}
102 
103 
104 
105 	BMessage*	request = NULL;
106 	int32		eventIndexLocation;
107 
108 	// Check if its a requested one
109 	if ( event->ecode == HCI_EVENT_CMD_COMPLETE ) {
110 
111 		(Output::Instance()->Post("Incoming Command Complete\n", BLACKBOARD_EVENTS));
112 		request = FindPetition(event->ecode, ((struct hci_ev_cmd_complete*)(event+1))->opcode, &eventIndexLocation );
113 
114 	} else if ( event->ecode == HCI_EVENT_CMD_STATUS ) {
115 
116 		(Output::Instance()->Post("Incoming Command Status\n", BLACKBOARD_EVENTS));
117 		request = FindPetition(event->ecode, ((struct hci_ev_cmd_status*)(event+1))->opcode, &eventIndexLocation );
118 
119 	} else
120 	{
121 		request = FindPetition(event->ecode);
122 	}
123 
124 	if ( request == NULL) {
125 		(Output::Instance()->Post("Event could not be understood or delivered\n", BLACKBOARD_EVENTS));
126 		return;
127 	}
128 
129 	// we are waiting for a reply
130 	switch (event->ecode) {
131 		case HCI_EVENT_INQUIRY_COMPLETE:
132     		InquiryComplete((uint8*)(event+1), request);
133     	break;
134 
135     	case HCI_EVENT_INQUIRY_RESULT:
136     		InquiryResult((uint8*)(event+1), request);
137 		break;
138 
139 		case HCI_EVENT_DISCONNECTION_COMPLETE:
140 			DisconnectionComplete((struct hci_ev_disconnection_complete_reply*)(event+1), request);
141 		break;
142 
143 		case HCI_EVENT_AUTH_COMPLETE:
144 		break;
145 
146 		case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
147 			RemoteNameRequestComplete((struct hci_ev_remote_name_request_complete_reply*)(event+1), request);
148 		break;
149 
150 		case HCI_EVENT_ENCRYPT_CHANGE:
151 		break;
152 
153 		case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE:
154 		break;
155 
156 		case HCI_EVENT_MASTER_LINK_KEY_COMPL:
157 		break;
158 
159 		case HCI_EVENT_RMT_FEATURES:
160 		break;
161 
162 		case HCI_EVENT_RMT_VERSION:
163 		break;
164 
165 		case HCI_EVENT_QOS_SETUP_COMPLETE:
166 		break;
167 
168 		case HCI_EVENT_CMD_COMPLETE:
169 			CommandComplete((struct hci_ev_cmd_complete*)(event+1), request, eventIndexLocation);
170 		break;
171 
172 		case HCI_EVENT_CMD_STATUS:
173  			CommandStatus((struct hci_ev_cmd_status*)(event+1), request, eventIndexLocation);
174 		break;
175 
176 		case HCI_EVENT_FLUSH_OCCUR:
177 		break;
178 
179 		case HCI_EVENT_ROLE_CHANGE:
180 			RoleChange((struct hci_ev_role_change*)(event+1), request, eventIndexLocation);
181 		break;
182 
183 		case HCI_EVENT_NUM_COMP_PKTS:
184 		break;
185 
186 		case HCI_EVENT_MODE_CHANGE:
187 		break;
188 
189 		case HCI_EVENT_RETURN_LINK_KEYS:
190 		break;
191 
192 		case HCI_EVENT_LINK_KEY_REQ:
193 		break;
194 
195 		case HCI_EVENT_LINK_KEY_NOTIFY:
196 			LinkKeyNotify((struct hci_ev_link_key_notify*)(event+1), request, eventIndexLocation);
197 		break;
198 
199 		case HCI_EVENT_LOOPBACK_COMMAND:
200 		break;
201 
202 		case HCI_EVENT_DATA_BUFFER_OVERFLOW:
203 		break;
204 
205 		case HCI_EVENT_MAX_SLOT_CHANGE:
206 		break;
207 
208 		case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
209 		break;
210 
211 		case HCI_EVENT_CON_PKT_TYPE_CHANGED:
212 		break;
213 
214 		case HCI_EVENT_QOS_VIOLATION:
215 		break;
216 
217 		case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE:
218 			PageScanRepetitionModeChange((struct hci_ev_page_scan_rep_mode_change*)(event+1), request, eventIndexLocation);
219 		break;
220 
221 		case HCI_EVENT_FLOW_SPECIFICATION:
222 		break;
223 
224 		case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
225 		break;
226 
227 		case HCI_EVENT_REMOTE_EXTENDED_FEATURES:
228 		break;
229 
230 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED:
231 		break;
232 
233 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED:
234 
235 		break;
236 	}
237 
238 }
239 
240 
241 void
242 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request, int32 index) {
243 
244 	int16   opcodeExpected;
245 	BMessage reply;
246 
247     Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD(GetID()));
248     Output::Instance()->Post("\n", BLACKBOARD_LD(GetID()));
249 
250 	// Handle command complete information
251     request->FindInt16("opcodeExpected", index, &opcodeExpected);
252 
253 
254 	if (request->IsSourceWaiting() == false)
255 		Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
256 
257     switch (opcodeExpected) {
258 
259         case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR):
260         {
261         	struct hci_rp_read_bd_addr* readbdaddr = (struct hci_rp_read_bd_addr*)(event+1);
262 
263             if (readbdaddr->status == BT_OK) {
264 
265                 reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, sizeof(bdaddr_t));
266                 reply.AddInt32("status", readbdaddr->status);
267 
268                 printf("Sending reply ... %ld\n",request->SendReply(&reply));
269                 reply.PrintToStream();
270 
271 			    Output::Instance()->Post("Positive reply for getAddress\n", BLACKBOARD_KIT);
272 
273             } else {
274                 reply.AddInt8("status", readbdaddr->status);
275                 request->SendReply(&reply);
276 			    Output::Instance()->Post("Negative reply for getAddress\n", BLACKBOARD_KIT);
277             }
278 
279  			// This request is not gonna be used anymore
280             ClearWantedEvent(request);
281      	}
282         break;
283 
284         case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME):
285         {
286         	struct hci_rp_read_local_name* readLocalName = (struct hci_rp_read_local_name*)(event+1);
287 
288         	reply.AddInt8("status", readLocalName->status);
289 
290             if (readLocalName->status == BT_OK) {
291 
292                 reply.AddString("friendlyname", (const char*)readLocalName->local_name );
293 			    Output::Instance()->Post("Positive reply for friendly name\n", BLACKBOARD_KIT);
294 
295             } else {
296 
297 			    Output::Instance()->Post("Negative reply for friendly name\n", BLACKBOARD_KIT);
298 
299             }
300 
301             printf("Sending reply ... %ld\n",request->SendReply(&reply));
302             reply.PrintToStream();
303 
304  			// This request is not gonna be used anymore
305             ClearWantedEvent(request);
306      	}
307         break;
308 
309         case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE):
310         {
311         	uint8* statusReply = (uint8*)(event+1);
312 
313         	reply.AddInt8("status", *statusReply);
314 
315             if (*statusReply == BT_OK) {
316 
317                 Output::Instance()->Post("Positive reply for scanmode\n", BLACKBOARD_KIT);
318 
319             } else {
320 
321                 Output::Instance()->Post("Negative reply for scanmode\n", BLACKBOARD_KIT);
322 
323             }
324 
325             printf("Sending reply ... %ld\n",request->SendReply(&reply));
326             reply.PrintToStream();
327 
328  			// This request is not gonna be used anymore
329             ClearWantedEvent(request);
330      	}
331         break;
332         case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY):
333         {
334         	uint8* statusReply = (uint8*)(event+1);
335 			//TODO: This reply has to match the BDADDR of the outgoing message
336         	reply.AddInt8("status", *statusReply);
337 
338             if (*statusReply == BT_OK) {
339 
340                 Output::Instance()->Post("Positive reply for pincode accept\n", BLACKBOARD_KIT);
341 
342             } else {
343 
344                 Output::Instance()->Post("Negative reply for pincode accept\n", BLACKBOARD_KIT);
345 
346             }
347 
348             printf("Sending reply ... %ld\n",request->SendReply(&reply));
349             reply.PrintToStream();
350 
351  			// This request is not gonna be used anymore
352             ClearWantedEvent(request);
353      	}
354         break;
355 
356 
357         case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY):
358         {
359         	uint8* statusReply = (uint8*)(event+1);
360 			//TODO: This reply might to match the BDADDR of the outgoing message
361 			//  	xxx:FindPetition should be expanded....
362         	reply.AddInt8("status", *statusReply);
363 
364             if (*statusReply == BT_OK) {
365 
366                 Output::Instance()->Post("Positive reply for pincode reject\n", BLACKBOARD_KIT);
367 
368             } else {
369 
370                 Output::Instance()->Post("Negative reply for pincode reject\n", BLACKBOARD_KIT);
371 
372             }
373 
374             printf("Sending reply ... %ld\n",request->SendReply(&reply));
375             reply.PrintToStream();
376 
377  			// This request is not gonna be used anymore
378             ClearWantedEvent(request);
379      	}
380         break;
381 
382 
383 		default:
384 		    Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT);
385 		break;
386 
387     }
388 }
389 
390 
391 void
392 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* request, int32 index) {
393 
394 	int16   opcodeExpected;
395 	BMessage reply;
396 
397     Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD(GetID()));
398     Output::Instance()->Post("\n", BLACKBOARD_LD(GetID()));
399 
400 	// Handle command complete information
401     request->FindInt16("opcodeExpected", index, &opcodeExpected);
402 
403 
404 	if (request->IsSourceWaiting() == false)
405 		Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
406 
407     switch (opcodeExpected) {
408 
409         case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY):
410         {
411         	reply.what = BT_MSG_INQUIRY_STARTED;
412         	reply.AddInt8("status", event->status);
413 
414             if (event->status == BT_OK) {
415 			    Output::Instance()->Post("Positive reply for inquiry status\n", BLACKBOARD_KIT);
416             } else {
417 			    Output::Instance()->Post("Negative reply for inquiry status\n", BLACKBOARD_KIT);
418             }
419 
420             printf("Sending reply ... %ld\n", request->SendReply(&reply));
421             reply.PrintToStream();
422 
423             ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY));
424      	}
425         break;
426 
427 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST):
428 		{
429 			if (event->status==BT_OK) {
430 				ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST));
431 			}
432 			else {
433 				BMessage reply;
434   		    	reply.AddInt8("status", event->status);
435 			    Output::Instance()->Post("Negative reply for remote friendly name\n", BLACKBOARD_KIT);
436 			    printf("Sending reply ... %ld\n", request->SendReply(&reply));
437 		        ClearWantedEvent(request);
438 		    }
439 		}
440 		break;
441 		/*
442 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ):
443 		{
444 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ));
445 		}
446 		break;
447 
448 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ):
449 		{
450 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ));
451 		}
452 		break;*/
453 
454 
455 		default:
456 		    Output::Instance()->Post("Command Status not handled\n", BLACKBOARD_KIT);
457 		break;
458 	}
459 
460 }
461 
462 
463 void
464 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request)
465 {
466 
467 	BMessage reply(BT_MSG_INQUIRY_DEVICE);
468 
469 
470     reply.AddData("info", B_ANY_TYPE, numberOfResponses+1 // skipping here the number of responses
471                         , (*numberOfResponses) * sizeof(struct inquiry_info) );
472 
473     printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply));
474 
475 }
476 
477 
478 void
479 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request)
480 {
481 	BMessage reply(BT_MSG_INQUIRY_COMPLETED);
482 
483 	reply.AddInt8("status", *status);
484 
485 
486     printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply));
487 //    (request->ReturnAddress()).SendMessage(&reply);
488 
489     ClearWantedEvent(request);
490 }
491 
492 
493 void
494 LocalDeviceImpl::RemoteNameRequestComplete(struct hci_ev_remote_name_request_complete_reply* remotename, BMessage* request)
495 {
496 	BMessage reply;
497 
498 	reply.AddInt8("status", remotename->status);
499 
500     if (remotename->status == BT_OK) {
501 
502         reply.AddString("friendlyname", (const char*)remotename->remote_name );
503 	    Output::Instance()->Post("Positive reply for remote friendly name\n", BLACKBOARD_KIT);
504 
505     } else {
506 
507 	    Output::Instance()->Post("Negative reply for remote friendly name\n", BLACKBOARD_KIT);
508 
509     }
510 
511     printf("Sending reply ... %ld\n", request->SendReply(&reply));
512     reply.PrintToStream();
513 
514 	// This request is not gonna be used anymore
515     ClearWantedEvent(request);
516 }
517 
518 
519 void
520 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, BMessage* request)
521 {
522 	size_t size;
523 	void* command;
524 
525 	printf("Connection type %d from %s\n", event->link_type, bdaddrUtils::ToString(event->bdaddr));
526 	(Output::Instance()->Post("Connection Incoming ...\n", BLACKBOARD_EVENTS));
527 
528 
529     /* TODO: add a possible request in the queue */
530 	if (true) { // Check Preferences if we are to accept this connection
531 	    command = buildAcceptConnectionRequest(event->bdaddr, 0x01 /*slave*/, &size);
532 
533 
534 		BMessage* newrequest = new BMessage;
535 		newrequest->AddInt16("eventExpected",  HCI_EVENT_CMD_STATUS);
536 		newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ));
537 
538 		newrequest->AddInt16("eventExpected",  HCI_EVENT_PIN_CODE_REQ);
539 		newrequest->AddInt16("eventExpected",  HCI_EVENT_ROLE_CHANGE);
540 		newrequest->AddInt16("eventExpected",  HCI_EVENT_LINK_KEY_NOTIFY);
541 		newrequest->AddInt16("eventExpected",  HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE);
542 
543 		AddWantedEvent(newrequest);
544 
545 	    if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) {
546 			(Output::Instance()->Post("Command issue error for ConnAccpq\n", BLACKBOARD_EVENTS));
547 			// remove the request
548 
549 		}
550 		else {
551 			(Output::Instance()->Post("Command issued for ConnAccp\n", BLACKBOARD_EVENTS));
552 
553 
554 		}
555 	}
556 
557 }
558 
559 
560 void
561 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request)
562 {
563 
564 	if (event->status == BT_OK) {
565 
566 		ConnectionIncoming* iConnection = new ConnectionIncoming(new RemoteDevice(event->bdaddr));
567 		iConnection->Show();
568 		printf("%s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), event->handle,
569                                                                  event->link_type, event->encrypt_mode);
570 
571 	} else {
572 		printf("%s: failed with status %#x\n", __FUNCTION__, event->status);
573 	}
574 
575 
576 
577 }
578 
579 
580 void
581 LocalDeviceImpl::DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event, BMessage * request)
582 {
583 	Output::Instance()->Post("Disconnected\n", BLACKBOARD_KIT);
584 }
585 
586 
587 void
588 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request)
589 {
590 
591 	PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID());
592 	iPincode->Show();
593 
594 }
595 
596 
597 void
598 LocalDeviceImpl::RoleChange(hci_ev_role_change *event, BMessage* request, int32 index)
599 {
600 	printf("%s: Address %s role=%d status=%d\n", __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), event->role, event->status);
601 }
602 
603 void
604 LocalDeviceImpl::PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change* event, BMessage* request, int32 index)
605 {
606 	printf("%s: Address %s type=%d\n", __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), event->page_scan_rep_mode);
607 }
608 
609 
610 void
611 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify *event, BMessage* request, int32 index)
612 {
613 
614 	printf("%s: Address %s [----] type=%d\n", __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), event->key_type);
615 
616 }
617 
618 
619 #if 0
620 #pragma mark - Request Methods -
621 #endif
622 
623 
624 status_t
625 LocalDeviceImpl::GetAddress(bdaddr_t* bdaddr, BMessage* request)
626 {
627 	ssize_t ssize;
628 
629 	if (fProperties->FindData("bdaddr", B_ANY_TYPE, 0, (const void **)bdaddr, &ssize) == B_OK) {
630 
631 
632 	    /* We have this info, returning back */
633 	    return B_OK;
634 
635 	} else {
636 		size_t size;
637 
638 	    void* command = buildReadBdAddr(&size);
639 
640 	    /* Adding a wanted event in the queue */
641 	    request->AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
642 	    request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
643 
644 	    AddWantedEvent(request);
645 		request->PrintToStream();
646 
647 	    if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
648 			(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
649 
650 		(Output::Instance()->Post("Command issued for GetAddress\n", BLACKBOARD_EVENTS));
651 	    return B_WOULD_BLOCK;
652 	}
653 
654 }
655 
656 
657 status_t
658 LocalDeviceImpl::GetFriendlyName(BString str, BMessage* request)
659 {
660 
661 	if (fProperties->FindString("friendlyname", &str) == B_OK) {
662 
663 		(Output::Instance()->Post("Friendly name already present in server\n", BLACKBOARD_EVENTS));
664 	    /* We have this info, returning back */
665 	    return B_OK;
666 
667 	} else {
668 		size_t size;
669 
670 	    void* command = buildReadLocalName(&size);
671 
672 	    /* Adding a wanted event in the queue */
673 	    request->AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
674 	    request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME));
675 
676 	    AddWantedEvent(request);
677 		request->PrintToStream();
678 
679 	    if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
680 			(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
681 
682 		(Output::Instance()->Post("Command issued for GetFriendlyname\n", BLACKBOARD_EVENTS));
683 
684 	    return B_WOULD_BLOCK;
685 	}
686 
687 }
688 
689 
690 status_t
691 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request)
692 {
693 	ssize_t size;
694 	void* command = NULL;
695 
696 	if (request->FindData("raw command", B_ANY_TYPE, 0, (const void **)&command, &size) == B_OK) {
697 
698 		AddWantedEvent(request);
699 
700 	    if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) {
701 			// TODO: - Reply the request with error!
702 			//       - Remove the just added request
703 			(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
704 		}
705 		else {
706 
707 			return B_OK;
708 		}
709 	}
710 	else {
711 		(Output::Instance()->Post("No command specified for simple request\n", BLACKBOARD_KIT));
712 	}
713 
714 	return B_ERROR;
715 }
716