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/webrtc_operator/device_handler.h"
17 
18 #include <android-base/logging.h>
19 
20 #include "host/frontend/webrtc_operator/client_handler.h"
21 #include "host/frontend/webrtc_operator/constants/signaling_constants.h"
22 
23 namespace cuttlefish {
24 
DeviceHandler(struct lws * wsi,DeviceRegistry * registry,const ServerConfig & server_config)25 DeviceHandler::DeviceHandler(struct lws* wsi, DeviceRegistry* registry,
26                              const ServerConfig& server_config)
27     : SignalHandler(wsi, registry, server_config), device_info_(), clients_() {}
28 
OnClosed()29 void DeviceHandler::OnClosed() {
30   if (!device_id_.empty() && registry_) {
31     registry_->UnRegisterDevice(device_id_);
32   }
33 }
34 
RegisterClient(std::shared_ptr<ClientHandler> client_handler)35 size_t DeviceHandler::RegisterClient(
36     std::shared_ptr<ClientHandler> client_handler) {
37   clients_.emplace_back(client_handler);
38   return clients_.size();
39 }
40 
handleMessage(const std::string & type,const Json::Value & message)41 void DeviceHandler::handleMessage(const std::string& type,
42                                   const Json::Value& message) {
43   if (type == webrtc_signaling::kRegisterType) {
44     HandleRegistrationRequest(message);
45   } else if (type == webrtc_signaling::kForwardType) {
46     HandleForward(message);
47   } else {
48     LogAndReplyError("Unknown message type: " + type);
49   }
50 }
51 
HandleRegistrationRequest(const Json::Value & message)52 void DeviceHandler::HandleRegistrationRequest(const Json::Value& message) {
53   if (!device_id_.empty()) {
54     LogAndReplyError("Device already registered: " + device_id_);
55     Close();
56     return;
57   }
58   if (!message.isMember(webrtc_signaling::kDeviceIdField) ||
59       !message[webrtc_signaling::kDeviceIdField].isString() ||
60       message[webrtc_signaling::kDeviceIdField].asString().empty()) {
61     LogAndReplyError("Missing device id in registration request");
62     Close();
63     return;
64   }
65   device_id_ = message[webrtc_signaling::kDeviceIdField].asString();
66   if (message.isMember(webrtc_signaling::kDeviceInfoField)) {
67     device_info_ = message[webrtc_signaling::kDeviceInfoField];
68   }
69   if (!registry_->RegisterDevice(device_id_, weak_from_this())) {
70     LOG(ERROR) << "Device registration failed";
71     Close();
72     return;
73   }
74 
75   SendServerConfig();
76 }
77 
HandleForward(const Json::Value & message)78 void DeviceHandler::HandleForward(const Json::Value& message) {
79   if (!message.isMember(webrtc_signaling::kClientIdField) ||
80       !message[webrtc_signaling::kClientIdField].isInt()) {
81     LogAndReplyError("Forward failed: Missing or invalid client id");
82     Close();
83     return;
84   }
85   size_t client_id = message[webrtc_signaling::kClientIdField].asInt();
86   if (!message.isMember(webrtc_signaling::kPayloadField)) {
87     LogAndReplyError("Forward failed: Missing payload");
88     Close();
89     return;
90   }
91   if (client_id <= 0 || client_id > clients_.size()) {
92     LogAndReplyError("Forward failed: Unknown client " +
93                      std::to_string(client_id));
94     return;
95   }
96   auto client_index = client_id - 1;
97   auto client_handler = clients_[client_index].lock();
98   if (!client_handler) {
99     SendClientDisconnectMessage(client_id);
100     return;
101   }
102   client_handler->SendDeviceMessage(message[webrtc_signaling::kPayloadField]);
103   return;
104 }
105 
SendClientMessage(size_t client_id,const Json::Value & client_message)106 void DeviceHandler::SendClientMessage(size_t client_id,
107                                       const Json::Value& client_message) {
108   Json::Value msg;
109   msg[webrtc_signaling::kTypeField] = webrtc_signaling::kClientMessageType;
110   msg[webrtc_signaling::kClientIdField] = static_cast<Json::UInt>(client_id);
111   msg[webrtc_signaling::kPayloadField] = client_message;
112   Reply(msg);
113 }
114 
SendClientDisconnectMessage(size_t client_id)115 void DeviceHandler::SendClientDisconnectMessage(size_t client_id) {
116   Json::Value msg;
117   msg[webrtc_signaling::kTypeField] = webrtc_signaling::kClientDisconnectType;
118   msg[webrtc_signaling::kClientIdField] = static_cast<Json::UInt>(client_id);
119   Reply(msg);
120 }
121 
DeviceHandlerFactory(DeviceRegistry * registry,const ServerConfig & server_config)122 DeviceHandlerFactory::DeviceHandlerFactory(DeviceRegistry* registry,
123                                            const ServerConfig& server_config)
124   : registry_(registry),
125     server_config_(server_config) {}
126 
Build(struct lws * wsi)127 std::shared_ptr<WebSocketHandler> DeviceHandlerFactory::Build(struct lws* wsi) {
128   return std::shared_ptr<WebSocketHandler>(
129       new DeviceHandler(wsi, registry_, server_config_));
130 }
131 }  // namespace cuttlefish
132