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 17 #include "host/libs/allocd/utils.h" 18 19 #include <cstdint> 20 #include <optional> 21 22 #include "common/libs/fs/shared_buf.h" 23 #include "common/libs/fs/shared_fd.h" 24 #include "host/libs/allocd/request.h" 25 26 namespace cuttlefish { 27 28 // While the JSON schema and payload structure are designed to be extensible, 29 // and avoid version incompatibility. However, should project requirements 30 // change, it is necessary that we have a mechanism to handle incompatibilities 31 // that arise over time. If an incompatibility should come about, the 32 // kMinHeaderVersion constant should be increased to match the new minimal set 33 // of features that are supported. 34 35 /// Current supported Header version number 36 constexpr uint16_t kCurHeaderVersion = 1; 37 38 /// Oldest compatible header version number 39 constexpr uint16_t kMinHeaderVersion = 1; 40 41 const std::map<RequestType, const char*> RequestTyToStrMap = { 42 {RequestType::ID, "alloc_id"}, 43 {RequestType::CreateInterface, "create_interface"}, 44 {RequestType::DestroyInterface, "destroy_interface"}, 45 {RequestType::StopSession, "stop_session"}, 46 {RequestType::Shutdown, "shutdown"}, 47 {RequestType::Invalid, "invalid"}}; 48 49 const std::map<std::string, RequestType> StrToRequestTyMap = { 50 {"alloc_id", RequestType::ID}, 51 {"create_interface", RequestType::CreateInterface}, 52 {"destroy_interface", RequestType::DestroyInterface}, 53 {"stop_session", RequestType::StopSession}, 54 {"shutdown", RequestType::Shutdown}, 55 {"invalid", RequestType::Invalid}}; 56 57 const std::map<std::string, IfaceType> StrToIfaceTyMap = { 58 {"invalid", IfaceType::Invalid}, {"mtap", IfaceType::mtap}, 59 {"wtap", IfaceType::wtap}, {"wifiap", IfaceType::wifiap}, 60 {"etap", IfaceType::etap}, {"wbr", IfaceType::wbr}, 61 {"ebr", IfaceType::ebr}}; 62 63 const std::map<IfaceType, std::string> IfaceTyToStrMap = { 64 {IfaceType::Invalid, "invalid"}, {IfaceType::mtap, "mtap"}, 65 {IfaceType::wtap, "wtap"}, {IfaceType::wifiap, "wifiap"}, 66 {IfaceType::etap, "etap"}, {IfaceType::wbr, "wbr"}, 67 {IfaceType::ebr, "ebr"}}; 68 69 const std::map<RequestStatus, std::string> ReqStatusToStrMap = { 70 {RequestStatus::Invalid, "invalid"}, 71 {RequestStatus::Pending, "pending"}, 72 {RequestStatus::Failure, "failure"}, 73 {RequestStatus::Success, "success"}}; 74 75 const std::map<std::string, RequestStatus> StrToReqStatusMap = { 76 {"invalid", RequestStatus::Invalid}, 77 {"pending", RequestStatus::Pending}, 78 {"failure", RequestStatus::Failure}, 79 {"success", RequestStatus::Success}}; 80 SendJsonMsg(SharedFD client_socket,const Json::Value & resp)81 bool SendJsonMsg(SharedFD client_socket, const Json::Value& resp) { 82 LOG(INFO) << "Sending JSON message"; 83 Json::StreamWriterBuilder factory; 84 auto resp_str = Json::writeString(factory, resp); 85 86 std::string header_buff(sizeof(RequestHeader), 0); 87 88 // fill in header 89 RequestHeader* header = reinterpret_cast<RequestHeader*>(header_buff.data()); 90 header->len = resp_str.size(); 91 header->version = kCurHeaderVersion; 92 93 auto payload = header_buff + resp_str; 94 95 return SendAll(client_socket, payload); 96 } 97 RecvJsonMsg(SharedFD client_socket)98 std::optional<Json::Value> RecvJsonMsg(SharedFD client_socket) { 99 LOG(INFO) << "Receiving JSON message"; 100 RequestHeader header; 101 client_socket->Recv(&header, sizeof(header), kRecvFlags); 102 103 if (header.version < kMinHeaderVersion) { 104 LOG(WARNING) << "bad request header version: " << header.version; 105 return std::nullopt; 106 } 107 108 std::string payload = RecvAll(client_socket, header.len); 109 110 JsonRequestReader reader; 111 return reader.parse(payload); 112 } 113 ReqTyToStr(RequestType req_ty)114 std::string ReqTyToStr(RequestType req_ty) { 115 switch (req_ty) { 116 case RequestType::Invalid: 117 return "invalid"; 118 case RequestType::Shutdown: 119 return "shutdown"; 120 case RequestType::StopSession: 121 return "stop_session"; 122 case RequestType::DestroyInterface: 123 return "destroy_interface"; 124 case RequestType::CreateInterface: 125 return "create_interface"; 126 case RequestType::ID: 127 return "id"; 128 } 129 } 130 StrToReqTy(const std::string & req)131 RequestType StrToReqTy(const std::string& req) { 132 auto it = StrToRequestTyMap.find(req); 133 if (it == StrToRequestTyMap.end()) { 134 return RequestType::Invalid; 135 } else { 136 return it->second; 137 } 138 } 139 StrToStatus(const std::string & st)140 RequestStatus StrToStatus(const std::string& st) { 141 auto it = StrToReqStatusMap.find(st); 142 if (it == StrToReqStatusMap.end()) { 143 return RequestStatus::Invalid; 144 } else { 145 return it->second; 146 } 147 } 148 StatusToStr(RequestStatus st)149 std::string StatusToStr(RequestStatus st) { 150 switch (st) { 151 case RequestStatus::Invalid: 152 return "invalid"; 153 case RequestStatus::Pending: 154 return "pending"; 155 case RequestStatus::Success: 156 return "success"; 157 case RequestStatus::Failure: 158 return "failure"; 159 } 160 } 161 IfaceTyToStr(IfaceType iface)162 std::string IfaceTyToStr(IfaceType iface) { 163 switch (iface) { 164 case IfaceType::Invalid: 165 return "invalid"; 166 case IfaceType::mtap: 167 return "mtap"; 168 case IfaceType::wtap: 169 return "wtap"; 170 case IfaceType::wifiap: 171 return "wifiap"; 172 case IfaceType::etap: 173 return "etap"; 174 case IfaceType::wbr: 175 return "wbr"; 176 case IfaceType::ebr: 177 return "ebr"; 178 } 179 } 180 StrToIfaceTy(const std::string & iface)181 IfaceType StrToIfaceTy(const std::string& iface) { 182 auto it = StrToIfaceTyMap.find(iface); 183 if (it == StrToIfaceTyMap.end()) { 184 return IfaceType::Invalid; 185 } else { 186 return it->second; 187 } 188 } 189 190 } // namespace cuttlefish 191