1 // Copyright 2021 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 15 #pragma once 16 17 #include "pw_log/proto/log.raw_rpc.pb.h" 18 #include "pw_log_rpc/log_filter_map.h" 19 #include "pw_status/status_with_size.h" 20 21 namespace pw::log_rpc { 22 23 // Provides a way to retrieve and modify log filters. 24 class FilterService final 25 : public log::pw_rpc::raw::Filters::Service<FilterService> { 26 public: FilterService(FilterMap & filter_map)27 FilterService(FilterMap& filter_map) : filter_map_(filter_map) {} 28 29 // Modifies a log filter and its rules. The filter must be registered in the 30 // provided filter map. SetFilter(ConstByteSpan request,rpc::RawUnaryResponder & responder)31 void SetFilter(ConstByteSpan request, rpc::RawUnaryResponder& responder) { 32 responder.Finish({}, SetFilterImpl(request)).IgnoreError(); 33 } 34 35 // Retrieves a log filter and its rules. The filter must be registered in the 36 // provided filter map. GetFilter(ConstByteSpan request,rpc::RawUnaryResponder & responder)37 void GetFilter(ConstByteSpan request, rpc::RawUnaryResponder& responder) { 38 std::byte buffer[kFilterResponseBufferSize] = {}; 39 StatusWithSize result = GetFilterImpl(request, buffer); 40 responder.Finish(span(buffer).first(result.size()), result.status()) 41 .IgnoreError(); 42 } 43 ListFilterIds(ConstByteSpan,rpc::RawUnaryResponder & responder)44 void ListFilterIds(ConstByteSpan, rpc::RawUnaryResponder& responder) { 45 std::byte buffer[kFilterIdsResponseBufferSize] = {}; 46 StatusWithSize result = ListFilterIdsImpl(buffer); 47 responder.Finish(span(buffer).first(result.size()), result.status()) 48 .IgnoreError(); 49 } 50 51 private: 52 static constexpr size_t kMinSupportedFilters = 4; 53 54 static constexpr size_t kFilterResponseBufferSize = 55 protobuf::TagSizeBytes(log::pwpb::Filter::Fields::kRule) + 56 protobuf::kMaxSizeOfLength + 57 kMinSupportedFilters * 58 (protobuf::SizeOfFieldEnum( 59 log::pwpb::FilterRule::Fields::kLevelGreaterThanOrEqual, 7) + 60 protobuf::SizeOfFieldBytes( 61 log::pwpb::FilterRule::Fields::kModuleEquals, 62 cfg::kMaxModuleNameBytes) + 63 protobuf::SizeOfFieldUint32( 64 log::pwpb::FilterRule::Fields::kAnyFlagsSet, 1) + 65 protobuf::SizeOfFieldEnum(log::pwpb::FilterRule::Fields::kAction, 66 2) + 67 protobuf::SizeOfFieldBytes( 68 log::pwpb::FilterRule::Fields::kThreadEquals, 69 cfg::kMaxThreadNameBytes)); 70 71 static constexpr size_t kFilterIdsResponseBufferSize = 72 kMinSupportedFilters * 73 protobuf::SizeOfFieldBytes( 74 log::pwpb::FilterIdListResponse::Fields::kFilterId, 4); 75 76 Status SetFilterImpl(ConstByteSpan request); 77 StatusWithSize GetFilterImpl(ConstByteSpan request, ByteSpan response); 78 StatusWithSize ListFilterIdsImpl(ByteSpan response); 79 80 FilterMap& filter_map_; 81 }; 82 83 } // namespace pw::log_rpc 84