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