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 <cstddef> 17 #include <span> 18 #include <tuple> 19 20 #include "pw_containers/intrusive_list.h" 21 #include "pw_rpc/channel.h" 22 #include "pw_rpc/internal/base_server_writer.h" 23 #include "pw_rpc/internal/channel.h" 24 #include "pw_rpc/internal/method.h" 25 #include "pw_rpc/service.h" 26 #include "pw_status/status.h" 27 28 namespace pw::rpc { 29 30 class Server { 31 public: Server(std::span<Channel> channels)32 constexpr Server(std::span<Channel> channels) 33 : channels_(static_cast<internal::Channel*>(channels.data()), 34 channels.size()) {} 35 36 ~Server(); 37 38 // Registers a service with the server. This should not be called directly 39 // with a Service; instead, use a generated class which inherits from it. RegisterService(Service & service)40 void RegisterService(Service& service) { services_.push_front(service); } 41 42 // Processes an RPC packet. The packet may contain an RPC request or a control 43 // packet, the result of which is processed in this function. Returns whether 44 // the packet was able to be processed: 45 // 46 // OK - The packet was processed by the server. 47 // DATA_LOSS - Failed to decode the packet. 48 // INVALID_ARGUMENT - The packet is intended for a client, not a server. 49 // 50 Status ProcessPacket(std::span<const std::byte> packet, 51 ChannelOutput& interface); 52 channel_count()53 constexpr size_t channel_count() const { return channels_.size(); } 54 55 protected: writers()56 IntrusiveList<internal::BaseServerWriter>& writers() { return writers_; } 57 58 private: 59 std::tuple<Service*, const internal::Method*> FindMethod( 60 const internal::Packet& packet); 61 62 void HandleCancelPacket(const internal::Packet& request, 63 internal::Channel& channel); 64 void HandleClientError(const internal::Packet& packet); 65 66 internal::Channel* FindChannel(uint32_t id) const; 67 internal::Channel* AssignChannel(uint32_t id, ChannelOutput& interface); 68 69 std::span<internal::Channel> channels_; 70 IntrusiveList<Service> services_; 71 IntrusiveList<internal::BaseServerWriter> writers_; 72 }; 73 74 } // namespace pw::rpc 75