/* * Copyright (C) 2020 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 "host/libs/allocd/utils.h" #include #include #include "common/libs/fs/shared_buf.h" #include "common/libs/fs/shared_fd.h" #include "host/libs/allocd/request.h" namespace cuttlefish { // While the JSON schema and payload structure are designed to be extensible, // and avoid version incompatibility. However, should project requirements // change, it is necessary that we have a mechanism to handle incompatibilities // that arise over time. If an incompatibility should come about, the // kMinHeaderVersion constant should be increased to match the new minimal set // of features that are supported. /// Current supported Header version number constexpr uint16_t kCurHeaderVersion = 1; /// Oldest compatible header version number constexpr uint16_t kMinHeaderVersion = 1; const std::map RequestTyToStrMap = { {RequestType::ID, "alloc_id"}, {RequestType::CreateInterface, "create_interface"}, {RequestType::DestroyInterface, "destroy_interface"}, {RequestType::StopSession, "stop_session"}, {RequestType::Shutdown, "shutdown"}, {RequestType::Invalid, "invalid"}}; const std::map StrToRequestTyMap = { {"alloc_id", RequestType::ID}, {"create_interface", RequestType::CreateInterface}, {"destroy_interface", RequestType::DestroyInterface}, {"stop_session", RequestType::StopSession}, {"shutdown", RequestType::Shutdown}, {"invalid", RequestType::Invalid}}; const std::map StrToIfaceTyMap = { {"invalid", IfaceType::Invalid}, {"mtap", IfaceType::mtap}, {"wtap", IfaceType::wtap}, {"etap", IfaceType::etap}, {"wbr", IfaceType::wbr}, {"ebr", IfaceType::ebr}}; const std::map IfaceTyToStrMap = { {IfaceType::Invalid, "invalid"}, {IfaceType::mtap, "mtap"}, {IfaceType::wtap, "wtap"}, {IfaceType::etap, "etap"}, {IfaceType::wbr, "wbr"}, {IfaceType::ebr, "ebr"}}; const std::map ReqStatusToStrMap = { {RequestStatus::Invalid, "invalid"}, {RequestStatus::Pending, "pending"}, {RequestStatus::Failure, "failure"}, {RequestStatus::Success, "success"}}; const std::map StrToReqStatusMap = { {"invalid", RequestStatus::Invalid}, {"pending", RequestStatus::Pending}, {"failure", RequestStatus::Failure}, {"success", RequestStatus::Success}}; bool SendJsonMsg(SharedFD client_socket, const Json::Value& resp) { LOG(INFO) << "Sending JSON message"; Json::StreamWriterBuilder factory; auto resp_str = Json::writeString(factory, resp); std::string header_buff(sizeof(RequestHeader), 0); // fill in header RequestHeader* header = reinterpret_cast(header_buff.data()); header->len = resp_str.size(); header->version = kCurHeaderVersion; auto payload = header_buff + resp_str; return SendAll(client_socket, payload); } std::optional RecvJsonMsg(SharedFD client_socket) { LOG(INFO) << "Receiving JSON message"; RequestHeader header; client_socket->Recv(&header, sizeof(header), kRecvFlags); if (header.version < kMinHeaderVersion) { LOG(WARNING) << "bad request header version: " << header.version; return std::nullopt; } std::string payload = RecvAll(client_socket, header.len); JsonRequestReader reader; return reader.parse(payload); } std::string ReqTyToStr(RequestType req_ty) { switch (req_ty) { case RequestType::Invalid: return "invalid"; case RequestType::Shutdown: return "shutdown"; case RequestType::StopSession: return "stop_session"; case RequestType::DestroyInterface: return "destroy_interface"; case RequestType::CreateInterface: return "create_interface"; case RequestType::ID: return "id"; } } RequestType StrToReqTy(const std::string& req) { auto it = StrToRequestTyMap.find(req); if (it == StrToRequestTyMap.end()) { return RequestType::Invalid; } else { return it->second; } } RequestStatus StrToStatus(const std::string& st) { auto it = StrToReqStatusMap.find(st); if (it == StrToReqStatusMap.end()) { return RequestStatus::Invalid; } else { return it->second; } } std::string StatusToStr(RequestStatus st) { switch (st) { case RequestStatus::Invalid: return "invalid"; case RequestStatus::Pending: return "pending"; case RequestStatus::Success: return "success"; case RequestStatus::Failure: return "failure"; } } std::string IfaceTyToStr(IfaceType iface) { switch (iface) { case IfaceType::Invalid: return "invalid"; case IfaceType::mtap: return "mtap"; case IfaceType::wtap: return "wtap"; case IfaceType::etap: return "etap"; case IfaceType::wbr: return "wbr"; case IfaceType::ebr: return "ebr"; } } IfaceType StrToIfaceTy(const std::string& iface) { auto it = StrToIfaceTyMap.find(iface); if (it == StrToIfaceTyMap.end()) { return IfaceType::Invalid; } else { return it->second; } } } // namespace cuttlefish