xref: /haiku/src/servers/bluetooth/LocalDeviceImpl.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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 "Debug.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 	TRACE_BT("LocalDeviceImpl: Unregistering %" B_PRId32 "\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_NUM_COMP_PKTS:
123 			NumberOfCompletedPackets(
124 				JumpEventHeader<struct hci_ev_num_comp_pkts>(event));
125 			break;
126 
127 		case HCI_EVENT_DISCONNECTION_COMPLETE:
128 			// should belong to a request?  can be sporadic or initiated by us?
129 			DisconnectionComplete(
130 				JumpEventHeader
131 					<struct hci_ev_disconnection_complete_reply>(event),
132 				NULL);
133 			break;
134 		case HCI_EVENT_PIN_CODE_REQ:
135 			PinCodeRequest(
136 				JumpEventHeader<struct hci_ev_pin_code_req>(event), NULL);
137 			break;
138 		default:
139 			// TODO: feedback unexpected not handled
140 			break;
141 	}
142 }
143 
144 
145 void
146 LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event,
147 	BMessage* request)
148 {
149 	// we are waiting for a reply
150 	switch (event->ecode) {
151 		case HCI_EVENT_INQUIRY_COMPLETE:
152 			InquiryComplete(JumpEventHeader<uint8>(event), request);
153 			break;
154 
155 		case HCI_EVENT_INQUIRY_RESULT:
156 			InquiryResult(JumpEventHeader<uint8>(event), request);
157 			break;
158 
159 		case HCI_EVENT_CONN_COMPLETE:
160 			ConnectionComplete(
161 				JumpEventHeader<struct hci_ev_conn_complete>(event), request);
162 			break;
163 
164 		case HCI_EVENT_DISCONNECTION_COMPLETE:
165 			// should belong to a request?  can be sporadic or initiated by us?
166 			DisconnectionComplete(
167 				JumpEventHeader<struct hci_ev_disconnection_complete_reply>
168 				(event), request);
169 			break;
170 
171 		case HCI_EVENT_AUTH_COMPLETE:
172 
173 			break;
174 
175 		case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
176 			RemoteNameRequestComplete(
177 				JumpEventHeader
178 					<struct hci_ev_remote_name_request_complete_reply>
179 				(event), request);
180 			break;
181 
182 		case HCI_EVENT_ENCRYPT_CHANGE:
183 			break;
184 
185 		case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE:
186 			break;
187 
188 		case HCI_EVENT_MASTER_LINK_KEY_COMPL:
189 			break;
190 
191 		case HCI_EVENT_RMT_FEATURES:
192 			break;
193 
194 		case HCI_EVENT_RMT_VERSION:
195 			break;
196 
197 		case HCI_EVENT_QOS_SETUP_COMPLETE:
198 			break;
199 
200 		case HCI_EVENT_FLUSH_OCCUR:
201 			break;
202 
203 		case HCI_EVENT_ROLE_CHANGE:
204 			RoleChange(
205 				JumpEventHeader<struct hci_ev_role_change>(event), request);
206 			break;
207 
208 		case HCI_EVENT_MODE_CHANGE:
209 			break;
210 
211 		case HCI_EVENT_RETURN_LINK_KEYS:
212 			ReturnLinkKeys(
213 				JumpEventHeader<struct hci_ev_return_link_keys>(event));
214 			break;
215 
216 		case HCI_EVENT_LINK_KEY_REQ:
217 			LinkKeyRequested(
218 				JumpEventHeader<struct hci_ev_link_key_req>(event), request);
219 			break;
220 
221 		case HCI_EVENT_LINK_KEY_NOTIFY:
222 			LinkKeyNotify(
223 				JumpEventHeader<struct hci_ev_link_key_notify>(event), request);
224 			break;
225 
226 		case HCI_EVENT_LOOPBACK_COMMAND:
227 			break;
228 
229 		case HCI_EVENT_DATA_BUFFER_OVERFLOW:
230 			break;
231 
232 		case HCI_EVENT_MAX_SLOT_CHANGE:
233 			MaxSlotChange(JumpEventHeader<struct hci_ev_max_slot_change>(event),
234 			request);
235 			break;
236 
237 		case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
238 			break;
239 
240 		case HCI_EVENT_CON_PKT_TYPE_CHANGED:
241 			break;
242 
243 		case HCI_EVENT_QOS_VIOLATION:
244 			break;
245 
246 		case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE:
247 			PageScanRepetitionModeChange(
248 				JumpEventHeader<struct hci_ev_page_scan_rep_mode_change>(event),
249 				request);
250 			break;
251 
252 		case HCI_EVENT_FLOW_SPECIFICATION:
253 			break;
254 
255 		case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
256 			break;
257 
258 		case HCI_EVENT_REMOTE_EXTENDED_FEATURES:
259 			break;
260 
261 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED:
262 			break;
263 
264 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED:
265 			break;
266 	}
267 }
268 
269 
270 void
271 LocalDeviceImpl::HandleEvent(struct hci_event_header* event)
272 {
273 /*
274 	printf("### Incoming event: len = %d\n", event->elen);
275 	for (int16 index = 0; index < event->elen + 2; index++) {
276 		printf("%x:", ((uint8*)event)[index]);
277 	}
278 	printf("### \n");
279 */
280 	BMessage* request = NULL;
281 	int32 eventIndexLocation;
282 
283 	// Check if it is a requested one
284 	switch (event->ecode) {
285 		case HCI_EVENT_CMD_COMPLETE:
286 		{
287 			struct hci_ev_cmd_complete* commandComplete
288 				= JumpEventHeader<struct hci_ev_cmd_complete>(event);
289 
290 			TRACE_BT("LocalDeviceImpl: Incoming CommandComplete(%d) for %s\n", commandComplete->ncmd,
291 				BluetoothCommandOpcode(commandComplete->opcode));
292 
293 			request = FindPetition(event->ecode, commandComplete->opcode,
294 				&eventIndexLocation);
295 
296 			if (request != NULL)
297 				CommandComplete(commandComplete, request, eventIndexLocation);
298 
299 			break;
300 		}
301 		case HCI_EVENT_CMD_STATUS:
302 		{
303 			struct hci_ev_cmd_status* commandStatus
304 				= JumpEventHeader<struct hci_ev_cmd_status>(event);
305 
306 			TRACE_BT("LocalDeviceImpl: Incoming CommandStatus(%d)(%s) for %s\n", commandStatus->ncmd,
307 				BluetoothError(commandStatus->status),
308 				BluetoothCommandOpcode(commandStatus->opcode));
309 
310 			request = FindPetition(event->ecode, commandStatus->opcode,
311 				&eventIndexLocation);
312 			if (request != NULL)
313 				CommandStatus(commandStatus, request, eventIndexLocation);
314 
315 			break;
316 		}
317 		default:
318 			TRACE_BT("LocalDeviceImpl: Incoming %s event\n", BluetoothEvent(event->ecode));
319 
320 			request = FindPetition(event->ecode);
321 			if (request != NULL)
322 				HandleExpectedRequest(event, request);
323 
324 			break;
325 	}
326 
327 	if (request == NULL) {
328 		TRACE_BT("LocalDeviceImpl: Event %s could not be understood or delivered\n",
329 			BluetoothEvent(event->ecode));
330 		HandleUnexpectedEvent(event);
331 	}
332 }
333 
334 
335 #if 0
336 #pragma mark -
337 #endif
338 
339 
340 void
341 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
342 	BMessage* request, int32 index)
343 {
344 	int16 opcodeExpected;
345 	BMessage reply;
346 	status_t status;
347 
348 	// Handle command complete information
349 	request->FindInt16("opcodeExpected", index, &opcodeExpected);
350 
351 	if (request->IsSourceWaiting() == false) {
352 		TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n");
353 	}
354 
355 	switch ((uint16)opcodeExpected) {
356 
357 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION):
358 		{
359 			struct hci_rp_read_loc_version* version
360 				= JumpEventHeader<struct hci_rp_read_loc_version,
361 				struct hci_ev_cmd_complete>(event);
362 
363 
364 			if (version->status == BT_OK) {
365 
366 				if (!IsPropertyAvailable("hci_version"))
367 					fProperties->AddInt8("hci_version", version->hci_version);
368 
369 				if (!IsPropertyAvailable("hci_revision")) {
370 					fProperties->AddInt16("hci_revision",
371 						version->hci_revision);
372 				}
373 
374 				if (!IsPropertyAvailable("lmp_version"))
375 					fProperties->AddInt8("lmp_version", version->lmp_version);
376 
377 				if (!IsPropertyAvailable("lmp_subversion")) {
378 					fProperties->AddInt16("lmp_subversion",
379 						version->lmp_subversion);
380 				}
381 
382 				if (!IsPropertyAvailable("manufacturer")) {
383 					fProperties->AddInt16("manufacturer",
384 						version->manufacturer);
385 				}
386 			}
387 
388 			TRACE_BT("LocalDeviceImpl: Reply for Local Version %x\n", version->status);
389 
390 			reply.AddInt8("status", version->status);
391 			status = request->SendReply(&reply);
392 			//printf("Sending reply... %ld\n", status);
393 			// debug reply.PrintToStream();
394 
395 			// This request is not gonna be used anymore
396 			ClearWantedEvent(request);
397 			break;
398 		}
399 
400 		case  PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_PG_TIMEOUT):
401 		{
402 			struct hci_rp_read_page_timeout* pageTimeout
403 				= JumpEventHeader<struct hci_rp_read_page_timeout,
404 				struct hci_ev_cmd_complete>(event);
405 
406 			if (pageTimeout->status == BT_OK) {
407 				fProperties->AddInt16("page_timeout",
408 					pageTimeout->page_timeout);
409 
410 				TRACE_BT("LocalDeviceImpl: Page Timeout=%x\n", pageTimeout->page_timeout);
411 			}
412 
413 			reply.AddInt8("status", pageTimeout->status);
414 			reply.AddInt32("result", pageTimeout->page_timeout);
415 			status = request->SendReply(&reply);
416 			//printf("Sending reply... %ld\n", status);
417 			// debug reply.PrintToStream();
418 
419 			// This request is not gonna be used anymore
420 			ClearWantedEvent(request);
421 			break;
422 		}
423 
424 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_FEATURES):
425 		{
426 			struct hci_rp_read_loc_features* features
427 				= JumpEventHeader<struct hci_rp_read_loc_features,
428 				struct hci_ev_cmd_complete>(event);
429 
430 			if (features->status == BT_OK) {
431 
432 				if (!IsPropertyAvailable("features")) {
433 					fProperties->AddData("features", B_ANY_TYPE,
434 						&features->features, 8);
435 
436 					uint16 packetType = HCI_DM1 | HCI_DH1 | HCI_HV1;
437 
438 					bool roleSwitch
439 						= (features->features[0] & LMP_RSWITCH) != 0;
440 					bool encryptCapable
441 						= (features->features[0] & LMP_ENCRYPT) != 0;
442 
443 					if (features->features[0] & LMP_3SLOT)
444 						packetType |= (HCI_DM3 | HCI_DH3);
445 
446 					if (features->features[0] & LMP_5SLOT)
447 						packetType |= (HCI_DM5 | HCI_DH5);
448 
449 					if (features->features[1] & LMP_HV2)
450 						packetType |= (HCI_HV2);
451 
452 					if (features->features[1] & LMP_HV3)
453 						packetType |= (HCI_HV3);
454 
455 					fProperties->AddInt16("packet_type", packetType);
456 					fProperties->AddBool("role_switch_capable", roleSwitch);
457 					fProperties->AddBool("encrypt_capable", encryptCapable);
458 
459 					TRACE_BT("LocalDeviceImpl: Packet type %x role switch %d encrypt %d\n",
460 						packetType, roleSwitch, encryptCapable);
461 				}
462 
463 			}
464 
465 			TRACE_BT("LocalDeviceImpl: Reply for Local Features %x\n", features->status);
466 
467 			reply.AddInt8("status", features->status);
468 			status = request->SendReply(&reply);
469 			//printf("Sending reply... %ld\n", status);
470 			// debug reply.PrintToStream();
471 
472 			// This request is not gonna be used anymore
473 			ClearWantedEvent(request);
474 			break;
475 		}
476 
477 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE):
478 		{
479 			struct hci_rp_read_buffer_size* buffer
480 				= JumpEventHeader<struct hci_rp_read_buffer_size,
481 				struct hci_ev_cmd_complete>(event);
482 
483 			if (buffer->status == BT_OK) {
484 
485 				if (!IsPropertyAvailable("acl_mtu"))
486 					fProperties->AddInt16("acl_mtu", buffer->acl_mtu);
487 
488 				if (!IsPropertyAvailable("sco_mtu"))
489 					fProperties->AddInt8("sco_mtu", buffer->sco_mtu);
490 
491 				if (!IsPropertyAvailable("acl_max_pkt"))
492 					fProperties->AddInt16("acl_max_pkt", buffer->acl_max_pkt);
493 
494 				if (!IsPropertyAvailable("sco_max_pkt"))
495 					fProperties->AddInt16("sco_max_pkt", buffer->sco_max_pkt);
496 
497 			}
498 
499 			TRACE_BT("LocalDeviceImpl: Reply for Read Buffer Size %x\n", buffer->status);
500 
501 
502 			reply.AddInt8("status", buffer->status);
503 			status = request->SendReply(&reply);
504 			//printf("Sending reply... %ld\n", status);
505 			// debug reply.PrintToStream();
506 
507 			// This request is not gonna be used anymore
508 			ClearWantedEvent(request);
509 		}
510 		break;
511 
512 		case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR):
513 		{
514 			struct hci_rp_read_bd_addr* readbdaddr
515 				= JumpEventHeader<struct hci_rp_read_bd_addr,
516 				struct hci_ev_cmd_complete>(event);
517 
518 			if (readbdaddr->status == BT_OK) {
519 				reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr,
520 					sizeof(bdaddr_t));
521 			}
522 
523 			TRACE_BT("LocalDeviceImpl: Read bdaddr status = %x\n", readbdaddr->status);
524 
525 			reply.AddInt8("status", readbdaddr->status);
526 			status = request->SendReply(&reply);
527 			//printf("Sending reply... %ld\n", status);
528 			// debug reply.PrintToStream();
529 
530 			// This request is not gonna be used anymore
531 			ClearWantedEvent(request);
532 		}
533 		break;
534 
535 
536 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV):
537 		{
538 			struct hci_read_dev_class_reply* classDev
539 				= JumpEventHeader<struct hci_read_dev_class_reply,
540 				struct hci_ev_cmd_complete>(event);
541 
542 			if (classDev->status == BT_OK) {
543 				reply.AddData("devclass", B_ANY_TYPE, &classDev->dev_class,
544 					sizeof(classDev->dev_class));
545 			}
546 
547 			TRACE_BT("LocalDeviceImpl: Read DeviceClass status = %x DeviceClass = [%x][%x][%x]\n",
548 				classDev->status, classDev->dev_class[0],
549 				classDev->dev_class[1], classDev->dev_class[2]);
550 
551 
552 			reply.AddInt8("status", classDev->status);
553 			status = request->SendReply(&reply);
554 			//printf("Sending reply... %ld\n", status);
555 			// debug reply.PrintToStream();
556 
557 			// This request is not gonna be used anymore
558 			ClearWantedEvent(request);
559 			break;
560 		}
561 
562 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME):
563 		{
564 			struct hci_rp_read_local_name* readLocalName
565 				= JumpEventHeader<struct hci_rp_read_local_name,
566 				struct hci_ev_cmd_complete>(event);
567 
568 
569 			if (readLocalName->status == BT_OK) {
570 				reply.AddString("friendlyname",
571 					(const char*)readLocalName->local_name);
572 			}
573 
574 			TRACE_BT("LocalDeviceImpl: Friendly name status %x\n", readLocalName->status);
575 
576 			reply.AddInt8("status", readLocalName->status);
577 			status = request->SendReply(&reply);
578 			//printf("Sending reply... %ld\n", status);
579 			// debug reply.PrintToStream();
580 
581 			// This request is not gonna be used anymore
582 			ClearWantedEvent(request);
583 			break;
584 		}
585 
586 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY):
587 		{
588 			uint8* statusReply = (uint8*)(event + 1);
589 
590 			// TODO: This reply has to match the BDADDR of the outgoing message
591 			TRACE_BT("LocalDeviceImpl: pincode accept status %x\n", *statusReply);
592 
593 			reply.AddInt8("status", *statusReply);
594 			status = request->SendReply(&reply);
595 			//printf("Sending reply... %ld\n", status);
596 			// debug reply.PrintToStream();
597 
598 			// This request is not gonna be used anymore
599 			//ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected);
600 			ClearWantedEvent(request);
601 			break;
602 		}
603 
604 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY):
605 		{
606 			uint8* statusReply = (uint8*)(event + 1);
607 
608 			// TODO: This reply might match the BDADDR of the outgoing message
609 			// => FindPetition should be expanded....
610 			TRACE_BT("LocalDeviceImpl: pincode reject status %x\n", *statusReply);
611 
612 			reply.AddInt8("status", *statusReply);
613 			status = request->SendReply(&reply);
614 			//printf("Sending reply... %ld\n", status);
615 			// debug reply.PrintToStream();
616 
617 			// This request is not gonna be used anymore
618 			ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected);
619 			break;
620 		}
621 
622 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_STORED_LINK_KEY):
623 		{
624 			struct hci_read_stored_link_key_reply* linkKeyRetrieval
625 				= JumpEventHeader<struct hci_read_stored_link_key_reply,
626 				struct hci_ev_cmd_complete>(event);
627 
628 			TRACE_BT("LocalDeviceImpl: Status %s MaxKeys=%d, KeysRead=%d\n",
629 				BluetoothError(linkKeyRetrieval->status),
630 				linkKeyRetrieval->max_num_keys,
631 				linkKeyRetrieval->num_keys_read);
632 
633 			reply.AddInt8("status", linkKeyRetrieval->status);
634 			status = request->SendReply(&reply);
635 			//printf("Sending reply... %ld\n", status);
636 			// debug reply.PrintToStream();
637 
638 			ClearWantedEvent(request);
639 			break;
640 		}
641 
642 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY):
643 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_REPLY):
644 		{
645 			struct hci_cp_link_key_reply_reply* linkKeyReply
646 				= JumpEventHeader<struct hci_cp_link_key_reply_reply,
647 				struct hci_ev_cmd_complete>(event);
648 
649 			TRACE_BT("LocalDeviceImpl: Status %s addresss=%s\n", BluetoothError(linkKeyReply->status),
650 				bdaddrUtils::ToString(linkKeyReply->bdaddr).String());
651 
652 			ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected);
653 			break;
654 		}
655 
656 		case  PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_SCAN_ENABLE):
657 		{
658 			struct hci_read_scan_enable* scanEnable
659 				= JumpEventHeader<struct hci_read_scan_enable,
660 				struct hci_ev_cmd_complete>(event);
661 
662 			if (scanEnable->status == BT_OK) {
663 				fProperties->AddInt8("scan_enable", scanEnable->enable);
664 
665 				TRACE_BT("LocalDeviceImpl: enable = %x\n", scanEnable->enable);
666 			}
667 
668 			reply.AddInt8("status", scanEnable->status);
669 			reply.AddInt8("scan_enable", scanEnable->enable);
670 			status = request->SendReply(&reply);
671 			printf("Sending reply. scan_enable = %d\n", scanEnable->enable);
672 			// debug reply.PrintToStream();
673 
674 			// This request is not gonna be used anymore
675 			ClearWantedEvent(request);
676 			break;
677 		}
678 
679 		// place here all CC that just replies a uint8 status
680 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET):
681 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE):
682 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV):
683 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT):
684 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT):
685 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE):
686 		case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_LOCAL_NAME):
687 		case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR):
688 		{
689 			reply.AddInt8("status", *(uint8*)(event + 1));
690 
691 			TRACE_BT("LocalDeviceImpl: %s for %s status %x\n", __FUNCTION__,
692 				BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1));
693 
694 			status = request->SendReply(&reply);
695 			printf("%s: Sending reply write...\n", __func__);
696 			if (status < B_OK)
697 				printf("%s: Error sending reply write!\n", __func__);
698 
699 			ClearWantedEvent(request);
700 			break;
701 		}
702 
703 		default:
704 			TRACE_BT("LocalDeviceImpl: Command Complete not handled\n");
705 			break;
706 	}
707 }
708 
709 
710 void
711 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event,
712 	BMessage* request, int32 index)
713 {
714 	int16 opcodeExpected;
715 	BMessage reply;
716 
717 	// Handle command complete information
718 	request->FindInt16("opcodeExpected", index, &opcodeExpected);
719 
720 	if (request->IsSourceWaiting() == false) {
721 		TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n");
722 	}
723 
724 	switch (opcodeExpected) {
725 
726 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY):
727 		{
728 			reply.what = BT_MSG_INQUIRY_STARTED;
729 
730 			TRACE_BT("LocalDeviceImpl: Inquiry status %x\n", event->status);
731 
732 			reply.AddInt8("status", event->status);
733 			request->SendReply(&reply);
734 			//printf("Sending reply... %ld\n", status);
735 			// debug reply.PrintToStream();
736 
737 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
738 				PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY));
739 		}
740 		break;
741 
742 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST):
743 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_CREATE_CONN):
744 		{
745 			if (event->status == BT_OK) {
746 				ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected);
747 			} else {
748 				TRACE_BT("LocalDeviceImpl: Command Status for remote friendly name %x\n",
749 					event->status);
750 
751 				reply.AddInt8("status", event->status);
752 				request->SendReply(&reply);
753 				//printf("Sending reply... %ld\n", status);
754 				// debug reply.PrintToStream();
755 
756 				ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected);
757 			}
758 		}
759 		break;
760 		/*
761 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ):
762 		{
763 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
764 				PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ));
765 		}
766 		break;
767 
768 		case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ):
769 		{
770 			ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
771 				PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ));
772 		}
773 		break;*/
774 
775 		default:
776 			TRACE_BT("LocalDeviceImpl: Command Status not handled\n");
777 		break;
778 	}
779 }
780 
781 
782 void
783 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request)
784 {
785 	BMessage reply(BT_MSG_INQUIRY_DEVICE);
786 
787 	uint8 responses = *numberOfResponses;
788 
789 	// skipping here the number of responses
790 	reply.AddData("info", B_ANY_TYPE, numberOfResponses + 1,
791 		(*numberOfResponses) * sizeof(struct inquiry_info) );
792 
793 	reply.AddInt8("count", *numberOfResponses);
794 
795 	TRACE_BT("LocalDeviceImpl: %s #responses=%d\n",
796 		__FUNCTION__, *numberOfResponses);
797 
798 	struct inquiry_info* info = JumpEventHeader<struct inquiry_info, uint8>
799 		(numberOfResponses);
800 
801 	while (responses > 0) {
802 		TRACE_BT("LocalDeviceImpl: page_rep=%d scan_period=%d, scan=%d clock=%d\n",
803 			info->pscan_rep_mode, info->pscan_period_mode, info->pscan_mode,
804 			info->clock_offset);
805 		responses--;
806 		info++;
807 	}
808 
809 	printf("%s: Sending reply...\n", __func__);
810 	status_t status = request->SendReply(&reply);
811 	if (status < B_OK)
812 		printf("%s: Error sending reply!\n", __func__);
813 }
814 
815 
816 void
817 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request)
818 {
819 	BMessage reply(BT_MSG_INQUIRY_COMPLETED);
820 
821 	reply.AddInt8("status", *status);
822 
823 	printf("%s: Sending reply...\n", __func__);
824 	status_t stat = request->SendReply(&reply);
825 	if (stat < B_OK)
826 		printf("%s: Error sending reply!\n", __func__);
827 
828 	ClearWantedEvent(request);
829 }
830 
831 
832 void
833 LocalDeviceImpl::RemoteNameRequestComplete(
834 	struct hci_ev_remote_name_request_complete_reply* remotename,
835 	BMessage* request)
836 {
837 	BMessage reply;
838 
839 	if (remotename->status == BT_OK) {
840 		reply.AddString("friendlyname", (const char*)remotename->remote_name );
841 	}
842 
843 	reply.AddInt8("status", remotename->status);
844 
845 	TRACE_BT("LocalDeviceImpl: %s for %s with status %s\n",
846 		BluetoothEvent(HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE),
847 		bdaddrUtils::ToString(remotename->bdaddr).String(),
848 		BluetoothError(remotename->status));
849 
850 	status_t status = request->SendReply(&reply);
851 	if (status < B_OK)
852 		printf("%s: Error sending reply to BMessage request: %s!\n",
853 			__func__, strerror(status));
854 
855 	// This request is not gonna be used anymore
856 	ClearWantedEvent(request);
857 }
858 
859 
860 void
861 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event,
862 	BMessage* request)
863 {
864 	size_t size;
865 	void* command;
866 
867 	TRACE_BT("LocalDeviceImpl: Connection Incoming type %x from %s...\n",
868 		event->link_type, bdaddrUtils::ToString(event->bdaddr).String());
869 
870 	// TODO: add a possible request in the queue
871 	if (true) { // Check Preferences if we are to accept this connection
872 
873 		// Keep ourselves as slave
874 		command = buildAcceptConnectionRequest(event->bdaddr, 0x01 , &size);
875 
876 		BMessage* newrequest = new BMessage;
877 		newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
878 		newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
879 			OCF_ACCEPT_CONN_REQ));
880 
881 		newrequest->AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE);
882 		newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
883 		newrequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE);
884 		newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY);
885 		newrequest->AddInt16("eventExpected",
886 			HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE);
887 
888 		#if 0
889 		newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE);
890 		newrequest->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE);
891 		#endif
892 
893 		AddWantedEvent(newrequest);
894 
895 		if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) {
896 			TRACE_BT("LocalDeviceImpl: Command issued error for Accepting connection\n");
897 				// remove the request?
898 		} else {
899 			TRACE_BT("LocalDeviceImpl: Command issued for Accepting connection\n");
900 		}
901 	}
902 }
903 
904 
905 void
906 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event,
907 	BMessage* request)
908 {
909 
910 	if (event->status == BT_OK) {
911 		uint8 cod[3] = {0, 0, 0};
912 
913 		// TODO: Review, this rDevice is leaked
914 		ConnectionIncoming* iConnection = new ConnectionIncoming(
915 			new RemoteDevice(event->bdaddr, cod));
916 		iConnection->Show();
917 
918 		TRACE_BT("LocalDeviceImpl: %s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__,
919 				bdaddrUtils::ToString(event->bdaddr).String(), event->handle,
920 				event->link_type, event->encrypt_mode);
921 
922 	} else {
923 		TRACE_BT("LocalDeviceImpl: %s: failed with error %s\n", __FUNCTION__,
924 			BluetoothError(event->status));
925 	}
926 
927 	// it was expected
928 	if (request != NULL) {
929 		BMessage reply;
930 		reply.AddInt8("status", event->status);
931 
932 		if (event->status == BT_OK)
933 			reply.AddInt16("handle", event->handle);
934 
935 		printf("%s: Sending reply...\n", __func__);
936 		status_t status = request->SendReply(&reply);
937 		if (status < B_OK)
938 			printf("%s: Error sending reply!\n", __func__);
939 		// debug reply.PrintToStream();
940 
941 		// This request is not gonna be used anymore
942 		ClearWantedEvent(request);
943 	}
944 
945 }
946 
947 
948 void
949 LocalDeviceImpl::DisconnectionComplete(
950 	struct hci_ev_disconnection_complete_reply* event, BMessage* request)
951 {
952 	TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, reason=%s status=%x\n", __FUNCTION__, event->handle,
953 		BluetoothError(event->reason), event->status);
954 
955 	if (request != NULL) {
956 		BMessage reply;
957 		reply.AddInt8("status", event->status);
958 
959 		printf("%s: Sending reply...\n", __func__);
960 		status_t status = request->SendReply(&reply);
961 		if (status < B_OK)
962 			printf("%s: Error sending reply!\n", __func__);
963 		// debug reply.PrintToStream();
964 
965 		ClearWantedEvent(request);
966 	}
967 }
968 
969 
970 void
971 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event,
972 	BMessage* request)
973 {
974 	PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID());
975 	iPincode->Show();
976 }
977 
978 
979 void
980 LocalDeviceImpl::RoleChange(hci_ev_role_change* event, BMessage* request)
981 {
982 	TRACE_BT("LocalDeviceImpl: %s: Address %s role=%d status=%d\n", __FUNCTION__,
983 		bdaddrUtils::ToString(event->bdaddr).String(), event->role, event->status);
984 }
985 
986 
987 void
988 LocalDeviceImpl::PageScanRepetitionModeChange(
989 	struct hci_ev_page_scan_rep_mode_change* event, BMessage* request)
990 {
991 	TRACE_BT("LocalDeviceImpl: %s: Address %s type=%d\n",	__FUNCTION__,
992 		bdaddrUtils::ToString(event->bdaddr).String(), event->page_scan_rep_mode);
993 }
994 
995 
996 void
997 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify* event,
998 	BMessage* request)
999 {
1000 	TRACE_BT("LocalDeviceImpl: %s: Address %s, key=%s, type=%d\n", __FUNCTION__,
1001 		bdaddrUtils::ToString(event->bdaddr).String(),
1002 		LinkKeyUtils::ToString(event->link_key).String(), event->key_type);
1003 }
1004 
1005 
1006 void
1007 LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested,
1008 	BMessage* request)
1009 {
1010 	TRACE_BT("LocalDeviceImpl: %s: Address %s\n", __FUNCTION__,
1011 		bdaddrUtils::ToString(keyRequested->bdaddr).String());
1012 
1013 	// TODO:
1014 	// Here we are suposed to check the BDADDR received, look into the server
1015 	// (RemoteDevice Database) if we have any pas link key interchanged with
1016 	// the given address if we have we are to accept it will "Link key Request
1017 	// Reply". As we dont not have such database yet, we will always deny it
1018 	// forcing the remote device to start a pairing.
1019 
1020 	BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)>
1021 		linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY);
1022 
1023 	bdaddrUtils::Copy(linkKeyNegativeReply->bdaddr, keyRequested->bdaddr);
1024 
1025 	if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(),
1026 		linkKeyNegativeReply.Size()) == B_ERROR) {
1027 		TRACE_BT("LocalDeviceImpl: Command issued error for reply %s\n", __FUNCTION__);
1028 	} else {
1029 		TRACE_BT("LocalDeviceImpl: Command issued in reply of  %s\n", __FUNCTION__);
1030 	}
1031 
1032 	if (request != NULL)
1033 		ClearWantedEvent(request, HCI_EVENT_LINK_KEY_REQ);
1034 
1035 }
1036 
1037 
1038 void
1039 LocalDeviceImpl::ReturnLinkKeys(struct hci_ev_return_link_keys* returnedKeys)
1040 {
1041 	TRACE_BT("LocalDeviceImpl: %s: #keys=%d\n",
1042 		__FUNCTION__, returnedKeys->num_keys);
1043 
1044 	uint8 numKeys = returnedKeys->num_keys;
1045 
1046 	struct link_key_info* linkKeys = &returnedKeys->link_keys;
1047 
1048 	while (numKeys > 0) {
1049 
1050 		TRACE_BT("LocalDeviceImpl: Address=%s key=%s\n",
1051 			bdaddrUtils::ToString(linkKeys->bdaddr).String(),
1052 			LinkKeyUtils::ToString(linkKeys->link_key).String());
1053 
1054 		linkKeys++;
1055 	}
1056 }
1057 
1058 
1059 void
1060 LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change* event,
1061 	BMessage* request)
1062 {
1063 	TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, max slots=%d\n", __FUNCTION__,
1064 		event->handle, event->lmp_max_slots);
1065 }
1066 
1067 
1068 void
1069 LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error* event)
1070 {
1071 	TRACE_BT("LocalDeviceImpl: %s: hardware code=%#x\n",	__FUNCTION__, event->hardware_code);
1072 }
1073 
1074 
1075 void
1076 LocalDeviceImpl::NumberOfCompletedPackets(struct hci_ev_num_comp_pkts* event)
1077 {
1078 	TRACE_BT("LocalDeviceImpl: %s: #Handles=%d\n", __FUNCTION__, event->num_hndl);
1079 
1080 	struct handle_and_number* numberPackets
1081 		= JumpEventHeader<handle_and_number, hci_ev_num_comp_pkts>(event);
1082 
1083 	for (uint8 i = 0; i < event->num_hndl; i++) {
1084 
1085 		TRACE_BT("LocalDeviceImpl: %s: Handle=%d #packets=%d\n", __FUNCTION__, numberPackets->handle,
1086 			numberPackets->num_completed);
1087 
1088 			numberPackets++;
1089 	}
1090 }
1091 
1092 
1093 #if 0
1094 #pragma mark - Request Methods -
1095 #endif
1096 
1097 status_t
1098 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request)
1099 {
1100 	ssize_t size;
1101 	void* command = NULL;
1102 
1103 	if (request->FindData("raw command", B_ANY_TYPE, 0,
1104 		(const void **)&command, &size) == B_OK) {
1105 
1106 		// Give the chance of just issuing the command
1107 		int16 eventFound;
1108 		if (request->FindInt16("eventExpected", &eventFound) == B_OK)
1109 			AddWantedEvent(request);
1110 		// LEAK: is command buffer freed within the Message?
1111 		if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size)
1112 			== B_ERROR) {
1113 			// TODO:
1114 			// Reply the request with error!
1115 			// Remove the just added request
1116 			TRACE_BT("LocalDeviceImpl: ## ERROR Command issue, REMOVING!\n");
1117 			ClearWantedEvent(request);
1118 
1119 		} else {
1120 			return B_OK;
1121 		}
1122 	} else {
1123 		TRACE_BT("LocalDeviceImpl: No command specified for simple request\n");
1124 	}
1125 
1126 	return B_ERROR;
1127 }
1128