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