blob: 4798e383c7d1fcf219e71bb25136e0a1eed087b6 [file] [log] [blame]
Garrick Evans96e03042019-05-28 14:30:52 +09001// Copyright 2016 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "arc/network/message_dispatcher.h"
6
7#include <utility>
8#include <vector>
9
10#include <base/bind.h>
11#include <base/files/scoped_file.h>
12#include <base/logging.h>
13#include <base/posix/unix_domain_socket_linux.h>
14
15namespace arc_networkd {
16
17MessageDispatcher::MessageDispatcher(base::ScopedFD fd)
18 : fd_(std::move(fd)), watcher_(FROM_HERE) {
19 base::MessageLoopForIO::current()->WatchFileDescriptor(
20 fd_.get(), true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
21}
22
23void MessageDispatcher::RegisterFailureHandler(
24 const base::Callback<void()>& handler) {
25 failure_handler_ = handler;
26}
27
28void MessageDispatcher::RegisterGuestMessageHandler(
29 const base::Callback<void(const GuestMessage&)>& handler) {
30 guest_handler_ = handler;
31}
32
33void MessageDispatcher::RegisterDeviceMessageHandler(
34 const base::Callback<void(const DeviceMessage&)>& handler) {
35 device_handler_ = handler;
36}
37
38void MessageDispatcher::OnFileCanReadWithoutBlocking(int fd) {
39 CHECK_EQ(fd, fd_.get());
40
41 char buffer[1024];
42 std::vector<base::ScopedFD> fds{};
43 ssize_t len =
44 base::UnixDomainSocket::RecvMsg(fd, buffer, sizeof(buffer), &fds);
45
46 if (len <= 0) {
47 PLOG(ERROR) << "Read failed: exiting";
48 watcher_.StopWatchingFileDescriptor();
49 if (!failure_handler_.is_null())
50 failure_handler_.Run();
51 return;
52 }
53
54 msg_.Clear();
55 if (!msg_.ParseFromArray(buffer, len)) {
56 LOG(ERROR) << "Error parsing protobuf";
57 return;
58 }
59
60 if (msg_.has_guest_message() && !guest_handler_.is_null()) {
61 guest_handler_.Run(msg_.guest_message());
62 }
63
64 if (msg_.has_device_message() && !device_handler_.is_null()) {
65 device_handler_.Run(msg_.device_message());
66 }
67}
68
69} // namespace arc_networkd