xref: /haiku/src/servers/bluetooth/LocalDeviceImpl.cpp (revision 37c7d5d83a2372a6971e383411d5bacbeef0ebdc)
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 
74 LocalDeviceImpl::~LocalDeviceImpl()
75 {
76 
77 }
78 
79 
80 void
81 LocalDeviceImpl::Unregister()
82 {
83 	BMessage* msg =	new	BMessage(BT_MSG_REMOVE_DEVICE);
84 
85 	msg->AddInt32("hci_id", fHCIDelegate->Id());
86 
87 	Output::Instance()->Postf(BLACKBOARD_DEVICEMANAGER, "Unregistering %x\n",
88 		fHCIDelegate->Id());
89 
90 	be_app_messenger.SendMessage(msg);
91 }
92 
93 
94 #if 0
95 #pragma mark - Event handling methods -
96 #endif
97 
98 template<typename T, typename Header>
99 inline T*
100 JumpEventHeader(Header* event)
101 {
102 	return (T*)(event + 1);
103 }
104 
105 
106 void
107 LocalDeviceImpl::HandleUnexpectedEvent(struct hci_event_header* event)
108 {
109 	// Events here might have not been initated by us
110 	// TODO: ML mark as handled pass a reply by parameter and reply in common
111 	switch (event->ecode) {
112 		case HCI_EVENT_HARDWARE_ERROR:
113 			HardwareError(
114 				JumpEventHeader<struct hci_ev_hardware_error>(event));
115 			break;
116 
117 		case HCI_EVENT_CONN_REQUEST:
118 			ConnectionRequest(
119 				JumpEventHeader<struct hci_ev_conn_request>(event), NULL);
120 			break;
121 
122 		case HCI_EVENT_CONN_COMPLETE:
123 			// should belong to a request? can be sporadic or initiated by us
124 			ConnectionComplete(
125 				JumpEventHeader<struct hci_ev_conn_complete>(event), NULL);
126 			break;
127 
128 		case HCI_EVENT_PIN_CODE_REQ:
129 			PinCodeRequest(
130 				JumpEventHeader<struct hci_ev_pin_code_req>(event), NULL);
131 			break;
132 	}
133 }
134 
135 
136 void
137 LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, BMessage* request)
138 {
139 	// we are waiting for a reply
140 	switch (event->ecode) {
141 		case HCI_EVENT_INQUIRY_COMPLETE:
142 			InquiryComplete(JumpEventHeader<uint8>(event), request);
143 			break;
144 
145 		case HCI_EVENT_INQUIRY_RESULT:
146 			InquiryResult(JumpEventHeader<uint8>(event), request);
147 			break;
148 
149 		case HCI_EVENT_DISCONNECTION_COMPLETE:
150 			// should belong to a request?  can be sporadic or initiated by us¿?...
151 			DisconnectionComplete(
152 				JumpEventHeader<struct hci_ev_disconnection_complete_reply>(event),
153 				request);
154 			break;
155 
156 		case HCI_EVENT_AUTH_COMPLETE:
157 
158 			break;
159 
160 		case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
161 			RemoteNameRequestComplete(
162 				JumpEventHeader<struct hci_ev_remote_name_request_complete_reply>
163 				(event), request);
164 			break;
165 
166 		case HCI_EVENT_ENCRYPT_CHANGE:
167 			break;
168 
169 		case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE:
170 			break;
171 
172 		case HCI_EVENT_MASTER_LINK_KEY_COMPL:
173 			break;
174 
175 		case HCI_EVENT_RMT_FEATURES:
176 			break;
177 
178 		case HCI_EVENT_RMT_VERSION:
179 			break;
180 
181 		case HCI_EVENT_QOS_SETUP_COMPLETE:
182 			break;
183 
184 		case HCI_EVENT_FLUSH_OCCUR:
185 			break;
186 
187 		case HCI_EVENT_ROLE_CHANGE:
188 			RoleChange(JumpEventHeader<struct hci_ev_role_change>(event), request);
189 			break;
190 
191 		case HCI_EVENT_NUM_COMP_PKTS:
192 			break;
193 
194 		case HCI_EVENT_MODE_CHANGE:
195 			break;
196 
197 		case HCI_EVENT_RETURN_LINK_KEYS:
198 			break;
199 
200 		case HCI_EVENT_LINK_KEY_REQ:
201 			break;
202 
203 		case HCI_EVENT_LINK_KEY_NOTIFY:
204 			LinkKeyNotify(JumpEventHeader<struct hci_ev_link_key_notify>
205 				(event), request);
206 			break;
207 
208 		case HCI_EVENT_LOOPBACK_COMMAND:
209 			break;
210 
211 		case HCI_EVENT_DATA_BUFFER_OVERFLOW:
212 			break;
213 
214 		case HCI_EVENT_MAX_SLOT_CHANGE:
215 			MaxSlotChange(JumpEventHeader<struct hci_ev_max_slot_change>(event),
216 			request);
217 			break;
218 
219 		case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
220 			break;
221 
222 		case HCI_EVENT_CON_PKT_TYPE_CHANGED:
223 			break;
224 
225 		case HCI_EVENT_QOS_VIOLATION:
226 			break;
227 
228 		case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE:
229 			PageScanRepetitionModeChange(
230 				JumpEventHeader<struct hci_ev_page_scan_rep_mode_change>(event),
231 				request);
232 			break;
233 
234 		case HCI_EVENT_FLOW_SPECIFICATION:
235 			break;
236 
237 		case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
238 			break;
239 
240 		case HCI_EVENT_REMOTE_EXTENDED_FEATURES:
241 			break;
242 
243 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED:
244 			break;
245 
246 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED:
247 			break;
248 	}
249 }
250 
251 
252 void
253 LocalDeviceImpl::HandleEvent(struct hci_event_header* event)
254 {
255 
256 	printf("### Incoming event: len = %d\n", event->elen);
257 	for (int16 index = 0; index < event->elen + 2; index++) {
258 		printf("%x:", ((uint8*)event)[index]);
259 	}
260 	printf("### \n");
261 
262 	BMessage* request = NULL;
263 	int32 eventIndexLocation;
264 
265 	// Check if it is a requested one
266 	switch (event->ecode) {
267 		case HCI_EVENT_CMD_COMPLETE:
268 		{
269 			struct hci_ev_cmd_complete* commandComplete
270 				= JumpEventHeader<struct hci_ev_cmd_complete>(event);
271 
272 			Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
273 				"Incomming CommandComplete for %s\n",
274 				BluetoothCommandOpcode(commandComplete->opcode));
275 
276 			request = FindPetition(event->ecode, commandComplete->opcode,
277 				&eventIndexLocation);
278 
279 			if (request != NULL)
280 				CommandComplete(commandComplete, request, eventIndexLocation);
281 
282 			break;
283 		}
284 		case HCI_EVENT_CMD_STATUS:
285 		{
286 			struct hci_ev_cmd_status* commandStatus
287 				= JumpEventHeader<struct hci_ev_cmd_status>(event);
288 
289 			Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
290 				"Incomming CommandStatus for %s\n",
291 				BluetoothCommandOpcode(commandStatus->opcode));
292 
293 			request = FindPetition(event->ecode, commandStatus->opcode,
294 				&eventIndexLocation);
295 			if (request != NULL)
296 				CommandStatus(commandStatus, request, eventIndexLocation);
297 
298 			break;
299 		}
300 		default:
301 			Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"Incomming %s event\n",
302 				BluetoothEvent(event->ecode));
303 
304 			request = FindPetition(event->ecode);
305 			if (request != NULL)
306 				HandleExpectedRequest(event, request);
307 
308 			break;
309 	}
310 
311 	if (request == NULL)
312 		Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
313 			"Event %s could not be understood or delivered\n",
314 			BluetoothEvent(event->ecode));
315 
316 	HandleUnexpectedEvent(event);
317 
318 }
319 
320 
321 #if 0
322 #pragma mark -
323 #endif
324 
325 
326 void
327 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
328 	BMessage* request,
329 	int32 index) {
330 
331 	int16 opcodeExpected;
332 	BMessage reply;
333 
334 	// Handle command complete information
335 	request->FindInt16("opcodeExpected", index, &opcodeExpected);
336 
337 	if (request->IsSourceWaiting() == false)
338 		Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
339 
340 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) for %s\n",
341 		__FUNCTION__, event->ncmd, BluetoothCommandOpcode(opcodeExpected));
342 
343 	switch ((uint16)opcodeExpected) {
344 
345 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION):
346 		{
347 			struct hci_rp_read_loc_version* version
348 				= JumpEventHeader<struct hci_rp_read_loc_version,
349 				struct hci_ev_cmd_complete>(event);
350 
351 
352 			if (version->status == BT_OK) {
353 
354 				if (!IsPropertyAvailable("hci_version"))
355 					fProperties->AddInt8("hci_version", version->hci_version);
356 
357 				if (!IsPropertyAvailable("hci_revision"))
358 					fProperties->AddInt16("hci_revision", version->hci_revision);
359 
360 				if (!IsPropertyAvailable("lmp_version"))
361 					fProperties->AddInt8("lmp_version", version->lmp_version);
362 
363 				if (!IsPropertyAvailable("lmp_subversion"))
364 					fProperties->AddInt16("lmp_subversion", version->lmp_subversion);
365 
366 				if (!IsPropertyAvailable("manufacturer"))
367 					fProperties->AddInt16("manufacturer", version->manufacturer);
368 
369 			}
370 
371 			Output::Instance()->Postf(BLACKBOARD_KIT,
372 				"Reply for Local Version %x\n", version->status);
373 
374 			reply.AddInt8("status", version->status);
375 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
376 			reply.PrintToStream();
377 
378 			// This request is not gonna be used anymore
379 			ClearWantedEvent(request);
380 			break;
381 		}
382 
383 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_FEATURES):
384 		{
385 			struct hci_rp_read_loc_features* features
386 				= JumpEventHeader<struct hci_rp_read_loc_features,
387 				struct hci_ev_cmd_complete>(event);
388 
389 			if (features->status == BT_OK) {
390 
391 				if (!IsPropertyAvailable("features")) {
392 					fProperties->AddData("features", B_ANY_TYPE, &features->features, 8);
393 
394 					uint16 packetType = HCI_DM1 | HCI_DH1 | HCI_HV1;
395 					bool roleSwitch = (features->features[0] & LMP_RSWITCH) != 0;
396 					bool encryptCapable = (features->features[0] & LMP_ENCRYPT) != 0;
397 
398 					if (features->features[0] & LMP_3SLOT)
399 						packetType |= (HCI_DM3 | HCI_DH3);
400 
401 					if (features->features[0] & LMP_5SLOT)
402 						packetType |= (HCI_DM5 | HCI_DH5);
403 
404 					if (features->features[1] & LMP_HV2)
405 						packetType |= (HCI_HV2);
406 
407 					if (features->features[1] & LMP_HV3)
408 						packetType |= (HCI_HV3);
409 
410 					fProperties->AddInt16("packet_type", packetType);
411 					fProperties->AddBool("role_switch_capable", roleSwitch);
412 					fProperties->AddBool("encrypt_capable", encryptCapable);
413 
414 					Output::Instance()->Postf(BLACKBOARD_KIT,
415 						"Packet type %x role switch %d encrypt %d\n",
416 						packetType, roleSwitch, encryptCapable);
417 				}
418 
419 			}
420 
421 			Output::Instance()->Postf(BLACKBOARD_KIT,
422 				"Reply for Local Features %x\n", features->status);
423 
424 			reply.AddInt8("status", features->status);
425 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
426 			reply.PrintToStream();
427 
428 			// This request is not gonna be used anymore
429 			ClearWantedEvent(request);
430 			break;
431 		}
432 
433 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE):
434 		{
435 			struct hci_rp_read_buffer_size* buffer
436 				= JumpEventHeader<struct hci_rp_read_buffer_size,
437 				struct hci_ev_cmd_complete>(event);
438 
439 			if (buffer->status == BT_OK) {
440 
441 				if (!IsPropertyAvailable("acl_mtu"))
442 					fProperties->AddInt16("acl_mtu", buffer->acl_mtu);
443 
444 				if (!IsPropertyAvailable("sco_mtu"))
445 					fProperties->AddInt8("sco_mtu", buffer->sco_mtu);
446 
447 				if (!IsPropertyAvailable("acl_max_pkt"))
448 					fProperties->AddInt16("acl_max_pkt", buffer->acl_max_pkt);
449 
450 				if (!IsPropertyAvailable("sco_max_pkt"))
451 					fProperties->AddInt16("sco_max_pkt", buffer->sco_max_pkt);
452 
453 			}
454 
455 			Output::Instance()->Postf(BLACKBOARD_KIT,
456 				"Reply for Read Buffer Size %x\n", buffer->status);
457 
458 
459 			reply.AddInt8("status", buffer->status);
460 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
461 			reply.PrintToStream();
462 
463 			// This request is not gonna be used anymore
464 			ClearWantedEvent(request);
465 		}
466 		break;
467 
468 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR):
469 		{
470 			struct hci_rp_read_bd_addr* readbdaddr
471 				= JumpEventHeader<struct hci_rp_read_bd_addr,
472 				struct hci_ev_cmd_complete>(event);
473 
474 			if (readbdaddr->status == BT_OK) {
475 				reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr,
476 					sizeof(bdaddr_t));
477 			}
478 
479 			Output::Instance()->Postf(BLACKBOARD_KIT,
480 				"Read bdaddr status = %x\n", readbdaddr->status);
481 
482 			reply.AddInt8("status", readbdaddr->status);
483 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
484 			reply.PrintToStream();
485 
486 			// This request is not gonna be used anymore
487 			ClearWantedEvent(request);
488 		}
489 		break;
490 
491 
492 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV):
493 		{
494 			struct hci_read_dev_class_reply* classDev
495 				= JumpEventHeader<struct hci_read_dev_class_reply,
496 				struct hci_ev_cmd_complete>(event);
497 
498 			if (classDev->status == BT_OK) {
499 				reply.AddData("devclass", B_ANY_TYPE, &classDev->dev_class,
500 					sizeof(classDev->dev_class));
501 			}
502 
503 			Output::Instance()->Postf(BLACKBOARD_KIT,
504 				"Read DeviceClass status = %x DeviceClass = [%x][%x][%x]\n",
505 				classDev->status, classDev->dev_class[0],
506 				classDev->dev_class[1], classDev->dev_class[2]);
507 
508 
509 			reply.AddInt8("status", classDev->status);
510 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
511 			reply.PrintToStream();
512 
513 			// This request is not gonna be used anymore
514 			ClearWantedEvent(request);
515 		}
516 		break;
517 
518 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME):
519 		{
520 			struct hci_rp_read_local_name* readLocalName
521 				= JumpEventHeader<struct hci_rp_read_local_name,
522 				struct hci_ev_cmd_complete>(event);
523 
524 
525 			if (readLocalName->status == BT_OK) {
526 				reply.AddString("friendlyname", (const char*)readLocalName->local_name);
527 			}
528 
529 			Output::Instance()->Postf(BLACKBOARD_KIT, "Friendly name status %x\n",
530 				readLocalName->status);
531 
532 			reply.AddInt8("status", readLocalName->status);
533 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
534 			reply.PrintToStream();
535 
536 			// This request is not gonna be used anymore
537 			ClearWantedEvent(request);
538 		}
539 		break;
540 
541 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY):
542 		{
543 			uint8* statusReply = (uint8*)(event + 1);
544 
545 			// TODO: This reply has to match the BDADDR of the outgoing message
546 			Output::Instance()->Postf(BLACKBOARD_KIT, "pincode accept status %x\n",
547 				*statusReply);
548 
549 			reply.AddInt8("status", *statusReply);
550 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
551 			reply.PrintToStream();
552 
553 			// This request is not gonna be used anymore
554 			ClearWantedEvent(request);
555 		}
556 		break;
557 
558 
559 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY):
560 		{
561 			uint8* statusReply = (uint8*)(event + 1);
562 
563 			// TODO: This reply might to match the BDADDR of the outgoing message
564 			// => FindPetition should be expanded....
565 			Output::Instance()->Postf(BLACKBOARD_KIT, "pincode reject status %x\n",
566 				*statusReply);
567 
568 			reply.AddInt8("status", *statusReply);
569 			printf("Sending reply ... %ld\n",request->SendReply(&reply));
570 			reply.PrintToStream();
571 
572 			// This request is not gonna be used anymore
573 			ClearWantedEvent(request);
574 		}
575 		break;
576 
577 		// place here all CC that just replies a uint8 status
578 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET):
579 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE):
580 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV):
581 		case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR):
582 		{
583 			reply.AddInt8("status", *(uint8*)(event + 1));
584 
585 			Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s for %s status %x\n",
586 				__FUNCTION__, BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1));
587 
588 			request->SendReply(&reply);
589 
590 			ClearWantedEvent(request);
591 		}
592 		break;
593 
594 		default:
595 			Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT);
596 		break;
597 
598 	}
599 }
600 
601 
602 void
603 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* request,
604 	int32 index) {
605 
606 	int16 opcodeExpected;
607 	BMessage reply;
608 
609 	// Handle command complete information
610 	request->FindInt16("opcodeExpected", index, &opcodeExpected);
611 
612 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) %x for %s\n",
613 		__FUNCTION__, event->ncmd, event->status,
614 		BluetoothCommandOpcode(event->opcode));
615 
616 	if (request->IsSourceWaiting() == false)
617 		Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
618 
619 	switch (opcodeExpected) {
620 
621 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY):
622 		{
623 			reply.what = BT_MSG_INQUIRY_STARTED;
624 
625 			Output::Instance()->Postf(BLACKBOARD_KIT,
626 				"Inquiry status %x\n", event->status);
627 
628 			reply.AddInt8("status", event->status);
629 			printf("Sending reply ... %ld\n", request->SendReply(&reply));
630 			reply.PrintToStream();
631 
632 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
633 				PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY));
634 		}
635 		break;
636 
637 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST):
638 		{
639 			if (event->status == BT_OK) {
640 				ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
641 					PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST));
642 			} else {
643 				Output::Instance()->Postf(BLACKBOARD_KIT,
644 					"Command Status for remote friendly name %x\n", event->status);
645 
646 				reply.AddInt8("status", event->status);
647 				printf("Sending reply ... %ld\n", request->SendReply(&reply));
648 				reply.PrintToStream();
649 
650 				ClearWantedEvent(request);
651 			}
652 		}
653 		break;
654 		/*
655 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ):
656 		{
657 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
658 				PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ));
659 		}
660 		break;
661 
662 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ):
663 		{
664 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
665 				PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ));
666 		}
667 		break;*/
668 
669 		default:
670 			Output::Instance()->Post("Command Status not handled\n", BLACKBOARD_KIT);
671 		break;
672 	}
673 
674 }
675 
676 
677 void
678 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request)
679 {
680 
681 	BMessage reply(BT_MSG_INQUIRY_DEVICE);
682 
683 	// skipping here the number of responses
684 	reply.AddData("info", B_ANY_TYPE, numberOfResponses + 1,
685 		(*numberOfResponses) * sizeof(struct inquiry_info) );
686 
687 	reply.AddInt8("count", *numberOfResponses);
688 
689 	printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply));
690 
691 }
692 
693 
694 void
695 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request)
696 {
697 	BMessage reply(BT_MSG_INQUIRY_COMPLETED);
698 
699 	reply.AddInt8("status", *status);
700 	printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply));
701 
702 	ClearWantedEvent(request);
703 }
704 
705 
706 void
707 LocalDeviceImpl::RemoteNameRequestComplete(
708 	struct hci_ev_remote_name_request_complete_reply* remotename,
709 	BMessage* request)
710 {
711 	BMessage reply;
712 
713 	if (remotename->status == BT_OK) {
714 		reply.AddString("friendlyname", (const char*)remotename->remote_name );
715 	}
716 
717 	reply.AddInt8("status", remotename->status);
718 
719 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
720 		"%s for %s with status %s\n",
721 		BluetoothEvent(HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE),
722 		bdaddrUtils::ToString(remotename->bdaddr),
723 		BluetoothError(remotename->status));
724 
725 	printf("Sending reply ... %ld\n", request->SendReply(&reply));
726 	reply.PrintToStream();
727 
728 	// This request is not gonna be used anymore
729 	ClearWantedEvent(request);
730 }
731 
732 
733 void
734 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, BMessage* request)
735 {
736 	size_t size;
737 	void* command;
738 
739 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
740 		"Connection Incoming type %x from %s...\n",
741 		event->link_type, bdaddrUtils::ToString(event->bdaddr));
742 
743 	// TODO: add a possible request in the queue
744 	if (true) { // Check Preferences if we are to accept this connection
745 
746 		command = buildAcceptConnectionRequest(event->bdaddr, 0x01 /*slave*/, &size);
747 
748 		BMessage* newrequest = new BMessage;
749 		newrequest->AddInt16("eventExpected",  HCI_EVENT_CMD_STATUS);
750 		newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
751 			OCF_ACCEPT_CONN_REQ));
752 
753 		newrequest->AddInt16("eventExpected",  HCI_EVENT_PIN_CODE_REQ);
754 		newrequest->AddInt16("eventExpected",  HCI_EVENT_ROLE_CHANGE);
755 		newrequest->AddInt16("eventExpected",  HCI_EVENT_LINK_KEY_NOTIFY);
756 		newrequest->AddInt16("eventExpected",  HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE);
757 		//newrequest->AddInt16("eventExpected",  HCI_EVENT_MAX_SLOT_CHANGE);
758 		//newrequest->AddInt16("eventExpected",  HCI_EVENT_DISCONNECTION_COMPLETE);
759 
760 		AddWantedEvent(newrequest);
761 
762 		if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) {
763 			Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
764 				"Command issue error for ConnAccept\n");
765 				// remove the request?
766 		} else {
767 			Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
768 				"Command issue for ConnAccept\n");
769 		}
770 	}
771 }
772 
773 
774 void
775 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request)
776 {
777 
778 	if (event->status == BT_OK) {
779 		uint8 cod[3] = {0, 0, 0};
780 
781 		ConnectionIncoming* iConnection = new ConnectionIncoming(
782 			new RemoteDevice(event->bdaddr, cod));
783 		iConnection->Show();
784 
785 		Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
786 			"%s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__,
787 				bdaddrUtils::ToString(event->bdaddr), event->handle,
788 				event->link_type, event->encrypt_mode);
789 
790 	} else {
791 		Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
792 			"%s: failed with status %#x\n", __FUNCTION__, event->status);
793 	}
794 
795 }
796 
797 
798 void
799 LocalDeviceImpl::DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event, BMessage* request)
800 {
801 	Output::Instance()->Post("Disconnected\n", BLACKBOARD_KIT);
802 
803 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
804 		"%s: Handle=%#x, reason=%x status=%x\n", __FUNCTION__, event->handle,
805 		event->reason, event->status);
806 
807 	ClearWantedEvent(request);
808 }
809 
810 
811 void
812 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request)
813 {
814 	PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID());
815 	iPincode->Show();
816 }
817 
818 
819 void
820 LocalDeviceImpl::RoleChange(hci_ev_role_change* event, BMessage* request)
821 {
822 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
823 		"%s: Address %s role=%d status=%d\n", __FUNCTION__,
824 		bdaddrUtils::ToString(event->bdaddr), event->role, event->status);
825 }
826 
827 
828 void
829 LocalDeviceImpl::PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change* event,
830 	BMessage* request)
831 {
832 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
833 		"%s: Address %s type=%d\n",	__FUNCTION__,
834 		bdaddrUtils::ToString(event->bdaddr), event->page_scan_rep_mode);
835 }
836 
837 
838 void
839 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify* event,
840 	BMessage* request)
841 {
842 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
843 		"%s: Address %s, key=%s, type=%d\n", __FUNCTION__,
844 		bdaddrUtils::ToString(event->bdaddr),
845 		LinkKeyUtils::ToString(event->link_key), event->key_type);
846 }
847 
848 
849 void
850 LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change* event,
851 	BMessage* request)
852 {
853 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
854 		"%s: Handle=%#x, max slots=%d\n", __FUNCTION__,
855 		event->handle, event->lmp_max_slots);
856 }
857 
858 
859 void
860 LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error* event)
861 {
862 	Output::Instance()->Postf(BLACKBOARD_LD(GetID()),
863 		"%s: hardware code=%#x\n",	__FUNCTION__, event->hardware_code);
864 }
865 
866 
867 #if 0
868 #pragma mark - Request Methods -
869 #endif
870 
871 
872 status_t
873 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request)
874 {
875 	ssize_t size;
876 	void* command = NULL;
877 
878 	if (request->FindData("raw command", B_ANY_TYPE, 0,
879 		(const void **)&command, &size) == B_OK) {
880 
881 		AddWantedEvent(request);
882 		// LEAK: is command buffer freed within the Message?
883 		if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size)
884 			== B_ERROR) {
885 			// TODO:
886 			// Reply the request with error!
887 			// Remove the just added request
888 			(Output::Instance()->Post("## ERROR Command issue, REMOVING!\n",
889 				BLACKBOARD_KIT));
890 			ClearWantedEvent(request);
891 
892 		} else {
893 			return B_OK;
894 		}
895 	} else {
896 		(Output::Instance()->Post("No command specified for simple request\n",
897 			BLACKBOARD_KIT));
898 	}
899 
900 	return B_ERROR;
901 }
902