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 #pragma once 15 16 #include <span> 17 18 #include "pw_bytes/span.h" 19 #include "pw_metric/metric.h" 20 #include "pw_router/egress.h" 21 #include "pw_router/packet_parser.h" 22 #include "pw_status/status.h" 23 #include "pw_sync/lock_annotations.h" 24 #include "pw_sync/mutex.h" 25 26 namespace pw::router { 27 28 // A packet router with a static routing table. 29 // 30 // Thread-safety: 31 // Internal packet parsing and calls to the provided PacketParser are 32 // synchronized. Synchronization at the egress level must be implemented by 33 // derived egresses. 34 // 35 class StaticRouter { 36 public: 37 struct Route { 38 // TODO(frolv): Consider making address size configurable. 39 uint32_t address; 40 Egress& egress; 41 }; 42 StaticRouter(PacketParser & parser,std::span<const Route> routes)43 StaticRouter(PacketParser& parser, std::span<const Route> routes) 44 : parser_(parser), routes_(routes) {} 45 46 StaticRouter(const StaticRouter&) = delete; 47 StaticRouter(StaticRouter&&) = delete; 48 StaticRouter& operator=(const StaticRouter&) = delete; 49 StaticRouter& operator=(StaticRouter&&) = delete; 50 dropped_packets()51 uint32_t dropped_packets() const { 52 return parser_errors_.value() + route_errors_.value() + 53 egress_errors_.value(); 54 } 55 metrics()56 const metric::Group& metrics() { return metrics_; } 57 58 // Routes a single packet through the appropriate egress. 59 // Returns one of the following to indicate a router-side error: 60 // 61 // OK - Packet sent successfully. 62 // DATA_LOSS - Packet corrupt or incomplete. 63 // NOT_FOUND - No registered route for the packet. 64 // UNAVAILABLE - Route egress did not accept packet. 65 // 66 Status RoutePacket(ConstByteSpan packet) PW_LOCKS_EXCLUDED(mutex_); 67 68 private: 69 PacketParser& parser_ PW_GUARDED_BY(mutex_); 70 const std::span<const Route> routes_; 71 sync::Mutex mutex_; 72 PW_METRIC_GROUP(metrics_, "static_router"); 73 PW_METRIC(metrics_, parser_errors_, "parser_errors", 0u); 74 PW_METRIC(metrics_, route_errors_, "route_errors", 0u); 75 PW_METRIC(metrics_, egress_errors_, "egress_errors", 0u); 76 }; 77 78 } // namespace pw::router 79