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/device_handler.h"
17
18 #include <android-base/logging.h>
19
20 #include "host/frontend/gcastv2/signaling_server/client_handler.h"
21 #include "host/frontend/gcastv2/signaling_server/constants/signaling_constants.h"
22
23 namespace cuttlefish {
24
DeviceHandler(DeviceRegistry * registry,const ServerConfig & server_config)25 DeviceHandler::DeviceHandler(DeviceRegistry* registry,
26 const ServerConfig& server_config)
27 : SignalHandler(registry, server_config), device_info_(), clients_() {}
28
~DeviceHandler()29 DeviceHandler::~DeviceHandler() {
30 // Unregister the device when the websocket connection is closed
31 if (!device_id_.empty() && registry_) {
32 registry_->UnRegisterDevice(device_id_);
33 }
34 }
35
RegisterClient(std::shared_ptr<ClientHandler> client_handler)36 size_t DeviceHandler::RegisterClient(
37 std::shared_ptr<ClientHandler> client_handler) {
38 clients_.emplace_back(client_handler);
39 return clients_.size();
40 }
41
handleMessage(const std::string & type,const Json::Value & message)42 int DeviceHandler::handleMessage(const std::string& type,
43 const Json::Value& message) {
44 if (type == webrtc_signaling::kRegisterType) {
45 return HandleRegistrationRequest(message);
46 } else if (type == webrtc_signaling::kForwardType) {
47 return HandleForward(message);
48 } else {
49 LogAndReplyError("Unknown message type: " + type);
50 }
51
52 return 0;
53 }
54
HandleRegistrationRequest(const Json::Value & message)55 int DeviceHandler::HandleRegistrationRequest(const Json::Value& message) {
56 if (!device_id_.empty()) {
57 LogAndReplyError("Device already registered: " + device_id_);
58 return -EINVAL;
59 }
60 if (!message.isMember(webrtc_signaling::kDeviceIdField) ||
61 !message[webrtc_signaling::kDeviceIdField].isString() ||
62 message[webrtc_signaling::kDeviceIdField].asString().empty()) {
63 LogAndReplyError("Missing device id in registration request");
64 return -EINVAL;
65 }
66 device_id_ = message[webrtc_signaling::kDeviceIdField].asString();
67 if (message.isMember(webrtc_signaling::kDeviceInfoField)) {
68 device_info_ = message[webrtc_signaling::kDeviceInfoField];
69 }
70 if (!registry_->RegisterDevice(device_id_, weak_from_this())) {
71 LOG(ERROR) << "Device registration failed";
72 return -1;
73 }
74
75 SendServerConfig();
76
77 return 0;
78 }
79
HandleForward(const Json::Value & message)80 int DeviceHandler::HandleForward(const Json::Value& message) {
81 if (!message.isMember(webrtc_signaling::kClientIdField) || !message[webrtc_signaling::kClientIdField].isInt()) {
82 LogAndReplyError("Forward failed: Missing or invalid client id");
83 return 0;
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 return 0;
89 }
90 if (client_id > clients_.size()) {
91 LogAndReplyError("Forward failed: Unknown client " +
92 std::to_string(client_id));
93 return 0;
94 }
95 auto client_index = client_id - 1;
96 auto client_handler = clients_[client_index].lock();
97 if (!client_handler) {
98 LogAndReplyError("Forward failed: Client " + std::to_string(client_id) +
99 " disconnected");
100 return 0;
101 }
102 client_handler->SendDeviceMessage(message[webrtc_signaling::kPayloadField]);
103 return 0;
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
115 } // namespace cuttlefish
116