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 <cstdint> 17 #include <limits> 18 #include <span> 19 20 #include "pw_containers/intrusive_list.h" 21 #include "pw_preprocessor/compiler.h" 22 #include "pw_rpc/internal/method.h" 23 #include "pw_rpc/internal/method_union.h" 24 25 namespace pw::rpc { 26 27 // Base class for all RPC services. This cannot be instantiated directly; use a 28 // generated subclass instead. 29 // 30 // Services store a span of concrete method implementation classes. To support 31 // different Method implementations, Service stores a base MethodUnion* and the 32 // size of the concrete MethodUnion object. 33 class Service : public IntrusiveList<Service>::Item { 34 public: id()35 uint32_t id() const { return id_; } 36 37 protected: 38 template <typename T, size_t kMethodCount> Service(uint32_t id,const std::array<T,kMethodCount> & methods)39 constexpr Service(uint32_t id, const std::array<T, kMethodCount>& methods) 40 : id_(id), 41 methods_(methods.data()), 42 method_size_(sizeof(T)), 43 method_count_(static_cast<uint16_t>(kMethodCount)) { 44 PW_MODIFY_DIAGNOSTICS_PUSH(); 45 // GCC 10 emits spurious -Wtype-limits warnings for the static_assert. 46 PW_MODIFY_DIAGNOSTIC_GCC(ignored, "-Wtype-limits"); 47 static_assert(kMethodCount <= std::numeric_limits<uint16_t>::max()); 48 PW_MODIFY_DIAGNOSTICS_POP(); 49 } 50 51 // For use by tests with only one method. 52 template <typename T> Service(uint32_t id,const T & method)53 constexpr Service(uint32_t id, const T& method) 54 : id_(id), methods_(&method), method_size_(sizeof(T)), method_count_(1) {} 55 56 private: 57 friend class Server; 58 friend class ServiceTestHelper; 59 60 // Finds the method with the provided method_id. Returns nullptr if no match. 61 const internal::Method* FindMethod(uint32_t method_id) const; 62 63 const uint32_t id_; 64 const internal::MethodUnion* const methods_; 65 const uint16_t method_size_; 66 const uint16_t method_count_; 67 }; 68 69 } // namespace pw::rpc 70