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 #include "pw_log_rpc/log_filter_service.h" 15 16 #include "pw_log/log.h" 17 #include "pw_log/proto/log.pwpb.h" 18 #include "pw_log_rpc/log_filter.h" 19 #include "pw_protobuf/decoder.h" 20 21 namespace pw::log_rpc { 22 23 namespace GetFilterRequest = ::pw::log::pwpb::GetFilterRequest; 24 namespace SetFilterRequest = ::pw::log::pwpb::SetFilterRequest; 25 namespace FilterRule = ::pw::log::pwpb::FilterRule; 26 SetFilterImpl(ConstByteSpan request)27Status FilterService::SetFilterImpl(ConstByteSpan request) { 28 protobuf::Decoder decoder(request); 29 PW_TRY(decoder.Next()); 30 if (static_cast<SetFilterRequest::Fields>(decoder.FieldNumber()) != 31 SetFilterRequest::Fields::kFilterId) { 32 return Status::InvalidArgument(); 33 } 34 ConstByteSpan filter_id; 35 PW_TRY(decoder.ReadBytes(&filter_id)); 36 Result<Filter*> filter = filter_map_.GetFilterFromId(filter_id); 37 if (!filter.ok()) { 38 return Status::NotFound(); 39 } 40 41 PW_TRY(decoder.Next()); 42 ConstByteSpan filter_buffer; 43 if (static_cast<SetFilterRequest::Fields>(decoder.FieldNumber()) != 44 SetFilterRequest::Fields::kFilter) { 45 return Status::InvalidArgument(); 46 } 47 PW_TRY(decoder.ReadBytes(&filter_buffer)); 48 49 return filter.value()->UpdateRulesFromProto(filter_buffer); 50 } 51 GetFilterImpl(ConstByteSpan request,ByteSpan response)52StatusWithSize FilterService::GetFilterImpl(ConstByteSpan request, 53 ByteSpan response) { 54 protobuf::Decoder decoder(request); 55 PW_TRY_WITH_SIZE(decoder.Next()); 56 if (static_cast<GetFilterRequest::Fields>(decoder.FieldNumber()) != 57 GetFilterRequest::Fields::kFilterId) { 58 return StatusWithSize::InvalidArgument(); 59 } 60 ConstByteSpan filter_id; 61 PW_TRY_WITH_SIZE(decoder.ReadBytes(&filter_id)); 62 Result<Filter*> filter = filter_map_.GetFilterFromId(filter_id); 63 if (!filter.ok()) { 64 return StatusWithSize::NotFound(); 65 } 66 67 log::pwpb::Filter::MemoryEncoder encoder(response); 68 for (auto& rule : (*filter)->rules()) { 69 FilterRule::StreamEncoder rule_encoder = encoder.GetRuleEncoder(); 70 rule_encoder.WriteLevelGreaterThanOrEqual(rule.level_greater_than_or_equal) 71 .IgnoreError(); 72 rule_encoder.WriteModuleEquals(rule.module_equals).IgnoreError(); 73 rule_encoder.WriteAnyFlagsSet(rule.any_flags_set).IgnoreError(); 74 rule_encoder.WriteAction(static_cast<FilterRule::Action>(rule.action)) 75 .IgnoreError(); 76 rule_encoder.WriteThreadEquals(rule.thread_equals).IgnoreError(); 77 PW_TRY_WITH_SIZE(rule_encoder.status()); 78 } 79 PW_TRY_WITH_SIZE(encoder.status()); 80 81 return StatusWithSize(encoder.size()); 82 } 83 ListFilterIdsImpl(ByteSpan response)84StatusWithSize FilterService::ListFilterIdsImpl(ByteSpan response) { 85 log::pwpb::FilterIdListResponse::MemoryEncoder encoder(response); 86 for (auto& filter : filter_map_.filters()) { 87 PW_TRY_WITH_SIZE(encoder.WriteFilterId(filter.id())); 88 } 89 return StatusWithSize(encoder.size()); 90 } 91 92 } // namespace pw::log_rpc 93