From 040fb3eaaca3d80c40a301d6ba8c2b1efb9a6190 Mon Sep 17 00:00:00 2001 From: Oliver Ruiz Dorantes Date: Sat, 24 Apr 2010 11:54:38 +0000 Subject: [PATCH] - Refactor the handling of Expected and unexpected events. - Handle all events invovled in the authentication - LinkKey requests -> reply always negative due the lack a a local linkey database - LinkKey Notification - Handle Completed number of packets for future control flow - Allow clients to issue a command without having to expect an event - Fix: LocalDevice Handler was stopping the search once the opcode expected did not match - Cleanup debug window git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36446 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/bluetooth/BluetoothServer.cpp | 19 +- src/servers/bluetooth/LocalDeviceHandler.cpp | 65 +++-- src/servers/bluetooth/LocalDeviceImpl.cpp | 291 +++++++++++++++---- src/servers/bluetooth/LocalDeviceImpl.h | 25 +- 4 files changed, 303 insertions(+), 97 deletions(-) diff --git a/src/servers/bluetooth/BluetoothServer.cpp b/src/servers/bluetooth/BluetoothServer.cpp index 30d60c26d0..0e2e10b3c2 100644 --- a/src/servers/bluetooth/BluetoothServer.cpp +++ b/src/servers/bluetooth/BluetoothServer.cpp @@ -42,7 +42,7 @@ DispatchEvent(struct hci_event_header* header, int32 code, size_t size) } // fetch the LocalDevice who belongs this event - LocalDeviceImpl* lDeviceImplementation = ((BluetoothServer*)be_app)-> + LocalDeviceImpl* lDeviceImplementation = ((BluetoothServer*)be_app)-> LocateLocalDeviceImpl(GET_PORTCODE_HID(code)); if (lDeviceImplementation == NULL) { @@ -436,6 +436,8 @@ BluetoothServer::HandleGetProperty(BMessage* message, BMessage* reply) // Check if the property has been already retrieved if (lDeviceImpl->IsPropertyAvailable(propertyRequested)) { + + // 1 bytes requests if (strcmp(propertyRequested, "hci_version") == 0 || strcmp(propertyRequested, "lmp_version") == 0 || strcmp(propertyRequested, "sco_mtu") == 0) { @@ -444,17 +446,30 @@ BluetoothServer::HandleGetProperty(BMessage* message, BMessage* reply) FindInt8(propertyRequested); reply->AddInt32("result", result); + // 2 bytes requests } else if (strcmp(propertyRequested, "hci_revision") == 0 || strcmp(propertyRequested, "lmp_subversion") == 0 || strcmp(propertyRequested, "manufacturer") == 0 || strcmp(propertyRequested, "acl_mtu") == 0 || strcmp(propertyRequested, "acl_max_pkt") == 0 - || strcmp(propertyRequested, "sco_max_pkt") == 0 ) { + || strcmp(propertyRequested, "sco_max_pkt") == 0 + || strcmp(propertyRequested, "packet_type") == 0 ) { uint16 result = lDeviceImpl->GetPropertiesMessage()-> FindInt16(propertyRequested); reply->AddInt32("result", result); + // 1 bit requests + } else if (strcmp(propertyRequested, "role_switch_capable") == 0 + || strcmp(propertyRequested, "encrypt_capable") == 0) { + + bool result = lDeviceImpl->GetPropertiesMessage()-> + FindBool(propertyRequested); + + reply->AddInt32("result", result); + + + } else { Output::Instance()->Postf(BLACKBOARD_LD(lDeviceImpl->GetID()), "Property %s could not be satisfied\n", propertyRequested); diff --git a/src/servers/bluetooth/LocalDeviceHandler.cpp b/src/servers/bluetooth/LocalDeviceHandler.cpp index 2ec2923488..0d3d0d9dc0 100644 --- a/src/servers/bluetooth/LocalDeviceHandler.cpp +++ b/src/servers/bluetooth/LocalDeviceHandler.cpp @@ -10,32 +10,32 @@ LocalDeviceHandler::LocalDeviceHandler(HCIDelegate* hd) { fHCIDelegate = hd; - fProperties = new BMessage(); + fProperties = new BMessage(); } -LocalDeviceHandler::~LocalDeviceHandler() +LocalDeviceHandler::~LocalDeviceHandler() { delete fHCIDelegate; - delete fProperties; + delete fProperties; } hci_id LocalDeviceHandler::GetID() { - return fHCIDelegate->Id(); + return fHCIDelegate->Id(); } status_t LocalDeviceHandler::Launch(void) { - return fHCIDelegate->Launch(); + return fHCIDelegate->Launch(); } -bool +bool LocalDeviceHandler::Available() { @@ -54,33 +54,33 @@ bool LocalDeviceHandler::IsPropertyAvailable(const char* property) { type_code typeFound; - int32 countFound; + int32 countFound; return (fProperties->GetInfo(property, &typeFound, &countFound) == B_OK ); } void -LocalDeviceHandler::AddWantedEvent(BMessage* msg) +LocalDeviceHandler::AddWantedEvent(BMessage* msg) { - fEventsWanted.Lock(); - // TODO: review why it is needed to replicate the msg - printf("Adding request... %p\n", msg); - fEventsWanted.AddMessage(msg); - fEventsWanted.Unlock(); + fEventsWanted.Lock(); + // TODO: review why it is needed to replicate the msg + printf("Adding request... %p\n", msg); + fEventsWanted.AddMessage(msg); + fEventsWanted.Unlock(); } -void +void LocalDeviceHandler::ClearWantedEvent(BMessage* msg) { - fEventsWanted.Lock(); - fEventsWanted.RemoveMessage(msg); - fEventsWanted.Unlock(); + fEventsWanted.Lock(); + fEventsWanted.RemoveMessage(msg); + fEventsWanted.Unlock(); } -void +void LocalDeviceHandler::ClearWantedEvent(BMessage* msg, uint16 event, uint16 opcode) { // Remove the whole petition from queue @@ -90,10 +90,10 @@ LocalDeviceHandler::ClearWantedEvent(BMessage* msg, uint16 event, uint16 opcode) int16 opcodeFound; int32 eventIndex = 0; - // for each Event + // for each Event while (msg->FindInt16("eventExpected", eventIndex, &eventFound) == B_OK) { - printf("%s:Event expected@%ld...\n", __FUNCTION__, eventIndex); + printf("%s:Event expected %d@%ld...\n", __FUNCTION__, event, eventIndex); if (eventFound == event) { @@ -102,12 +102,12 @@ LocalDeviceHandler::ClearWantedEvent(BMessage* msg, uint16 event, uint16 opcode) if (opcode != 0) { // The opcode matches - if ((msg->FindInt16("opcodeExpected", eventIndex, &opcodeFound) == B_OK) + if ((msg->FindInt16("opcodeExpected", eventIndex, &opcodeFound) == B_OK) && ((uint16)opcodeFound == opcode)) { // this should remove only the entry printf("Removed event %#x and opcode %d from request %p\n", - event, opcode, msg); + event, opcode, msg); (void)msg->RemoveData("eventExpected", eventIndex); (void)msg->RemoveData("opcodeExpected", eventIndex); goto finish; @@ -142,39 +142,40 @@ LocalDeviceHandler::FindPetition(uint16 event, uint16 opcode, int32* indexFound) // for each Petition for (int32 index = 0 ; index < fEventsWanted.CountMessages() ; index++) { BMessage* msg = fEventsWanted.FindMessage(index); - printf("%s:Petition %ld ... of %ld msg #%p\n", __FUNCTION__, index, + printf("%s:Petition %ld ... of %ld msg #%p\n", __FUNCTION__, index, fEventsWanted.CountMessages(), msg); - //msg->PrintToStream(); + msg->PrintToStream(); eventIndex = 0; // for each Event while (msg->FindInt16("eventExpected", eventIndex, &eventFound) == B_OK ) { if (eventFound == event) { - - printf("%s:Event found@%ld...", __FUNCTION__, eventIndex); - // there is an opcode specified.. - if (msg->FindInt16("opcodeExpected", eventIndex, &opcodeFound) + + printf("%s:Event %d found@%ld...", __FUNCTION__, event, eventIndex); + // there is an opcode specified.. + if (msg->FindInt16("opcodeExpected", eventIndex, &opcodeFound) == B_OK) { // ensure the opcode if ((uint16)opcodeFound != opcode) { printf("%s:opcode does not match %d\n", __FUNCTION__, opcode); - break; + eventIndex++; + continue; } printf("Opcode matches %d\n", opcode); } else { printf("No opcode specified\n"); } - + fEventsWanted.Unlock(); if (indexFound != NULL) *indexFound = eventIndex; return msg; - } + } eventIndex++; } } - printf("%s:Nothing found\n", __FUNCTION__); + printf("%s:Event %d not found\n", __FUNCTION__, event); fEventsWanted.Unlock(); return NULL; diff --git a/src/servers/bluetooth/LocalDeviceImpl.cpp b/src/servers/bluetooth/LocalDeviceImpl.cpp index 53f8fe1243..c9ee0bff81 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.cpp +++ b/src/servers/bluetooth/LocalDeviceImpl.cpp @@ -119,22 +119,31 @@ LocalDeviceImpl::HandleUnexpectedEvent(struct hci_event_header* event) JumpEventHeader(event), NULL); break; - case HCI_EVENT_CONN_COMPLETE: - // should belong to a request? can be sporadic or initiated by us - ConnectionComplete( - JumpEventHeader(event), NULL); + case HCI_EVENT_NUM_COMP_PKTS: + NumberOfCompletedPackets( + JumpEventHeader(event)); break; + case HCI_EVENT_DISCONNECTION_COMPLETE: + // should belong to a request? can be sporadic or initiated by us¿?... + DisconnectionComplete( + JumpEventHeader(event), + NULL); + break; case HCI_EVENT_PIN_CODE_REQ: PinCodeRequest( JumpEventHeader(event), NULL); break; + default: + // TODO: feedback unexpected not handled + break; } } void -LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, BMessage* request) +LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, + BMessage* request) { // we are waiting for a reply switch (event->ecode) { @@ -146,6 +155,11 @@ LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, BMessage* InquiryResult(JumpEventHeader(event), request); break; + case HCI_EVENT_CONN_COMPLETE: + ConnectionComplete( + JumpEventHeader(event), request); + break; + case HCI_EVENT_DISCONNECTION_COMPLETE: // should belong to a request? can be sporadic or initiated by us¿?... DisconnectionComplete( @@ -188,16 +202,16 @@ LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, BMessage* RoleChange(JumpEventHeader(event), request); break; - case HCI_EVENT_NUM_COMP_PKTS: - break; - case HCI_EVENT_MODE_CHANGE: break; case HCI_EVENT_RETURN_LINK_KEYS: + ReturnLinkKeys(JumpEventHeader(event)); break; case HCI_EVENT_LINK_KEY_REQ: + LinkKeyRequested( + JumpEventHeader(event), request); break; case HCI_EVENT_LINK_KEY_NOTIFY: @@ -270,7 +284,7 @@ LocalDeviceImpl::HandleEvent(struct hci_event_header* event) = JumpEventHeader(event); Output::Instance()->Postf(BLACKBOARD_LD(GetID()), - "Incomming CommandComplete for %s\n", + "Incomming CommandComplete(%d) for %s\n", commandComplete->ncmd, BluetoothCommandOpcode(commandComplete->opcode)); request = FindPetition(event->ecode, commandComplete->opcode, @@ -287,7 +301,8 @@ LocalDeviceImpl::HandleEvent(struct hci_event_header* event) = JumpEventHeader(event); Output::Instance()->Postf(BLACKBOARD_LD(GetID()), - "Incomming CommandStatus for %s\n", + "Incomming CommandStatus(%d)(%s) for %s\n", commandStatus->ncmd, + BluetoothError(commandStatus->status), BluetoothCommandOpcode(commandStatus->opcode)); request = FindPetition(event->ecode, commandStatus->opcode, @@ -308,13 +323,12 @@ LocalDeviceImpl::HandleEvent(struct hci_event_header* event) break; } - if (request == NULL) + if (request == NULL) { Output::Instance()->Postf(BLACKBOARD_LD(GetID()), "Event %s could not be understood or delivered\n", BluetoothEvent(event->ecode)); - - HandleUnexpectedEvent(event); - + HandleUnexpectedEvent(event); + } } @@ -337,9 +351,6 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, if (request->IsSourceWaiting() == false) Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); - Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) for %s\n", - __FUNCTION__, event->ncmd, BluetoothCommandOpcode(opcodeExpected)); - switch ((uint16)opcodeExpected) { case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION): @@ -368,7 +379,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, } - Output::Instance()->Postf(BLACKBOARD_KIT, + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), "Reply for Local Version %x\n", version->status); reply.AddInt8("status", version->status); @@ -380,6 +391,30 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, break; } + case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_PG_TIMEOUT): + { + struct hci_rp_read_page_timeout* pageTimeout + = JumpEventHeader(event); + + if (pageTimeout->status == BT_OK) { + + fProperties->AddInt16("page_timeout", pageTimeout->page_timeout); + + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), "Page Timeout=%x\n", + pageTimeout->page_timeout); + } + + reply.AddInt8("status", pageTimeout->status); + reply.AddInt32("result", pageTimeout->page_timeout); + printf("Sending reply ... %ld\n", request->SendReply(&reply)); + reply.PrintToStream(); + + // This request is not gonna be used anymore + ClearWantedEvent(request); + break; + } + case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_FEATURES): { struct hci_rp_read_loc_features* features @@ -512,8 +547,8 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, // This request is not gonna be used anymore ClearWantedEvent(request); + break; } - break; case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME): { @@ -535,8 +570,8 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, // This request is not gonna be used anymore ClearWantedEvent(request); + break; } - break; case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY): { @@ -551,10 +586,9 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, reply.PrintToStream(); // This request is not gonna be used anymore - ClearWantedEvent(request); + ClearWantedEvent(request/*, HCI_EVENT_CMD_COMPLETE, opcodeExpected*/); + break; } - break; - case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY): { @@ -570,14 +604,51 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, reply.PrintToStream(); // This request is not gonna be used anymore - ClearWantedEvent(request); + ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected); + break; + } + + case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_STORED_LINK_KEY): + { + struct hci_read_stored_link_key_reply* linkKeyRetrieval + = JumpEventHeader(event); + + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "Status %s MaxKeys=%d, KeysRead=%d\n", + BluetoothError(linkKeyRetrieval->status), + linkKeyRetrieval->max_num_keys, linkKeyRetrieval->num_keys_read); + + reply.AddInt8("status", linkKeyRetrieval->status); + printf("Sending reply ... %ld\n",request->SendReply(&reply)); + reply.PrintToStream(); + + ClearWantedEvent(request); + break; + } + + case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY): + case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_REPLY): + { + struct hci_cp_link_key_reply_reply* linkKeyReply + = JumpEventHeader(event); + + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "Status %s addresss=%s\n", BluetoothError(linkKeyReply->status), + bdaddrUtils::ToString(linkKeyReply->bdaddr)); + + ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected); + break; } - break; // place here all CC that just replies a uint8 status case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET): case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE): case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV): + case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT): + case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT): + case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE): case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR): { reply.AddInt8("status", *(uint8*)(event + 1)); @@ -588,20 +659,21 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, request->SendReply(&reply); ClearWantedEvent(request); + break; } - break; default: Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT); - break; + break; } } void -LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* request, - int32 index) { +LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, + BMessage* request, int32 index) +{ int16 opcodeExpected; BMessage reply; @@ -609,10 +681,6 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* reques // Handle command complete information request->FindInt16("opcodeExpected", index, &opcodeExpected); - Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) %x for %s\n", - __FUNCTION__, event->ncmd, event->status, - BluetoothCommandOpcode(event->opcode)); - if (request->IsSourceWaiting() == false) Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); @@ -635,10 +703,10 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* reques break; case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST): + case PACK_OPCODE(OGF_LINK_CONTROL, OCF_CREATE_CONN): { if (event->status == BT_OK) { - ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, - PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST)); + ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected); } else { Output::Instance()->Postf(BLACKBOARD_KIT, "Command Status for remote friendly name %x\n", event->status); @@ -647,7 +715,7 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* reques printf("Sending reply ... %ld\n", request->SendReply(&reply)); reply.PrintToStream(); - ClearWantedEvent(request); + ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected); } } break; @@ -677,17 +745,31 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* reques void LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request) { - BMessage reply(BT_MSG_INQUIRY_DEVICE); + uint8 responses = *numberOfResponses; + // skipping here the number of responses reply.AddData("info", B_ANY_TYPE, numberOfResponses + 1, (*numberOfResponses) * sizeof(struct inquiry_info) ); reply.AddInt8("count", *numberOfResponses); - printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), "%s #responses=%d\n", + __FUNCTION__, *numberOfResponses); + struct inquiry_info* info = JumpEventHeader + (numberOfResponses); + + while (responses > 0) { + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "page_rep=%d scan_period=%d, scan=%d clock=%d\n", info->pscan_rep_mode, + info->pscan_period_mode, info->pscan_mode, info->clock_offset); + responses--; + info++; + } + + printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); } @@ -731,7 +813,8 @@ LocalDeviceImpl::RemoteNameRequestComplete( void -LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, BMessage* request) +LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, + BMessage* request) { size_t size; void* command; @@ -743,36 +826,39 @@ LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, BMessage* // TODO: add a possible request in the queue if (true) { // Check Preferences if we are to accept this connection - command = buildAcceptConnectionRequest(event->bdaddr, 0x01 /*slave*/, &size); + // Keep ourselves as slave + command = buildAcceptConnectionRequest(event->bdaddr, 0x01 , &size); BMessage* newrequest = new BMessage; newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ)); + newrequest->AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE); newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ); newrequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE); newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY); newrequest->AddInt16("eventExpected", HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE); - //newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE); - //newrequest->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE); + // newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE); + // newrequest->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE); AddWantedEvent(newrequest); if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) { Output::Instance()->Postf(BLACKBOARD_LD(GetID()), - "Command issue error for ConnAccept\n"); + "Command issued error for Accepting connection\n"); // remove the request? } else { Output::Instance()->Postf(BLACKBOARD_LD(GetID()), - "Command issue for ConnAccept\n"); + "Command issued for Accepting connection\n"); } } } void -LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request) +LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, + BMessage* request) { if (event->status == BT_OK) { @@ -789,27 +875,40 @@ LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage } else { Output::Instance()->Postf(BLACKBOARD_LD(GetID()), - "%s: failed with status %#x\n", __FUNCTION__, event->status); + "%s: failed with error %s\n", __FUNCTION__, BluetoothError(event->status)); + } + + // it was expected + if (request != NULL) { + BMessage reply; + reply.AddInt8("status", event->status); + + request->SendReply(&reply); + reply.PrintToStream(); + + // This request is not gonna be used anymore + ClearWantedEvent(request); } } void -LocalDeviceImpl::DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event, BMessage* request) +LocalDeviceImpl::DisconnectionComplete( + struct hci_ev_disconnection_complete_reply* event, BMessage* request) { - Output::Instance()->Post("Disconnected\n", BLACKBOARD_KIT); - Output::Instance()->Postf(BLACKBOARD_LD(GetID()), - "%s: Handle=%#x, reason=%x status=%x\n", __FUNCTION__, event->handle, - event->reason, event->status); + "%s: Handle=%#x, reason=%s status=%x\n", __FUNCTION__, event->handle, + BluetoothError(event->reason), event->status); - ClearWantedEvent(request); + if (request != NULL) + ClearWantedEvent(request); } void -LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request) +LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, + BMessage* request) { PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID()); iPincode->Show(); @@ -826,8 +925,8 @@ LocalDeviceImpl::RoleChange(hci_ev_role_change* event, BMessage* request) void -LocalDeviceImpl::PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change* event, - BMessage* request) +LocalDeviceImpl::PageScanRepetitionModeChange( + struct hci_ev_page_scan_rep_mode_change* event, BMessage* request) { Output::Instance()->Postf(BLACKBOARD_LD(GetID()), "%s: Address %s type=%d\n", __FUNCTION__, @@ -846,6 +945,62 @@ LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify* event, } +void +LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested, + BMessage* request) +{ + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "%s: Address %s\n", __FUNCTION__, + bdaddrUtils::ToString(keyRequested->bdaddr)); + + // TODO: + // Here we are suposed to check the BDADDR received, look into the server + // (RemoteDevice Database) if we have any pas link key interchanged with + // the given address if we have we are to accept it will "Link key Request + // Reply". As we dont not have such database yet, we will always deny it + // forcing the remote device to start a pairing. + + BluetoothCommand + linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY); + + bacpy(&linkKeyNegativeReply->bdaddr, &keyRequested->bdaddr); + + if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(), + linkKeyNegativeReply.Size()) == B_ERROR) { + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "Command issued error for reply %s\n", __FUNCTION__); + } else { + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "Command issued in reply of %s\n", __FUNCTION__); + } + + if (request != NULL) + ClearWantedEvent(request, HCI_EVENT_LINK_KEY_REQ); + +} + + +void +LocalDeviceImpl::ReturnLinkKeys(struct hci_ev_return_link_keys* returnedKeys) +{ + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), "%s: #keys=%d %s\n", + __FUNCTION__, returnedKeys->num_keys); + + uint8 numKeys = returnedKeys->num_keys; + + struct link_key_info* linkKeys = &returnedKeys->link_keys; + + while (numKeys > 0) { + + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), "Address=%s key=%s\n", + bdaddrUtils::ToString(linkKeys->bdaddr), + LinkKeyUtils::ToString(linkKeys->link_key)); + + linkKeys++; + } +} + + void LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change* event, BMessage* request) @@ -864,11 +1019,30 @@ LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error* event) } +void +LocalDeviceImpl::NumberOfCompletedPackets(struct hci_ev_num_comp_pkts* event) +{ + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "%s: #Handles=%d\n", __FUNCTION__, event->num_hndl); + + struct handle_and_number* numberPackets + = JumpEventHeader(event); + + for (uint8 i = 0; i < event->num_hndl; i++) { + + Output::Instance()->Postf(BLACKBOARD_LD(GetID()), + "%s: Handle=%d #packets=%d\n", __FUNCTION__, numberPackets->handle, + numberPackets->num_completed); + + numberPackets++; + } +} + + #if 0 #pragma mark - Request Methods - #endif - status_t LocalDeviceImpl::ProcessSimpleRequest(BMessage* request) { @@ -878,7 +1052,10 @@ LocalDeviceImpl::ProcessSimpleRequest(BMessage* request) if (request->FindData("raw command", B_ANY_TYPE, 0, (const void **)&command, &size) == B_OK) { - AddWantedEvent(request); + // Give the chance of just issuing the command + int16 eventFound; + if (request->FindInt16("eventExpected", &eventFound) == B_OK) + AddWantedEvent(request); // LEAK: is command buffer freed within the Message? if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) { diff --git a/src/servers/bluetooth/LocalDeviceImpl.h b/src/servers/bluetooth/LocalDeviceImpl.h index 4ba477ddd1..7af07d4c76 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.h +++ b/src/servers/bluetooth/LocalDeviceImpl.h @@ -35,27 +35,40 @@ public: private: void HandleUnexpectedEvent(struct hci_event_header* event); - void HandleExpectedRequest(struct hci_event_header* event, BMessage* request); + void HandleExpectedRequest(struct hci_event_header* event, + BMessage* request); // Events handling - void CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request, int32 index); - void CommandStatus(struct hci_ev_cmd_status* event, BMessage* request, int32 index); + void CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request, + int32 index); + void CommandStatus(struct hci_ev_cmd_status* event, BMessage* request, + int32 index); + + void NumberOfCompletedPackets(struct hci_ev_num_comp_pkts* event); // Inquiry void InquiryResult(uint8* numberOfResponses, BMessage* request); void InquiryComplete(uint8* status, BMessage* request); - void RemoteNameRequestComplete(struct hci_ev_remote_name_request_complete_reply* remotename, BMessage* request); + void RemoteNameRequestComplete(struct hci_ev_remote_name_request_complete_reply* + remotename, BMessage* request); // Connection void ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request); void ConnectionRequest(struct hci_ev_conn_request* event, BMessage* request); - void DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event, BMessage* request); + void DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event, + BMessage* request); // Pairing void PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request); void RoleChange(struct hci_ev_role_change* event, BMessage* request); void LinkKeyNotify(struct hci_ev_link_key_notify* event, BMessage* request); - void PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change* event, BMessage* request); + void ReturnLinkKeys(struct hci_ev_return_link_keys* returnedKeys); + + void LinkKeyRequested(struct hci_ev_link_key_req* keyReqyested, + BMessage* request); + + void PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change* event, + BMessage* request); void MaxSlotChange(struct hci_ev_max_slot_change* event, BMessage* request); void HardwareError(struct hci_ev_hardware_error* event);