From c122595a54be01fc6da1941dad99e308bb739e74 Mon Sep 17 00:00:00 2001 From: vighnesh-sawant Date: Mon, 16 Mar 2026 02:07:47 +0530 Subject: [PATCH] bluetooth: Make RemoteDevice::Authenticate actually pair after connecting Sends an auth request to the controller, if connection was initated by us Change-Id: I32af0a24b902d0223bb4e773258ea9e9749a899c Reviewed-on: https://review.haiku-os.org/c/haiku/+/10527 Reviewed-by: waddlesplash --- headers/private/bluetooth/CommandManager.h | 1 + src/kits/bluetooth/CommandManager.cpp | 16 ++++++++++ src/kits/bluetooth/RemoteDevice.cpp | 30 ++++++++++++++++-- src/servers/bluetooth/LocalDeviceImpl.cpp | 36 +++++++++++++++++++++- src/servers/bluetooth/LocalDeviceImpl.h | 1 + 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/headers/private/bluetooth/CommandManager.h b/headers/private/bluetooth/CommandManager.h index 611eff8d85..f1a1e54901 100644 --- a/headers/private/bluetooth/CommandManager.h +++ b/headers/private/bluetooth/CommandManager.h @@ -123,6 +123,7 @@ void* buildRejectConnectionRequest(bdaddr_t bdaddr, size_t* outsize); void* buildIOCapabilityRequestReply(bdaddr_t bdaddr, uint8 capability, uint8 oob_data, uint8 authentication, size_t* outsize); void* buildUserConfirmReply(bdaddr_t bdaddr, size_t* outsize); +void* buildAuthenticationRequested(uint16 handle, size_t* outsize); /* OGF_INFORMATIONAL_PARAM */ void* buildReadLocalVersionInformation(size_t* outsize); diff --git a/src/kits/bluetooth/CommandManager.cpp b/src/kits/bluetooth/CommandManager.cpp index 64b90a6163..fd0dcf5345 100644 --- a/src/kits/bluetooth/CommandManager.cpp +++ b/src/kits/bluetooth/CommandManager.cpp @@ -299,6 +299,22 @@ buildUserConfirmReply(bdaddr_t bdaddr, size_t* outsize) } +void* +buildAuthenticationRequested(uint16 handle, size_t* outsize) +{ + CALLED(); + struct hci_cp_auth_requested* param; + + void* command = buildCommand(OGF_LINK_CONTROL, OCF_AUTH_REQUESTED, (void**)¶m, + sizeof(struct hci_cp_auth_requested), outsize); + + if (command != NULL) + param->handle = handle; + + return command; +} + + #if 0 #pragma mark - INFORMATIONAL_PARAM - #endif diff --git a/src/kits/bluetooth/RemoteDevice.cpp b/src/kits/bluetooth/RemoteDevice.cpp index 2c9c4a4110..ba189540eb 100644 --- a/src/kits/bluetooth/RemoteDevice.cpp +++ b/src/kits/bluetooth/RemoteDevice.cpp @@ -188,10 +188,34 @@ RemoteDevice::Authenticate() if (fMessenger->SendMessage(&request, &reply) == B_OK) reply.FindInt8("status", &btStatus); - if (btStatus == BT_OK) { - reply.FindInt16("handle", (int16*)&fHandle); + if (btStatus != BT_OK) + return false; + + reply.FindInt16("handle", (int16*)&fHandle); + + BluetoothCommand authRequest(OGF_LINK_CONTROL, + OCF_AUTH_REQUESTED); + + authRequest->handle = fHandle; + + BMessage authRequestMsg(BT_MSG_HANDLE_SIMPLE_REQUEST); + BMessage authReply; + + authRequestMsg.AddInt32("hci_id", fDiscovererLocalDevice->ID()); + authRequestMsg.AddData("raw command", B_ANY_TYPE, authRequest.Data(), authRequest.Size()); + + authRequestMsg.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); + authRequestMsg.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_AUTH_REQUESTED)); + + authRequestMsg.AddInt16("eventExpected", HCI_EVENT_AUTH_COMPLETE); + + int8 authStatus = BT_ERROR; + if (fMessenger->SendMessage(&authRequestMsg, &authReply) == B_OK) + authReply.FindInt8("status", &authStatus); + + if (authStatus == BT_OK) return true; - } else + else return false; } diff --git a/src/servers/bluetooth/LocalDeviceImpl.cpp b/src/servers/bluetooth/LocalDeviceImpl.cpp index fcd29dac8f..0af7c3dae8 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.cpp +++ b/src/servers/bluetooth/LocalDeviceImpl.cpp @@ -166,7 +166,7 @@ LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, break; case HCI_EVENT_AUTH_COMPLETE: - + AuthComplete(JumpEventHeader(event), request); break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: @@ -821,6 +821,12 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected); } break; + case PACK_OPCODE(OGF_LINK_CONTROL, OCF_AUTH_REQUESTED): + { + TRACE_BT("LocalDeviceImpl: Command Status for auth requested %x\n", event->status); + ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected); + } break; + default: TRACE_BT("LocalDeviceImpl: Command Status not handled\n"); break; @@ -1376,6 +1382,34 @@ LocalDeviceImpl::SimplePairingComplete(struct hci_ev_simple_pairing_complete* ev ClearWantedEvent(request); } + +void +LocalDeviceImpl::AuthComplete(struct hci_ev_auth_complete* eventData, BMessage* request) +{ + int16 handle = B_LENDIAN_TO_HOST_INT16(eventData->handle); + int8 status = eventData->status; + + if (status == BT_OK) { + TRACE_BT("LocalDeviceImpl: Authentication Successful for handle %d\n", handle); + } else { + TRACE_BT("LocalDeviceImpl: Authentication Failed for handle %d with status 0x%02x\n", + handle, status); + } + + if (request != NULL) { + BMessage reply; + reply.AddInt8("status", status); + reply.AddInt16("handle", handle); + + request->SendReply(&reply); + + ClearWantedEvent(request); + } else { + TRACE_BT("LocalDeviceImpl: Auth Complete received but no local request was waiting.\n"); + } +} + + #if 0 #pragma mark - Request Methods - #endif diff --git a/src/servers/bluetooth/LocalDeviceImpl.h b/src/servers/bluetooth/LocalDeviceImpl.h index 8c98595c93..f4cda926e0 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.h +++ b/src/servers/bluetooth/LocalDeviceImpl.h @@ -84,6 +84,7 @@ private: void UserConfirmationRequest(struct hci_ev_user_confirmation_request* event, BMessage* request); void SimplePairingComplete(struct hci_ev_simple_pairing_complete* event, BMessage* request); + void AuthComplete(struct hci_ev_auth_complete* eventData, BMessage* request); }; #endif