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.
8 #include "BluetoothServer.h"
10 #include "LocalDeviceImpl.h"
11 #include "CommandManager.h"
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>
20 #include <bluetoothserver_p.h>
21 #include <ConnectionIncoming.h>
22 #include <PincodeWindow.h>
29 #pragma mark - Class methods -
35 LocalDeviceImpl::CreateControllerAccessor(BPath
* path
)
37 HCIDelegate
* delegate
= new(std::nothrow
) HCIControllerAccessor(path
);
41 LocalDeviceImpl
* device
= new(std::nothrow
) LocalDeviceImpl(delegate
);
52 LocalDeviceImpl::CreateTransportAccessor(BPath
* path
)
54 HCIDelegate
* delegate
= new(std::nothrow
) HCITransportAccessor(path
);
58 LocalDeviceImpl
* device
= new(std::nothrow
) LocalDeviceImpl(delegate
);
68 LocalDeviceImpl::LocalDeviceImpl(HCIDelegate
* hd
) : LocalDeviceHandler(hd
)
74 LocalDeviceImpl::~LocalDeviceImpl()
81 LocalDeviceImpl::Unregister()
83 BMessage
* msg
= new BMessage(BT_MSG_REMOVE_DEVICE
);
85 msg
->AddInt32("hci_id", fHCIDelegate
->Id());
87 TRACE_BT("LocalDeviceImpl: Unregistering %" B_PRId32
"\n",
90 be_app_messenger
.SendMessage(msg
);
95 #pragma mark - Event handling methods -
98 template<typename T
, typename Header
>
100 JumpEventHeader(Header
* event
)
102 return (T
*)(event
+ 1);
107 LocalDeviceImpl::HandleUnexpectedEvent(struct hci_event_header
* event
)
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
:
114 JumpEventHeader
<struct hci_ev_hardware_error
>(event
));
117 case HCI_EVENT_CONN_REQUEST
:
119 JumpEventHeader
<struct hci_ev_conn_request
>(event
), NULL
);
122 case HCI_EVENT_NUM_COMP_PKTS
:
123 NumberOfCompletedPackets(
124 JumpEventHeader
<struct hci_ev_num_comp_pkts
>(event
));
127 case HCI_EVENT_DISCONNECTION_COMPLETE
:
128 // should belong to a request? can be sporadic or initiated by us?
129 DisconnectionComplete(
131 <struct hci_ev_disconnection_complete_reply
>(event
),
134 case HCI_EVENT_PIN_CODE_REQ
:
136 JumpEventHeader
<struct hci_ev_pin_code_req
>(event
), NULL
);
139 // TODO: feedback unexpected not handled
146 LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header
* event
,
149 // we are waiting for a reply
150 switch (event
->ecode
) {
151 case HCI_EVENT_INQUIRY_COMPLETE
:
152 InquiryComplete(JumpEventHeader
<uint8
>(event
), request
);
155 case HCI_EVENT_INQUIRY_RESULT
:
156 InquiryResult(JumpEventHeader
<uint8
>(event
), request
);
159 case HCI_EVENT_CONN_COMPLETE
:
161 JumpEventHeader
<struct hci_ev_conn_complete
>(event
), request
);
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
>
171 case HCI_EVENT_AUTH_COMPLETE
:
175 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE
:
176 RemoteNameRequestComplete(
178 <struct hci_ev_remote_name_request_complete_reply
>
182 case HCI_EVENT_ENCRYPT_CHANGE
:
185 case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE
:
188 case HCI_EVENT_MASTER_LINK_KEY_COMPL
:
191 case HCI_EVENT_RMT_FEATURES
:
194 case HCI_EVENT_RMT_VERSION
:
197 case HCI_EVENT_QOS_SETUP_COMPLETE
:
200 case HCI_EVENT_FLUSH_OCCUR
:
203 case HCI_EVENT_ROLE_CHANGE
:
205 JumpEventHeader
<struct hci_ev_role_change
>(event
), request
);
208 case HCI_EVENT_MODE_CHANGE
:
211 case HCI_EVENT_RETURN_LINK_KEYS
:
213 JumpEventHeader
<struct hci_ev_return_link_keys
>(event
));
216 case HCI_EVENT_LINK_KEY_REQ
:
218 JumpEventHeader
<struct hci_ev_link_key_req
>(event
), request
);
221 case HCI_EVENT_LINK_KEY_NOTIFY
:
223 JumpEventHeader
<struct hci_ev_link_key_notify
>(event
), request
);
226 case HCI_EVENT_LOOPBACK_COMMAND
:
229 case HCI_EVENT_DATA_BUFFER_OVERFLOW
:
232 case HCI_EVENT_MAX_SLOT_CHANGE
:
233 MaxSlotChange(JumpEventHeader
<struct hci_ev_max_slot_change
>(event
),
237 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL
:
240 case HCI_EVENT_CON_PKT_TYPE_CHANGED
:
243 case HCI_EVENT_QOS_VIOLATION
:
246 case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE
:
247 PageScanRepetitionModeChange(
248 JumpEventHeader
<struct hci_ev_page_scan_rep_mode_change
>(event
),
252 case HCI_EVENT_FLOW_SPECIFICATION
:
255 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI
:
258 case HCI_EVENT_REMOTE_EXTENDED_FEATURES
:
261 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED
:
264 case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED
:
271 LocalDeviceImpl::HandleEvent(struct hci_event_header
* event
)
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]);
280 BMessage
* request
= NULL
;
281 int32 eventIndexLocation
;
283 // Check if it is a requested one
284 switch (event
->ecode
) {
285 case HCI_EVENT_CMD_COMPLETE
:
287 struct hci_ev_cmd_complete
* commandComplete
288 = JumpEventHeader
<struct hci_ev_cmd_complete
>(event
);
290 TRACE_BT("LocalDeviceImpl: Incoming CommandComplete(%d) for %s\n", commandComplete
->ncmd
,
291 BluetoothCommandOpcode(commandComplete
->opcode
));
293 request
= FindPetition(event
->ecode
, commandComplete
->opcode
,
294 &eventIndexLocation
);
297 CommandComplete(commandComplete
, request
, eventIndexLocation
);
301 case HCI_EVENT_CMD_STATUS
:
303 struct hci_ev_cmd_status
* commandStatus
304 = JumpEventHeader
<struct hci_ev_cmd_status
>(event
);
306 TRACE_BT("LocalDeviceImpl: Incoming CommandStatus(%d)(%s) for %s\n", commandStatus
->ncmd
,
307 BluetoothError(commandStatus
->status
),
308 BluetoothCommandOpcode(commandStatus
->opcode
));
310 request
= FindPetition(event
->ecode
, commandStatus
->opcode
,
311 &eventIndexLocation
);
313 CommandStatus(commandStatus
, request
, eventIndexLocation
);
318 TRACE_BT("LocalDeviceImpl: Incoming %s event\n", BluetoothEvent(event
->ecode
));
320 request
= FindPetition(event
->ecode
);
322 HandleExpectedRequest(event
, request
);
327 if (request
== NULL
) {
328 TRACE_BT("LocalDeviceImpl: Event %s could not be understood or delivered\n",
329 BluetoothEvent(event
->ecode
));
330 HandleUnexpectedEvent(event
);
341 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete
* event
,
342 BMessage
* request
, int32 index
)
344 int16 opcodeExpected
;
348 // Handle command complete information
349 request
->FindInt16("opcodeExpected", index
, &opcodeExpected
);
351 if (request
->IsSourceWaiting() == false) {
352 TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n");
355 switch ((uint16
)opcodeExpected
) {
357 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM
, OCF_READ_LOCAL_VERSION
):
359 struct hci_rp_read_loc_version
* version
360 = JumpEventHeader
<struct hci_rp_read_loc_version
,
361 struct hci_ev_cmd_complete
>(event
);
364 if (version
->status
== BT_OK
) {
366 if (!IsPropertyAvailable("hci_version"))
367 fProperties
->AddInt8("hci_version", version
->hci_version
);
369 if (!IsPropertyAvailable("hci_revision")) {
370 fProperties
->AddInt16("hci_revision",
371 version
->hci_revision
);
374 if (!IsPropertyAvailable("lmp_version"))
375 fProperties
->AddInt8("lmp_version", version
->lmp_version
);
377 if (!IsPropertyAvailable("lmp_subversion")) {
378 fProperties
->AddInt16("lmp_subversion",
379 version
->lmp_subversion
);
382 if (!IsPropertyAvailable("manufacturer")) {
383 fProperties
->AddInt16("manufacturer",
384 version
->manufacturer
);
388 TRACE_BT("LocalDeviceImpl: Reply for Local Version %x\n", version
->status
);
390 reply
.AddInt8("status", version
->status
);
391 status
= request
->SendReply(&reply
);
392 //printf("Sending reply... %ld\n", status);
393 // debug reply.PrintToStream();
395 // This request is not gonna be used anymore
396 ClearWantedEvent(request
);
400 case PACK_OPCODE(OGF_CONTROL_BASEBAND
, OCF_READ_PG_TIMEOUT
):
402 struct hci_rp_read_page_timeout
* pageTimeout
403 = JumpEventHeader
<struct hci_rp_read_page_timeout
,
404 struct hci_ev_cmd_complete
>(event
);
406 if (pageTimeout
->status
== BT_OK
) {
407 fProperties
->AddInt16("page_timeout",
408 pageTimeout
->page_timeout
);
410 TRACE_BT("LocalDeviceImpl: Page Timeout=%x\n", pageTimeout
->page_timeout
);
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();
419 // This request is not gonna be used anymore
420 ClearWantedEvent(request
);
424 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM
, OCF_READ_LOCAL_FEATURES
):
426 struct hci_rp_read_loc_features
* features
427 = JumpEventHeader
<struct hci_rp_read_loc_features
,
428 struct hci_ev_cmd_complete
>(event
);
430 if (features
->status
== BT_OK
) {
432 if (!IsPropertyAvailable("features")) {
433 fProperties
->AddData("features", B_ANY_TYPE
,
434 &features
->features
, 8);
436 uint16 packetType
= HCI_DM1
| HCI_DH1
| HCI_HV1
;
439 = (features
->features
[0] & LMP_RSWITCH
) != 0;
441 = (features
->features
[0] & LMP_ENCRYPT
) != 0;
443 if (features
->features
[0] & LMP_3SLOT
)
444 packetType
|= (HCI_DM3
| HCI_DH3
);
446 if (features
->features
[0] & LMP_5SLOT
)
447 packetType
|= (HCI_DM5
| HCI_DH5
);
449 if (features
->features
[1] & LMP_HV2
)
450 packetType
|= (HCI_HV2
);
452 if (features
->features
[1] & LMP_HV3
)
453 packetType
|= (HCI_HV3
);
455 fProperties
->AddInt16("packet_type", packetType
);
456 fProperties
->AddBool("role_switch_capable", roleSwitch
);
457 fProperties
->AddBool("encrypt_capable", encryptCapable
);
459 TRACE_BT("LocalDeviceImpl: Packet type %x role switch %d encrypt %d\n",
460 packetType
, roleSwitch
, encryptCapable
);
465 TRACE_BT("LocalDeviceImpl: Reply for Local Features %x\n", features
->status
);
467 reply
.AddInt8("status", features
->status
);
468 status
= request
->SendReply(&reply
);
469 //printf("Sending reply... %ld\n", status);
470 // debug reply.PrintToStream();
472 // This request is not gonna be used anymore
473 ClearWantedEvent(request
);
477 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM
, OCF_READ_BUFFER_SIZE
):
479 struct hci_rp_read_buffer_size
* buffer
480 = JumpEventHeader
<struct hci_rp_read_buffer_size
,
481 struct hci_ev_cmd_complete
>(event
);
483 if (buffer
->status
== BT_OK
) {
485 if (!IsPropertyAvailable("acl_mtu"))
486 fProperties
->AddInt16("acl_mtu", buffer
->acl_mtu
);
488 if (!IsPropertyAvailable("sco_mtu"))
489 fProperties
->AddInt8("sco_mtu", buffer
->sco_mtu
);
491 if (!IsPropertyAvailable("acl_max_pkt"))
492 fProperties
->AddInt16("acl_max_pkt", buffer
->acl_max_pkt
);
494 if (!IsPropertyAvailable("sco_max_pkt"))
495 fProperties
->AddInt16("sco_max_pkt", buffer
->sco_max_pkt
);
499 TRACE_BT("LocalDeviceImpl: Reply for Read Buffer Size %x\n", buffer
->status
);
502 reply
.AddInt8("status", buffer
->status
);
503 status
= request
->SendReply(&reply
);
504 //printf("Sending reply... %ld\n", status);
505 // debug reply.PrintToStream();
507 // This request is not gonna be used anymore
508 ClearWantedEvent(request
);
512 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM
, OCF_READ_BD_ADDR
):
514 struct hci_rp_read_bd_addr
* readbdaddr
515 = JumpEventHeader
<struct hci_rp_read_bd_addr
,
516 struct hci_ev_cmd_complete
>(event
);
518 if (readbdaddr
->status
== BT_OK
) {
519 reply
.AddData("bdaddr", B_ANY_TYPE
, &readbdaddr
->bdaddr
,
523 TRACE_BT("LocalDeviceImpl: Read bdaddr status = %x\n", readbdaddr
->status
);
525 reply
.AddInt8("status", readbdaddr
->status
);
526 status
= request
->SendReply(&reply
);
527 //printf("Sending reply... %ld\n", status);
528 // debug reply.PrintToStream();
530 // This request is not gonna be used anymore
531 ClearWantedEvent(request
);
536 case PACK_OPCODE(OGF_CONTROL_BASEBAND
, OCF_READ_CLASS_OF_DEV
):
538 struct hci_read_dev_class_reply
* classDev
539 = JumpEventHeader
<struct hci_read_dev_class_reply
,
540 struct hci_ev_cmd_complete
>(event
);
542 if (classDev
->status
== BT_OK
) {
543 reply
.AddData("devclass", B_ANY_TYPE
, &classDev
->dev_class
,
544 sizeof(classDev
->dev_class
));
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]);
552 reply
.AddInt8("status", classDev
->status
);
553 status
= request
->SendReply(&reply
);
554 //printf("Sending reply... %ld\n", status);
555 // debug reply.PrintToStream();
557 // This request is not gonna be used anymore
558 ClearWantedEvent(request
);
562 case PACK_OPCODE(OGF_CONTROL_BASEBAND
, OCF_READ_LOCAL_NAME
):
564 struct hci_rp_read_local_name
* readLocalName
565 = JumpEventHeader
<struct hci_rp_read_local_name
,
566 struct hci_ev_cmd_complete
>(event
);
569 if (readLocalName
->status
== BT_OK
) {
570 reply
.AddString("friendlyname",
571 (const char*)readLocalName
->local_name
);
574 TRACE_BT("LocalDeviceImpl: Friendly name status %x\n", readLocalName
->status
);
576 reply
.AddInt8("status", readLocalName
->status
);
577 status
= request
->SendReply(&reply
);
578 //printf("Sending reply... %ld\n", status);
579 // debug reply.PrintToStream();
581 // This request is not gonna be used anymore
582 ClearWantedEvent(request
);
586 case PACK_OPCODE(OGF_LINK_CONTROL
, OCF_PIN_CODE_REPLY
):
588 uint8
* statusReply
= (uint8
*)(event
+ 1);
590 // TODO: This reply has to match the BDADDR of the outgoing message
591 TRACE_BT("LocalDeviceImpl: pincode accept status %x\n", *statusReply
);
593 reply
.AddInt8("status", *statusReply
);
594 status
= request
->SendReply(&reply
);
595 //printf("Sending reply... %ld\n", status);
596 // debug reply.PrintToStream();
598 // This request is not gonna be used anymore
599 //ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected);
600 ClearWantedEvent(request
);
604 case PACK_OPCODE(OGF_LINK_CONTROL
, OCF_PIN_CODE_NEG_REPLY
):
606 uint8
* statusReply
= (uint8
*)(event
+ 1);
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
);
612 reply
.AddInt8("status", *statusReply
);
613 status
= request
->SendReply(&reply
);
614 //printf("Sending reply... %ld\n", status);
615 // debug reply.PrintToStream();
617 // This request is not gonna be used anymore
618 ClearWantedEvent(request
, HCI_EVENT_CMD_COMPLETE
, opcodeExpected
);
622 case PACK_OPCODE(OGF_CONTROL_BASEBAND
, OCF_READ_STORED_LINK_KEY
):
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
);
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
);
633 reply
.AddInt8("status", linkKeyRetrieval
->status
);
634 status
= request
->SendReply(&reply
);
635 //printf("Sending reply... %ld\n", status);
636 // debug reply.PrintToStream();
638 ClearWantedEvent(request
);
642 case PACK_OPCODE(OGF_LINK_CONTROL
, OCF_LINK_KEY_NEG_REPLY
):
643 case PACK_OPCODE(OGF_LINK_CONTROL
, OCF_LINK_KEY_REPLY
):
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
);
649 TRACE_BT("LocalDeviceImpl: Status %s addresss=%s\n", BluetoothError(linkKeyReply
->status
),
650 bdaddrUtils::ToString(linkKeyReply
->bdaddr
).String());
652 ClearWantedEvent(request
, HCI_EVENT_CMD_COMPLETE
, opcodeExpected
);
656 case PACK_OPCODE(OGF_CONTROL_BASEBAND
, OCF_READ_SCAN_ENABLE
):
658 struct hci_read_scan_enable
* scanEnable
659 = JumpEventHeader
<struct hci_read_scan_enable
,
660 struct hci_ev_cmd_complete
>(event
);
662 if (scanEnable
->status
== BT_OK
) {
663 fProperties
->AddInt8("scan_enable", scanEnable
->enable
);
665 TRACE_BT("LocalDeviceImpl: enable = %x\n", scanEnable
->enable
);
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();
674 // This request is not gonna be used anymore
675 ClearWantedEvent(request
);
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
):
689 reply
.AddInt8("status", *(uint8
*)(event
+ 1));
691 TRACE_BT("LocalDeviceImpl: %s for %s status %x\n", __FUNCTION__
,
692 BluetoothCommandOpcode(opcodeExpected
), *(uint8
*)(event
+ 1));
694 status
= request
->SendReply(&reply
);
695 printf("%s: Sending reply write...\n", __func__
);
697 printf("%s: Error sending reply write!\n", __func__
);
699 ClearWantedEvent(request
);
704 TRACE_BT("LocalDeviceImpl: Command Complete not handled\n");
712 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status
* event
,
713 BMessage
* request
, int32 index
)
716 int16 opcodeExpected
;
720 // Handle command complete information
721 request
->FindInt16("opcodeExpected", index
, &opcodeExpected
);
723 if (request
->IsSourceWaiting() == false) {
724 TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n");
727 switch (opcodeExpected
) {
729 case PACK_OPCODE(OGF_LINK_CONTROL
, OCF_INQUIRY
):
731 reply
.what
= BT_MSG_INQUIRY_STARTED
;
733 TRACE_BT("LocalDeviceImpl: Inquiry status %x\n", event
->status
);
735 reply
.AddInt8("status", event
->status
);
736 status
= request
->SendReply(&reply
);
737 //printf("Sending reply... %ld\n", status);
738 // debug reply.PrintToStream();
740 ClearWantedEvent(request
, HCI_EVENT_CMD_STATUS
,
741 PACK_OPCODE(OGF_LINK_CONTROL
, OCF_INQUIRY
));
745 case PACK_OPCODE(OGF_LINK_CONTROL
, OCF_REMOTE_NAME_REQUEST
):
746 case PACK_OPCODE(OGF_LINK_CONTROL
, OCF_CREATE_CONN
):
748 if (event
->status
== BT_OK
) {
749 ClearWantedEvent(request
, HCI_EVENT_CMD_STATUS
, opcodeExpected
);
751 TRACE_BT("LocalDeviceImpl: Command Status for remote friendly name %x\n",
754 reply
.AddInt8("status", event
->status
);
755 status
= request
->SendReply(&reply
);
756 //printf("Sending reply... %ld\n", status);
757 // debug reply.PrintToStream();
759 ClearWantedEvent(request
, HCI_EVENT_CMD_STATUS
, opcodeExpected
);
764 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ):
766 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
767 PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ));
771 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ):
773 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
774 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ));
779 TRACE_BT("LocalDeviceImpl: Command Status not handled\n");
787 LocalDeviceImpl::InquiryResult(uint8
* numberOfResponses
, BMessage
* request
)
789 BMessage
reply(BT_MSG_INQUIRY_DEVICE
);
791 uint8 responses
= *numberOfResponses
;
793 // skipping here the number of responses
794 reply
.AddData("info", B_ANY_TYPE
, numberOfResponses
+ 1,
795 (*numberOfResponses
) * sizeof(struct inquiry_info
) );
797 reply
.AddInt8("count", *numberOfResponses
);
799 TRACE_BT("LocalDeviceImpl: %s #responses=%d\n",
800 __FUNCTION__
, *numberOfResponses
);
802 struct inquiry_info
* info
= JumpEventHeader
<struct inquiry_info
, uint8
>
805 while (responses
> 0) {
806 TRACE_BT("LocalDeviceImpl: page_rep=%d scan_period=%d, scan=%d clock=%d\n",
807 info
->pscan_rep_mode
, info
->pscan_period_mode
, info
->pscan_mode
,
813 printf("%s: Sending reply...\n", __func__
);
814 status_t status
= request
->SendReply(&reply
);
816 printf("%s: Error sending reply!\n", __func__
);
821 LocalDeviceImpl::InquiryComplete(uint8
* status
, BMessage
* request
)
823 BMessage
reply(BT_MSG_INQUIRY_COMPLETED
);
825 reply
.AddInt8("status", *status
);
827 printf("%s: Sending reply...\n", __func__
);
828 status_t stat
= request
->SendReply(&reply
);
830 printf("%s: Error sending reply!\n", __func__
);
832 ClearWantedEvent(request
);
837 LocalDeviceImpl::RemoteNameRequestComplete(
838 struct hci_ev_remote_name_request_complete_reply
* remotename
,
843 if (remotename
->status
== BT_OK
) {
844 reply
.AddString("friendlyname", (const char*)remotename
->remote_name
);
847 reply
.AddInt8("status", remotename
->status
);
849 TRACE_BT("LocalDeviceImpl: %s for %s with status %s\n",
850 BluetoothEvent(HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE
),
851 bdaddrUtils::ToString(remotename
->bdaddr
).String(),
852 BluetoothError(remotename
->status
));
854 status_t status
= request
->SendReply(&reply
);
856 printf("%s: Error sending reply to BMessage request: %s!\n",
857 __func__
, strerror(status
));
859 // This request is not gonna be used anymore
860 ClearWantedEvent(request
);
865 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request
* event
,
871 TRACE_BT("LocalDeviceImpl: Connection Incoming type %x from %s...\n",
872 event
->link_type
, bdaddrUtils::ToString(event
->bdaddr
).String());
874 // TODO: add a possible request in the queue
875 if (true) { // Check Preferences if we are to accept this connection
877 // Keep ourselves as slave
878 command
= buildAcceptConnectionRequest(event
->bdaddr
, 0x01 , &size
);
880 BMessage
* newrequest
= new BMessage
;
881 newrequest
->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS
);
882 newrequest
->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL
,
883 OCF_ACCEPT_CONN_REQ
));
885 newrequest
->AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE
);
886 newrequest
->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ
);
887 newrequest
->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE
);
888 newrequest
->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY
);
889 newrequest
->AddInt16("eventExpected",
890 HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE
);
893 newrequest
->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE
);
894 newrequest
->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE
);
897 AddWantedEvent(newrequest
);
899 if ((fHCIDelegate
)->IssueCommand(command
, size
) == B_ERROR
) {
900 TRACE_BT("LocalDeviceImpl: Command issued error for Accepting connection\n");
901 // remove the request?
903 TRACE_BT("LocalDeviceImpl: Command issued for Accepting connection\n");
910 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete
* event
,
914 if (event
->status
== BT_OK
) {
915 uint8 cod
[3] = {0, 0, 0};
917 // TODO: Review, this rDevice is leaked
918 ConnectionIncoming
* iConnection
= new ConnectionIncoming(
919 new RemoteDevice(event
->bdaddr
, cod
));
922 TRACE_BT("LocalDeviceImpl: %s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__
,
923 bdaddrUtils::ToString(event
->bdaddr
).String(), event
->handle
,
924 event
->link_type
, event
->encrypt_mode
);
927 TRACE_BT("LocalDeviceImpl: %s: failed with error %s\n", __FUNCTION__
,
928 BluetoothError(event
->status
));
932 if (request
!= NULL
) {
934 reply
.AddInt8("status", event
->status
);
936 if (event
->status
== BT_OK
)
937 reply
.AddInt16("handle", event
->handle
);
939 printf("%s: Sending reply...\n", __func__
);
940 status_t status
= request
->SendReply(&reply
);
942 printf("%s: Error sending reply!\n", __func__
);
943 // debug reply.PrintToStream();
945 // This request is not gonna be used anymore
946 ClearWantedEvent(request
);
953 LocalDeviceImpl::DisconnectionComplete(
954 struct hci_ev_disconnection_complete_reply
* event
, BMessage
* request
)
956 TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, reason=%s status=%x\n", __FUNCTION__
, event
->handle
,
957 BluetoothError(event
->reason
), event
->status
);
959 if (request
!= NULL
) {
961 reply
.AddInt8("status", event
->status
);
963 printf("%s: Sending reply...\n", __func__
);
964 status_t status
= request
->SendReply(&reply
);
966 printf("%s: Error sending reply!\n", __func__
);
967 // debug reply.PrintToStream();
969 ClearWantedEvent(request
);
975 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req
* event
,
978 PincodeWindow
* iPincode
= new PincodeWindow(event
->bdaddr
, GetID());
984 LocalDeviceImpl::RoleChange(hci_ev_role_change
* event
, BMessage
* request
)
986 TRACE_BT("LocalDeviceImpl: %s: Address %s role=%d status=%d\n", __FUNCTION__
,
987 bdaddrUtils::ToString(event
->bdaddr
).String(), event
->role
, event
->status
);
992 LocalDeviceImpl::PageScanRepetitionModeChange(
993 struct hci_ev_page_scan_rep_mode_change
* event
, BMessage
* request
)
995 TRACE_BT("LocalDeviceImpl: %s: Address %s type=%d\n", __FUNCTION__
,
996 bdaddrUtils::ToString(event
->bdaddr
).String(), event
->page_scan_rep_mode
);
1001 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify
* event
,
1004 TRACE_BT("LocalDeviceImpl: %s: Address %s, key=%s, type=%d\n", __FUNCTION__
,
1005 bdaddrUtils::ToString(event
->bdaddr
).String(),
1006 LinkKeyUtils::ToString(event
->link_key
).String(), event
->key_type
);
1011 LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req
* keyRequested
,
1014 TRACE_BT("LocalDeviceImpl: %s: Address %s\n", __FUNCTION__
,
1015 bdaddrUtils::ToString(keyRequested
->bdaddr
).String());
1018 // Here we are suposed to check the BDADDR received, look into the server
1019 // (RemoteDevice Database) if we have any pas link key interchanged with
1020 // the given address if we have we are to accept it will "Link key Request
1021 // Reply". As we dont not have such database yet, we will always deny it
1022 // forcing the remote device to start a pairing.
1024 BluetoothCommand
<typed_command(hci_cp_link_key_neg_reply
)>
1025 linkKeyNegativeReply(OGF_LINK_CONTROL
, OCF_LINK_KEY_NEG_REPLY
);
1027 bdaddrUtils::Copy(linkKeyNegativeReply
->bdaddr
, keyRequested
->bdaddr
);
1029 if ((fHCIDelegate
)->IssueCommand(linkKeyNegativeReply
.Data(),
1030 linkKeyNegativeReply
.Size()) == B_ERROR
) {
1031 TRACE_BT("LocalDeviceImpl: Command issued error for reply %s\n", __FUNCTION__
);
1033 TRACE_BT("LocalDeviceImpl: Command issued in reply of %s\n", __FUNCTION__
);
1036 if (request
!= NULL
)
1037 ClearWantedEvent(request
, HCI_EVENT_LINK_KEY_REQ
);
1043 LocalDeviceImpl::ReturnLinkKeys(struct hci_ev_return_link_keys
* returnedKeys
)
1045 TRACE_BT("LocalDeviceImpl: %s: #keys=%d\n",
1046 __FUNCTION__
, returnedKeys
->num_keys
);
1048 uint8 numKeys
= returnedKeys
->num_keys
;
1050 struct link_key_info
* linkKeys
= &returnedKeys
->link_keys
;
1052 while (numKeys
> 0) {
1054 TRACE_BT("LocalDeviceImpl: Address=%s key=%s\n",
1055 bdaddrUtils::ToString(linkKeys
->bdaddr
).String(),
1056 LinkKeyUtils::ToString(linkKeys
->link_key
).String());
1064 LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change
* event
,
1067 TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, max slots=%d\n", __FUNCTION__
,
1068 event
->handle
, event
->lmp_max_slots
);
1073 LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error
* event
)
1075 TRACE_BT("LocalDeviceImpl: %s: hardware code=%#x\n", __FUNCTION__
, event
->hardware_code
);
1080 LocalDeviceImpl::NumberOfCompletedPackets(struct hci_ev_num_comp_pkts
* event
)
1082 TRACE_BT("LocalDeviceImpl: %s: #Handles=%d\n", __FUNCTION__
, event
->num_hndl
);
1084 struct handle_and_number
* numberPackets
1085 = JumpEventHeader
<handle_and_number
, hci_ev_num_comp_pkts
>(event
);
1087 for (uint8 i
= 0; i
< event
->num_hndl
; i
++) {
1089 TRACE_BT("LocalDeviceImpl: %s: Handle=%d #packets=%d\n", __FUNCTION__
, numberPackets
->handle
,
1090 numberPackets
->num_completed
);
1098 #pragma mark - Request Methods -
1102 LocalDeviceImpl::ProcessSimpleRequest(BMessage
* request
)
1105 void* command
= NULL
;
1107 if (request
->FindData("raw command", B_ANY_TYPE
, 0,
1108 (const void **)&command
, &size
) == B_OK
) {
1110 // Give the chance of just issuing the command
1112 if (request
->FindInt16("eventExpected", &eventFound
) == B_OK
)
1113 AddWantedEvent(request
);
1114 // LEAK: is command buffer freed within the Message?
1115 if (((HCITransportAccessor
*)fHCIDelegate
)->IssueCommand(command
, size
)
1118 // Reply the request with error!
1119 // Remove the just added request
1120 TRACE_BT("LocalDeviceImpl: ## ERROR Command issue, REMOVING!\n");
1121 ClearWantedEvent(request
);
1127 TRACE_BT("LocalDeviceImpl: No command specified for simple request\n");