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/signal_handler.h"
17 
18 #include <android-base/logging.h>
19 #include <json/json.h>
20 
21 #include "host/frontend/gcastv2/signaling_server/constants/signaling_constants.h"
22 
23 namespace cuttlefish {
24 
SignalHandler(DeviceRegistry * registry,const ServerConfig & server_config)25 SignalHandler::SignalHandler(DeviceRegistry* registry,
26                              const ServerConfig& server_config)
27     : registry_(registry), server_config_(server_config) {}
28 
IsBinaryMessage(uint8_t header_byte)29 bool SignalHandler::IsBinaryMessage(uint8_t header_byte) {
30   // https://tools.ietf.org/html/rfc6455#section-5.2
31   return (header_byte & 0x0f) == 0x02;
32 }
33 
handleMessage(uint8_t header_byte,const uint8_t * msg,size_t len)34 int SignalHandler::handleMessage(uint8_t header_byte, const uint8_t* msg,
35                                  size_t len) {
36   if (IsBinaryMessage(header_byte)) {
37     LOG(ERROR) << "Received a binary message";
38     return -EINVAL;
39   }
40   Json::Value json_message;
41   Json::Reader json_reader;
42   auto str = reinterpret_cast<const char*>(msg);
43   if (!json_reader.parse(str, str + len, json_message)) {
44     LOG(ERROR) << "Received Invalid JSON";
45     // Rate limiting would be a good idea here
46     return -EINVAL;
47   }
48   if (!json_message.isMember(webrtc_signaling::kTypeField) ||
49       !json_message[webrtc_signaling::kTypeField].isString()) {
50     LogAndReplyError("Invalid message format: '" + std::string(msg, msg + len) +
51                      "'");
52     // Rate limiting would be a good idea here
53     return -EINVAL;
54   }
55 
56   auto type = json_message[webrtc_signaling::kTypeField].asString();
57   return handleMessage(type, json_message);
58 }
59 
SendServerConfig()60 void SignalHandler::SendServerConfig() {
61   // Call every time to allow config changes?
62   auto reply = server_config_.ToJson();
63   reply[webrtc_signaling::kTypeField] = webrtc_signaling::kConfigType;
64   Reply(reply);
65 }
66 
LogAndReplyError(const std::string & error_message)67 void SignalHandler::LogAndReplyError(const std::string& error_message) {
68   LOG(ERROR) << error_message;
69   auto reply_str = "{\"error\":\"" + error_message + "\"}";
70   sendMessage(reply_str.c_str(), reply_str.size());
71 }
72 
Reply(const Json::Value & json)73 void SignalHandler::Reply(const Json::Value& json) {
74   Json::FastWriter json_writer;
75   auto replyAsString = json_writer.write(json);
76   sendMessage(replyAsString.c_str(), replyAsString.size());
77 }
78 
79 }  // namespace cuttlefish
80