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
34LocalDeviceImpl*
35LocalDeviceImpl::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
51LocalDeviceImpl*
52LocalDeviceImpl::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
68LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd)
69{
70
71}
72
73
74LocalDeviceImpl::~LocalDeviceImpl()
75{
76
77}
78
79
80void
81LocalDeviceImpl::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
98template<typename T, typename Header>
99inline T*
100JumpEventHeader(Header* event)
101{
102	return (T*)(event + 1);
103}
104
105
106void
107LocalDeviceImpl::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
145void
146LocalDeviceImpl::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
270void
271LocalDeviceImpl::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
340void
341LocalDeviceImpl::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
710void
711LocalDeviceImpl::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
782void
783LocalDeviceImpl::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
816void
817LocalDeviceImpl::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
832void
833LocalDeviceImpl::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
860void
861LocalDeviceImpl::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
905void
906LocalDeviceImpl::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
948void
949LocalDeviceImpl::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
970void
971LocalDeviceImpl::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
979void
980LocalDeviceImpl::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
987void
988LocalDeviceImpl::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
996void
997LocalDeviceImpl::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
1006void
1007LocalDeviceImpl::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
1038void
1039LocalDeviceImpl::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
1059void
1060LocalDeviceImpl::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
1068void
1069LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error* event)
1070{
1071	TRACE_BT("LocalDeviceImpl: %s: hardware code=%#x\n",	__FUNCTION__, event->hardware_code);
1072}
1073
1074
1075void
1076LocalDeviceImpl::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
1097status_t
1098LocalDeviceImpl::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