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