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