You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.2 KiB
132 lines
4.2 KiB
//
|
|
// Copyright (C) 2021 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "common/libs/confui/packet.h"
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
|
|
#include <android-base/logging.h>
|
|
#include <android-base/strings.h>
|
|
|
|
#include "common/libs/confui/protocol.h"
|
|
#include "common/libs/confui/utils.h"
|
|
#include "common/libs/fs/shared_buf.h"
|
|
|
|
namespace cuttlefish {
|
|
namespace confui {
|
|
namespace packet {
|
|
ConfUiMessage PayloadToConfUiMessage(const std::string& str_to_parse) {
|
|
auto tokens = android::base::Split(str_to_parse, ":");
|
|
ConfUiCheck(tokens.size() >= 3)
|
|
<< "PayloadToConfUiMessage takes \"" + str_to_parse + "\""
|
|
<< "and does not have 3 tokens";
|
|
std::string msg;
|
|
std::for_each(tokens.begin() + 2, tokens.end() - 1,
|
|
[&msg](auto& token) { msg.append(token + ":"); });
|
|
msg.append(*tokens.rbegin());
|
|
return {tokens[0], tokens[1], msg};
|
|
}
|
|
|
|
// Use only this function to make a packet to send over the confirmation
|
|
// ui packet layer
|
|
template <typename... Args>
|
|
static Payload ToPayload(const ConfUiCmd cmd, const std::string& session_id,
|
|
Args&&... args) {
|
|
std::string cmd_str = ToString(cmd);
|
|
std::string msg =
|
|
ArgsToString(session_id, ":", cmd_str, ":", std::forward<Args>(args)...);
|
|
PayloadHeader header;
|
|
header.payload_length_ = msg.size();
|
|
return {header, msg};
|
|
}
|
|
|
|
template <typename... Args>
|
|
static bool WritePayload(SharedFD d, const ConfUiCmd cmd,
|
|
const std::string& session_id, Args&&... args) {
|
|
if (!d->IsOpen()) {
|
|
LOG(ERROR) << "file, socket, etc, is not open to write";
|
|
return false;
|
|
}
|
|
auto [payload, msg] = ToPayload(cmd, session_id, std::forward<Args>(args)...);
|
|
|
|
auto nwrite =
|
|
WriteAll(d, reinterpret_cast<const char*>(&payload), sizeof(payload));
|
|
if (nwrite != sizeof(payload)) {
|
|
return false;
|
|
}
|
|
nwrite = cuttlefish::WriteAll(d, msg.c_str(), msg.size());
|
|
if (nwrite != msg.size()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static std::optional<ConfUiMessage> ReadPayload(SharedFD s) {
|
|
if (!s->IsOpen()) {
|
|
LOG(ERROR) << "file, socket, etc, is not open to read";
|
|
return std::nullopt;
|
|
}
|
|
PayloadHeader p;
|
|
auto nread = ReadExactBinary(s, &p);
|
|
|
|
if (nread != sizeof(p)) {
|
|
return std::nullopt;
|
|
}
|
|
|
|
if (p.payload_length_ == 0) {
|
|
return {{SESSION_ANY, ToString(ConfUiCmd::kUnknown), std::string{""}}};
|
|
}
|
|
|
|
if (p.payload_length_ >= kMaxPayloadLength) {
|
|
LOG(ERROR) << "Payload length must be less than " << kMaxPayloadLength;
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::unique_ptr<char[]> buf{new char[p.payload_length_ + 1]};
|
|
nread = ReadExact(s, buf.get(), p.payload_length_);
|
|
buf[p.payload_length_] = 0;
|
|
if (nread != p.payload_length_) {
|
|
return std::nullopt;
|
|
}
|
|
std::string msg_to_parse{buf.get()};
|
|
auto [session_id, type, contents] = PayloadToConfUiMessage(msg_to_parse);
|
|
return {{session_id, type, contents}};
|
|
}
|
|
|
|
std::optional<ConfUiMessage> RecvConfUiMsg(SharedFD fd) {
|
|
return ReadPayload(fd);
|
|
}
|
|
|
|
bool SendCmd(SharedFD fd, const std::string& session_id, ConfUiCmd cmd,
|
|
const std::string& additional_info) {
|
|
return WritePayload(fd, cmd, session_id, additional_info);
|
|
}
|
|
|
|
bool SendAck(SharedFD fd, const std::string& session_id, const bool is_success,
|
|
const std::string& additional_info) {
|
|
return WritePayload(fd, ConfUiCmd::kCliAck, session_id,
|
|
ToCliAckMessage(is_success, additional_info));
|
|
}
|
|
|
|
bool SendResponse(SharedFD fd, const std::string& session_id,
|
|
const std::string& additional_info) {
|
|
return WritePayload(fd, ConfUiCmd::kCliRespond, session_id, additional_info);
|
|
}
|
|
|
|
} // end of namespace packet
|
|
} // end of namespace confui
|
|
} // end of namespace cuttlefish
|