1 // Copyright 2021 The Pigweed Authors
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
7 // https://www.apache.org/licenses/LICENSE-2.0
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
15 #include "pw_router/static_router.h"
20 #include "pw_log/log.h"
22 namespace pw::router {
24 Status StaticRouter::RoutePacket(ConstByteSpan packet) {
28 // Only packet parsing is synchronized within the router; egresses must be
29 // synchronized externally.
30 std::lock_guard lock(mutex_);
32 if (!parser_.Parse(packet)) {
33 PW_LOG_ERROR("StaticRouter failed to parse packet; dropping");
34 parser_errors_.Increment();
35 return Status::DataLoss();
38 std::optional<uint32_t> result = parser_.GetDestinationAddress();
39 if (!result.has_value()) {
40 PW_LOG_ERROR("StaticRouter packet does not have address; dropping");
41 parser_errors_.Increment();
42 return Status::DataLoss();
45 address = result.value();
48 auto route = std::find_if(routes_.begin(), routes_.end(), [&](auto r) {
49 return r.address == address;
51 if (route == routes_.end()) {
52 PW_LOG_ERROR("StaticRouter no route for address %u; dropping packet",
53 static_cast<unsigned>(address));
54 route_errors_.Increment();
55 return Status::NotFound();
58 PW_LOG_DEBUG("StaticRouter routing %u-byte packet to address %u",
59 static_cast<unsigned>(packet.size()),
60 static_cast<unsigned>(address));
62 if (Status status = route->egress.SendPacket(packet); !status.ok()) {
63 PW_LOG_ERROR("StaticRouter egress error for address %u: %s",
64 static_cast<unsigned>(address),
66 egress_errors_.Increment();
67 return Status::Unavailable();
73 } // namespace pw::router