blob: 26d1753e8c1009bd495bb223d71675bfdc6a51dd [file] [log] [blame]
// Copyright 2017 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 "attribute.h"
namespace btlib {
namespace att {
AccessRequirements::AccessRequirements() : value_(0u) {}
AccessRequirements::AccessRequirements(bool encryption,
bool authentication,
bool authorization)
: value_(kAttributePermissionBitAllowed) {
if (encryption) {
value_ |= kAttributePermissionBitEncryptionRequired;
}
if (authentication) {
value_ |= kAttributePermissionBitAuthenticationRequired;
}
if (authorization) {
value_ |= kAttributePermissionBitAuthorizationRequired;
}
}
Attribute::Attribute(AttributeGrouping* group,
Handle handle,
const common::UUID& type,
const AccessRequirements& read_reqs,
const AccessRequirements& write_reqs)
: group_(group),
handle_(handle),
type_(type),
read_reqs_(read_reqs),
write_reqs_(write_reqs) {
ZX_DEBUG_ASSERT(group_);
ZX_DEBUG_ASSERT(is_initialized());
}
Attribute::Attribute() : handle_(kInvalidHandle) {}
void Attribute::SetValue(const common::ByteBuffer& value) {
ZX_DEBUG_ASSERT(value.size());
ZX_DEBUG_ASSERT(value.size() <= kMaxAttributeValueLength);
ZX_DEBUG_ASSERT(!write_reqs_.allowed());
value_ = common::DynamicByteBuffer(value);
}
bool Attribute::ReadAsync(const std::string& peer_id,
uint16_t offset,
ReadResultCallback result_callback) const {
if (!is_initialized() || !read_handler_)
return false;
if (!read_reqs_.allowed())
return false;
read_handler_(peer_id, handle_, offset, std::move(result_callback));
return true;
}
bool Attribute::WriteAsync(const std::string& peer_id,
uint16_t offset,
const common::ByteBuffer& value,
WriteResultCallback result_callback) const {
if (!is_initialized() || !write_handler_)
return false;
if (!write_reqs_.allowed())
return false;
write_handler_(peer_id, handle_, offset, std::move(value), std::move(result_callback));
return true;
}
AttributeGrouping::AttributeGrouping(const common::UUID& group_type,
Handle start_handle,
size_t attr_count,
const common::ByteBuffer& decl_value)
: start_handle_(start_handle), active_(false) {
ZX_DEBUG_ASSERT(start_handle_ != kInvalidHandle);
ZX_DEBUG_ASSERT(kHandleMax - start_handle > attr_count);
ZX_DEBUG_ASSERT(decl_value.size());
end_handle_ = start_handle + attr_count;
attributes_.reserve(attr_count + 1);
// TODO(armansito): Allow callers to require at most encryption.
attributes_.push_back(Attribute(
this, start_handle, group_type,
AccessRequirements(false, false, false), // read allowed, no security
AccessRequirements())); // write disallowed
attributes_[0].SetValue(decl_value);
}
Attribute* AttributeGrouping::AddAttribute(
const common::UUID& type,
const AccessRequirements& read_reqs,
const AccessRequirements& write_reqs) {
if (complete())
return nullptr;
ZX_DEBUG_ASSERT(attributes_[attributes_.size() - 1].handle() < end_handle_);
Handle handle = start_handle_ + attributes_.size();
attributes_.push_back(Attribute(this, handle, type, read_reqs, write_reqs));
return &attributes_[handle - start_handle_];
}
} // namespace att
} // namespace btlib