From a309dd68909ffb8053fac2e93ae9172b80a6d653 Mon Sep 17 00:00:00 2001 From: mohammedrattia Date: Sat, 13 Jun 2026 01:24:50 +0300 Subject: [PATCH] bluetooth: adding a functioning cancel button to the Inquiry Panel - This is a mandatory feature in HCI Implementation Conformance Statement (ICS). - The inquiry cancel logic was implemented in Haiku, but wasn't linked to the inquiry panel. Change-Id: Ic827b0a09979a078bed5b9f99a8541dc319ac449 Reviewed-on: https://review.haiku-os.org/c/haiku/+/11106 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- headers/os/bluetooth/DiscoveryListener.h | 2 +- src/kits/bluetooth/DiscoveryAgent.cpp | 2 +- src/kits/bluetooth/DiscoveryListener.cpp | 8 ++-- src/preferences/bluetooth/InquiryPanel.cpp | 48 ++++++++++++++++++++-- src/preferences/bluetooth/InquiryPanel.h | 1 + src/servers/bluetooth/LocalDeviceImpl.cpp | 20 +++++++++ 6 files changed, 72 insertions(+), 9 deletions(-) diff --git a/headers/os/bluetooth/DiscoveryListener.h b/headers/os/bluetooth/DiscoveryListener.h index 5f9f8676eb..1993f16104 100644 --- a/headers/os/bluetooth/DiscoveryListener.h +++ b/headers/os/bluetooth/DiscoveryListener.h @@ -42,7 +42,7 @@ public: virtual void servicesDiscovered(int transID, ServiceRecord[] servRecord); virtual void serviceSearchCompleted(int transID, int respCode); */ - virtual void InquiryCompleted(int discType); + virtual void InquiryResponse(int discType); /* JSR82 non-defined methods */ virtual void InquiryStarted(status_t status); diff --git a/src/kits/bluetooth/DiscoveryAgent.cpp b/src/kits/bluetooth/DiscoveryAgent.cpp index 1b5aca196d..9fe4b7f665 100644 --- a/src/kits/bluetooth/DiscoveryAgent.cpp +++ b/src/kits/bluetooth/DiscoveryAgent.cpp @@ -119,7 +119,7 @@ DiscoveryAgent::CancelInquiry(DiscoveryListener* listener) cancelInquiryCommand = buildInquiryCancel(&size); request.AddData("raw command", B_ANY_TYPE, cancelInquiryCommand, size); - request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); + request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL)); diff --git a/src/kits/bluetooth/DiscoveryListener.cpp b/src/kits/bluetooth/DiscoveryListener.cpp index cd2f526067..1950829782 100644 --- a/src/kits/bluetooth/DiscoveryListener.cpp +++ b/src/kits/bluetooth/DiscoveryListener.cpp @@ -37,7 +37,7 @@ DiscoveryListener::InquiryStarted(status_t status) void -DiscoveryListener::InquiryCompleted(int discType) +DiscoveryListener::InquiryResponse(int discType) { CALLED(); } @@ -156,15 +156,15 @@ DiscoveryListener::MessageReceived(BMessage* message) break; case BT_MSG_INQUIRY_COMPLETED: - InquiryCompleted(BT_INQUIRY_COMPLETED); + InquiryResponse(BT_INQUIRY_COMPLETED); break; case BT_MSG_INQUIRY_TERMINATED: /* inquiry was cancelled */ - InquiryCompleted(BT_INQUIRY_TERMINATED); + InquiryResponse(BT_INQUIRY_TERMINATED); break; case BT_MSG_INQUIRY_ERROR: - InquiryCompleted(BT_INQUIRY_ERROR); + InquiryResponse(BT_INQUIRY_ERROR); break; default: diff --git a/src/preferences/bluetooth/InquiryPanel.cpp b/src/preferences/bluetooth/InquiryPanel.cpp index aac8e5dd79..93e577a9f0 100644 --- a/src/preferences/bluetooth/InquiryPanel.cpp +++ b/src/preferences/bluetooth/InquiryPanel.cpp @@ -40,6 +40,7 @@ extern uint8 GetInquiryTime(); static const uint32 kMsgStart = 'InSt'; static const uint32 kMsgFinish = 'InFn'; +static const uint32 kMsgCancel = 'InCl'; static const uint32 kMsgShowDebug = 'ShDG'; static const uint32 kMsgInquiry = 'iQbt'; @@ -73,10 +74,24 @@ public: void - InquiryCompleted(int discType) + InquiryResponse(int discType) { - BMessage* message = new BMessage(kMsgFinish); - fInquiryPanel->PostMessage(message); + BMessage* message; + switch (discType) + { + case BT_INQUIRY_COMPLETED: + message = new BMessage(kMsgFinish); + fInquiryPanel->PostMessage(message); + break; + + case BT_INQUIRY_TERMINATED: + message = new BMessage(kMsgCancel); + fInquiryPanel->PostMessage(message); + break; + + case BT_INQUIRY_ERROR: + break; + } } @@ -119,6 +134,10 @@ InquiryPanel::InquiryPanel(BRect frame, LocalDevice* lDevice) fInquiryButton = new BButton("Inquiry", B_TRANSLATE("Inquiry"), new BMessage(kMsgInquiry), B_WILL_DRAW); + fCancelButton = new BButton("cancel", B_TRANSLATE("Cancel"), + new BMessage(kMsgCancel), B_WILL_DRAW); + fCancelButton->SetEnabled(false); + fAddButton = new BButton("add", B_TRANSLATE("Add device to list"), new BMessage(kMsgAddToRemoteList), B_WILL_DRAW); fAddButton->SetEnabled(false); @@ -159,6 +178,7 @@ InquiryPanel::InquiryPanel(BRect frame, LocalDevice* lDevice) .AddGroup(B_HORIZONTAL, 10) .Add(fAddButton) .AddGlue() + .Add(fCancelButton) .Add(fInquiryButton) .End() .End(); @@ -222,6 +242,7 @@ InquiryPanel::MessageReceived(BMessage* message) fAddButton->SetEnabled(false); fInquiryButton->SetEnabled(false); + fCancelButton->SetEnabled(true); BMessageRunner::StartSending(fMessenger, fSecondsMessage, 1000000, timer); @@ -236,6 +257,7 @@ InquiryPanel::MessageReceived(BMessage* message) fScanning = false; fRetrieving = true; labelPlaced = false; + fCancelButton->SetEnabled(false); fScanProgress->SetTo(100); fScanProgress->SetTrailingText(B_TRANSLATE("Retrieving names" B_UTF8_ELLIPSIS)); @@ -243,6 +265,21 @@ InquiryPanel::MessageReceived(BMessage* message) break; + case kMsgCancel: + + fDiscoveryAgent->CancelInquiry(fDiscoveryListener); + retrievalIndex = 0; + fScanning = false; + fRetrieving = true; + labelPlaced = false; + fCancelButton->SetEnabled(false); + fScanProgress->SetTo(100); + fScanProgress->SetTrailingText(B_TRANSLATE("Canceling Inquiry" + B_UTF8_ELLIPSIS)); + BMessageRunner::StartSending(fMessenger, fRetrieveMessage, 1000000, 1); + + break; + case kMsgSecond: if (fScanning && scanningTime < timer) { // TODO time formatting could use Locale Kit @@ -328,6 +365,11 @@ InquiryPanel::UpdateListStatus(void) bool InquiryPanel::QuitRequested(void) { + if (fScanning) + fDiscoveryAgent->CancelInquiry(fDiscoveryListener); + + if (fDiscoveryListener->Lock()) + fDiscoveryListener->Quit(); return true; } diff --git a/src/preferences/bluetooth/InquiryPanel.h b/src/preferences/bluetooth/InquiryPanel.h index 0238987973..8c2c4aa802 100644 --- a/src/preferences/bluetooth/InquiryPanel.h +++ b/src/preferences/bluetooth/InquiryPanel.h @@ -33,6 +33,7 @@ private: BStatusBar* fScanProgress; BButton* fAddButton; BButton* fInquiryButton; + BButton* fCancelButton; BTextView* fMessage; BListView* fRemoteList; BScrollView* fScrollView; diff --git a/src/servers/bluetooth/LocalDeviceImpl.cpp b/src/servers/bluetooth/LocalDeviceImpl.cpp index 77e3c7a9c2..7c41117c4e 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.cpp +++ b/src/servers/bluetooth/LocalDeviceImpl.cpp @@ -738,6 +738,26 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, break; } + case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL): + { + reply.AddInt8("status", *(uint8*)(event + 1)); + + TRACE_BT("LocalDeviceImpl: %s for %s status %x\n", __FUNCTION__, + BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1)); + + status = request->SendReply(&reply); + printf("%s: Sending reply write...\n", __func__); + if (status < B_OK) + printf("%s: Error sending reply write!\n", __func__); + + BMessage* inquiry_request = FindPetition(HCI_EVENT_INQUIRY_COMPLETE); + if (inquiry_request != NULL) + ClearWantedEvent(inquiry_request); + + ClearWantedEvent(request); + 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):