blob: c538cb1e4649514d326a3f8270105bbd2796ec76 [file] [log] [blame]
// Copyright 2020 the Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "idle_phase.h"
#include <zircon/assert.h>
#include <type_traits>
#include "src/connectivity/bluetooth/core/bt-host/common/log.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/packet.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/smp.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/types.h"
namespace bt {
namespace sm {
IdlePhase::IdlePhase(fxl::WeakPtr<PairingChannel> chan, fxl::WeakPtr<Listener> listener,
hci::Connection::Role role, PairingRequestCallback on_pairing_req,
SecurityRequestCallback on_security_req)
: PairingPhase(std::move(chan), std::move(listener), role),
weak_ptr_factory_(this),
on_pairing_req_(std::move(on_pairing_req)),
on_security_req_(std::move(on_security_req)) {
sm_chan().SetChannelHandler(weak_ptr_factory_.GetWeakPtr());
}
void IdlePhase::OnPairingRequest(PairingRequestParams req_params) {
// Reject the command if we are the master.
if (is_initiator()) {
bt_log(TRACE, "sm", "rejecting \"Pairing Request\" as master");
SendPairingFailed(ErrorCode::kCommandNotSupported);
return;
}
on_pairing_req_(req_params);
}
void IdlePhase::OnSecurityRequest(AuthReqField req) {
// Reject the command if we are the slave.
if (is_responder()) {
bt_log(TRACE, "sm", "rejecting \"Security Request\" as slave");
SendPairingFailed(ErrorCode::kCommandNotSupported);
return;
}
on_security_req_(req);
}
void IdlePhase::OnRxBFrame(ByteBufferPtr sdu) {
fit::result<ValidPacketReader, ErrorCode> maybe_reader = ValidPacketReader::ParseSdu(sdu);
if (maybe_reader.is_error()) {
bt_log(INFO, "sm", "dropped SMP packet: %s", bt_str(Status(maybe_reader.error())));
return;
}
ValidPacketReader reader = maybe_reader.value();
Code smp_code = reader.code();
if (smp_code == kPairingRequest) {
OnPairingRequest(reader.payload<PairingRequestParams>());
} else if (smp_code == kSecurityRequest) {
OnSecurityRequest(reader.payload<AuthReqField>());
} else {
bt_log(INFO, "sm", "dropped unexpected SMP code %#.2X when not pairing", smp_code);
}
}
void IdlePhase::OnChannelClosed() { bt_log(TRACE, "sm", "channel closed while not pairing"); }
} // namespace sm
} // namespace bt