1 // Copyright 2020 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include <span> 17 18 #include "pw_assert/assert.h" 19 #include "pw_rpc/channel.h" 20 #include "pw_status/status.h" 21 22 namespace pw::rpc::internal { 23 24 class Packet; 25 26 class Channel : public rpc::Channel { 27 public: 28 Channel() = delete; 29 Channel(uint32_t id,ChannelOutput * output)30 constexpr Channel(uint32_t id, ChannelOutput* output) 31 : rpc::Channel(id, output) {} 32 33 class OutputBuffer { 34 public: 35 constexpr OutputBuffer() = default; 36 37 OutputBuffer(const OutputBuffer&) = delete; 38 OutputBuffer(OutputBuffer && other)39 OutputBuffer(OutputBuffer&& other) { *this = std::move(other); } 40 ~OutputBuffer()41 ~OutputBuffer() { PW_DCHECK(buffer_.empty()); } 42 43 OutputBuffer& operator=(const OutputBuffer&) = delete; 44 45 OutputBuffer& operator=(OutputBuffer&& other) { 46 PW_DCHECK(buffer_.empty()); 47 buffer_ = other.buffer_; 48 other.buffer_ = {}; 49 return *this; 50 } 51 52 // Returns a portion of this OutputBuffer to use as the packet payload. 53 std::span<std::byte> payload(const Packet& packet) const; 54 Contains(std::span<const std::byte> buffer)55 bool Contains(std::span<const std::byte> buffer) const { 56 return buffer.data() >= buffer_.data() && 57 buffer.data() + buffer.size() <= buffer_.data() + buffer_.size(); 58 } 59 empty()60 bool empty() const { return buffer_.empty(); } 61 62 private: 63 friend class Channel; 64 OutputBuffer(std::span<std::byte> buffer)65 explicit constexpr OutputBuffer(std::span<std::byte> buffer) 66 : buffer_(buffer) {} 67 68 std::span<std::byte> buffer_; 69 }; 70 71 // Acquires a buffer for the packet. AcquireBuffer()72 OutputBuffer AcquireBuffer() const { 73 return OutputBuffer(output().AcquireBuffer()); 74 } 75 Send(const internal::Packet & packet)76 Status Send(const internal::Packet& packet) { 77 OutputBuffer buffer = AcquireBuffer(); 78 return Send(buffer, packet); 79 } 80 81 Status Send(OutputBuffer& output, const internal::Packet& packet); 82 Release(OutputBuffer & buffer)83 void Release(OutputBuffer& buffer) { 84 output().DiscardBuffer(buffer.buffer_); 85 buffer.buffer_ = {}; 86 } 87 }; 88 89 } // namespace pw::rpc::internal 90