| /* |
| * 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 <cstdint> |
| #include <optional> |
| |
| #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<RequestType, const char*> 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<std::string, RequestType> 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<std::string, IfaceType> StrToIfaceTyMap = { |
| {"invalid", IfaceType::Invalid}, |
| {"mtap", IfaceType::mtap}, |
| {"wtap", IfaceType::wtap}, |
| {"etap", IfaceType::etap}, |
| {"wbr", IfaceType::wbr}, |
| {"ebr", IfaceType::ebr}}; |
| |
| const std::map<IfaceType, std::string> IfaceTyToStrMap = { |
| {IfaceType::Invalid, "invalid"}, |
| {IfaceType::mtap, "mtap"}, |
| {IfaceType::wtap, "wtap"}, |
| {IfaceType::etap, "etap"}, |
| {IfaceType::wbr, "wbr"}, |
| {IfaceType::ebr, "ebr"}}; |
| |
| const std::map<RequestStatus, std::string> ReqStatusToStrMap = { |
| {RequestStatus::Invalid, "invalid"}, |
| {RequestStatus::Pending, "pending"}, |
| {RequestStatus::Failure, "failure"}, |
| {RequestStatus::Success, "success"}}; |
| |
| const std::map<std::string, RequestStatus> 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<RequestHeader*>(header_buff.data()); |
| header->len = resp_str.size(); |
| header->version = kCurHeaderVersion; |
| |
| auto payload = header_buff + resp_str; |
| |
| return SendAll(client_socket, payload); |
| } |
| |
| std::optional<Json::Value> 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 |