1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include "host/frontend/gcastv2/signaling_server/client_handler.h"
17
18 #include <android-base/logging.h>
19
20 #include "host/frontend/gcastv2/signaling_server/constants/signaling_constants.h"
21 #include "host/frontend/gcastv2/signaling_server/device_handler.h"
22
23 namespace cuttlefish {
24
ClientHandler(DeviceRegistry * registry,const ServerConfig & server_config)25 ClientHandler::ClientHandler(DeviceRegistry* registry,
26 const ServerConfig& server_config)
27 : SignalHandler(registry, server_config),
28 device_handler_(),
29 client_id_(0) {}
30
SendDeviceMessage(const Json::Value & device_message)31 void ClientHandler::SendDeviceMessage(const Json::Value& device_message) {
32 Json::Value message;
33 message[webrtc_signaling::kTypeField] = webrtc_signaling::kDeviceMessageType;
34 message[webrtc_signaling::kPayloadField] = device_message;
35 Reply(message);
36 }
37
handleMessage(const std::string & type,const Json::Value & message)38 int ClientHandler::handleMessage(const std::string& type,
39 const Json::Value& message) {
40 if (type == webrtc_signaling::kConnectType) {
41 return handleConnectionRequest(message);
42 } else if (type == webrtc_signaling::kForwardType) {
43 return handleForward(message);
44 } else {
45 LogAndReplyError("Unknown message type: " + type);
46 return -1;
47 }
48 }
49
handleConnectionRequest(const Json::Value & message)50 int ClientHandler::handleConnectionRequest(const Json::Value& message) {
51 if (client_id_ > 0) {
52 LOG(ERROR) << "Detected attempt to connect to multiple devices over same "
53 "websocket";
54 return -EINVAL;
55 }
56 if (!message.isMember(webrtc_signaling::kDeviceIdField) ||
57 !message[webrtc_signaling::kDeviceIdField].isString()) {
58 LogAndReplyError("Invalid connection request: Missing device id");
59 return -EINVAL;
60 }
61 auto device_id = message[webrtc_signaling::kDeviceIdField].asString();
62 // Always send the server config back, even if the requested device is not
63 // registered. Applications may put clients on hold until the device is ready
64 // to connect.
65 SendServerConfig();
66
67 auto device_handler = registry_->GetDevice(device_id);
68 if (!device_handler) {
69 LogAndReplyError("Connection failed: Device not found: '" + device_id +
70 "'");
71 return -1;
72 }
73
74 client_id_ = device_handler->RegisterClient(shared_from_this());
75 device_handler_ = device_handler;
76 Json::Value device_info_reply;
77 device_info_reply[webrtc_signaling::kTypeField] =
78 webrtc_signaling::kDeviceInfoType;
79 device_info_reply[webrtc_signaling::kDeviceInfoField] =
80 device_handler->device_info();
81 Reply(device_info_reply);
82 return 0;
83 }
84
handleForward(const Json::Value & message)85 int ClientHandler::handleForward(const Json::Value& message) {
86 if (client_id_ == 0) {
87 LogAndReplyError("Forward failed: No device asociated to client");
88 return 0;
89 }
90 if (!message.isMember(webrtc_signaling::kPayloadField)) {
91 LogAndReplyError("Forward failed: No payload present in message");
92 return 0;
93 }
94 auto device_handler = device_handler_.lock();
95 if (!device_handler) {
96 LogAndReplyError("Forward failed: Device disconnected");
97 // Disconnect this client since the device is gone
98 return -1;
99 }
100 device_handler->SendClientMessage(client_id_,
101 message[webrtc_signaling::kPayloadField]);
102 return 0;
103 }
104
105 } // namespace cuttlefish
106