blob: 057c5707ac28a15735b55cce059b6235b4b39c99 [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>
Hidehiko Abede129222019-08-16 00:55:04 +090013#include <base/posix/unix_domain_socket.h>
Garrick Evans96e03042019-05-28 14:30:52 +090014
15namespace arc_networkd {
16
17MessageDispatcher::MessageDispatcher(base::ScopedFD fd)
Hidehiko Abede129222019-08-16 00:55:04 +090018 : fd_(std::move(fd)),
19 watcher_(base::FileDescriptorWatcher::WatchReadable(
20 fd_.get(),
21 base::BindRepeating(&MessageDispatcher::OnFileCanReadWithoutBlocking,
22 base::Unretained(this)))) {}
Garrick Evans96e03042019-05-28 14:30:52 +090023
24void MessageDispatcher::RegisterFailureHandler(
25 const base::Callback<void()>& handler) {
26 failure_handler_ = handler;
27}
28
29void MessageDispatcher::RegisterGuestMessageHandler(
30 const base::Callback<void(const GuestMessage&)>& handler) {
31 guest_handler_ = handler;
32}
33
34void MessageDispatcher::RegisterDeviceMessageHandler(
35 const base::Callback<void(const DeviceMessage&)>& handler) {
36 device_handler_ = handler;
37}
38
Hidehiko Abede129222019-08-16 00:55:04 +090039void MessageDispatcher::OnFileCanReadWithoutBlocking() {
Garrick Evans96e03042019-05-28 14:30:52 +090040 char buffer[1024];
41 std::vector<base::ScopedFD> fds{};
42 ssize_t len =
Hidehiko Abede129222019-08-16 00:55:04 +090043 base::UnixDomainSocket::RecvMsg(fd_.get(), buffer, sizeof(buffer), &fds);
Garrick Evans96e03042019-05-28 14:30:52 +090044
45 if (len <= 0) {
46 PLOG(ERROR) << "Read failed: exiting";
Hidehiko Abede129222019-08-16 00:55:04 +090047 watcher_.reset();
Garrick Evans96e03042019-05-28 14:30:52 +090048 if (!failure_handler_.is_null())
49 failure_handler_.Run();
50 return;
51 }
52
53 msg_.Clear();
54 if (!msg_.ParseFromArray(buffer, len)) {
55 LOG(ERROR) << "Error parsing protobuf";
56 return;
57 }
58
59 if (msg_.has_guest_message() && !guest_handler_.is_null()) {
60 guest_handler_.Run(msg_.guest_message());
61 }
62
63 if (msg_.has_device_message() && !device_handler_.is_null()) {
64 device_handler_.Run(msg_.device_message());
65 }
66}
67
68} // namespace arc_networkd