13b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal/* 23b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * Copyright (C) 2016 The Android Open Source Project 33b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * 43b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * Licensed under the Apache License, Version 2.0 (the "License"); 53b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * you may not use this file except in compliance with the License. 63b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * You may obtain a copy of the License at 73b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * 83b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * http://www.apache.org/licenses/LICENSE-2.0 93b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * 103b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * Unless required by applicable law or agreed to in writing, software 113b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * distributed under the License is distributed on an "AS IS" BASIS, 123b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * See the License for the specific language governing permissions and 143b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal * limitations under the License. 153b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal */ 163b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 173b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include <array> 183b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include <cstdint> 193b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include <cstring> 203b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include <memory> 213b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include <utility> 223b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 233b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include "android-base/logging.h" 243b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 253b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include "wifilogd/main_loop.h" 263b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal#include "wifilogd/protocol.h" 273b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 283b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawalnamespace android { 293b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawalnamespace wifilogd { 303b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 313b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawalnamespace { 323b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawalconstexpr auto kMainBufferSizeBytes = 128 * 1024; 33fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal// TODO(b/32840641): Tune the sleep time. 34fd59221459953a821b9021e00276749ac46ea5eamukesh agrawalconstexpr auto kTransientErrorSleepTimeNsec = 100 * 1000; // 100 usec 353b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal} 363b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 373b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawalMainLoop::MainLoop(const std::string& socket_name) 383b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal : MainLoop(socket_name, std::make_unique<Os>(), 393b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal std::make_unique<CommandProcessor>(kMainBufferSizeBytes)) {} 403b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 413b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawalMainLoop::MainLoop(const std::string& socket_name, std::unique_ptr<Os> os, 423b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal std::unique_ptr<CommandProcessor> command_processor) 433b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal : os_(std::move(os)), command_processor_(std::move(command_processor)) { 443b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal Os::Errno err; 453b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal std::tie(sock_fd_, err) = os_->GetControlSocket(socket_name); 463b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal if (err) { 473b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal LOG(FATAL) << "Failed to get control socket: " << std::strerror(errno); 483b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal } 493b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal} 503b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 513b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawalvoid MainLoop::RunOnce() { 523b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal std::array<uint8_t, protocol::kMaxMessageSize> input_buf; 533b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal size_t datagram_len; 543b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal Os::Errno err; 553b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal std::tie(datagram_len, err) = 563b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal os_->ReceiveDatagram(sock_fd_, input_buf.data(), input_buf.size()); 573b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal if (err) { 58fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal ProcessError(err); 593b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal return; 603b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal } 613b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 623b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal if (datagram_len > protocol::kMaxMessageSize) { 633b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal // TODO(b/32098735): Increment stats counter. 643b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal datagram_len = protocol::kMaxMessageSize; 653b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal } 663b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 673b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal command_processor_->ProcessCommand(input_buf.data(), datagram_len, 683b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal Os::kInvalidFd); 693b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal} 703b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal 71fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal// Private methods below. 72fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal 73fd59221459953a821b9021e00276749ac46ea5eamukesh agrawalvoid MainLoop::ProcessError(Os::Errno err) { 74fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal if (err == EINTR || err == ENOMEM) { 75fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal // TODO(b/32098735): Increment stats counter. 76fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal os_->Nanosleep(kTransientErrorSleepTimeNsec); 77fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal return; 78fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal } 79fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal 80fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal // Any other error is unexpected, and assumed to be non-recoverable. 81fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal // (If, e.g., our socket is in a bad state, then we won't be able to receive 82fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal // any new log messages.) 83fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal LOG(FATAL) << "Unexpected error: " << std::strerror(err); 84fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal} 85fd59221459953a821b9021e00276749ac46ea5eamukesh agrawal 863b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal} // namespace wifilogd 873b1d20a5720a5fe6b0a1eccd577b0d2447139efcmukesh agrawal} // namespace android 88