• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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},
59     {"mtap", IfaceType::mtap},
60     {"wtap", IfaceType::wtap},
61     {"etap", IfaceType::etap},
62     {"wbr", IfaceType::wbr},
63     {"ebr", IfaceType::ebr}};
64 
65 const std::map<IfaceType, std::string> IfaceTyToStrMap = {
66     {IfaceType::Invalid, "invalid"},
67     {IfaceType::mtap, "mtap"},
68     {IfaceType::wtap, "wtap"},
69     {IfaceType::etap, "etap"},
70     {IfaceType::wbr, "wbr"},
71     {IfaceType::ebr, "ebr"}};
72 
73 const std::map<RequestStatus, std::string> ReqStatusToStrMap = {
74     {RequestStatus::Invalid, "invalid"},
75     {RequestStatus::Pending, "pending"},
76     {RequestStatus::Failure, "failure"},
77     {RequestStatus::Success, "success"}};
78 
79 const std::map<std::string, RequestStatus> StrToReqStatusMap = {
80     {"invalid", RequestStatus::Invalid},
81     {"pending", RequestStatus::Pending},
82     {"failure", RequestStatus::Failure},
83     {"success", RequestStatus::Success}};
84 
SendJsonMsg(SharedFD client_socket,const Json::Value & resp)85 bool SendJsonMsg(SharedFD client_socket, const Json::Value& resp) {
86   LOG(INFO) << "Sending JSON message";
87   Json::StreamWriterBuilder factory;
88   auto resp_str = Json::writeString(factory, resp);
89 
90   std::string header_buff(sizeof(RequestHeader), 0);
91 
92   // fill in header
93   RequestHeader* header = reinterpret_cast<RequestHeader*>(header_buff.data());
94   header->len = resp_str.size();
95   header->version = kCurHeaderVersion;
96 
97   auto payload = header_buff + resp_str;
98 
99   return SendAll(client_socket, payload);
100 }
101 
RecvJsonMsg(SharedFD client_socket)102 std::optional<Json::Value> RecvJsonMsg(SharedFD client_socket) {
103   LOG(INFO) << "Receiving JSON message";
104   RequestHeader header;
105   client_socket->Recv(&header, sizeof(header), kRecvFlags);
106 
107   if (header.version < kMinHeaderVersion) {
108     LOG(WARNING) << "bad request header version: " << header.version;
109     return std::nullopt;
110   }
111 
112   std::string payload = RecvAll(client_socket, header.len);
113 
114   JsonRequestReader reader;
115   return reader.parse(payload);
116 }
117 
ReqTyToStr(RequestType req_ty)118 std::string ReqTyToStr(RequestType req_ty) {
119   switch (req_ty) {
120     case RequestType::Invalid:
121       return "invalid";
122     case RequestType::Shutdown:
123       return "shutdown";
124     case RequestType::StopSession:
125       return "stop_session";
126     case RequestType::DestroyInterface:
127       return "destroy_interface";
128     case RequestType::CreateInterface:
129       return "create_interface";
130     case RequestType::ID:
131       return "id";
132   }
133 }
134 
StrToReqTy(const std::string & req)135 RequestType StrToReqTy(const std::string& req) {
136   auto it = StrToRequestTyMap.find(req);
137   if (it == StrToRequestTyMap.end()) {
138     return RequestType::Invalid;
139   } else {
140     return it->second;
141   }
142 }
143 
StrToStatus(const std::string & st)144 RequestStatus StrToStatus(const std::string& st) {
145   auto it = StrToReqStatusMap.find(st);
146   if (it == StrToReqStatusMap.end()) {
147     return RequestStatus::Invalid;
148   } else {
149     return it->second;
150   }
151 }
152 
StatusToStr(RequestStatus st)153 std::string StatusToStr(RequestStatus st) {
154   switch (st) {
155     case RequestStatus::Invalid:
156       return "invalid";
157     case RequestStatus::Pending:
158       return "pending";
159     case RequestStatus::Success:
160       return "success";
161     case RequestStatus::Failure:
162       return "failure";
163   }
164 }
165 
IfaceTyToStr(IfaceType iface)166 std::string IfaceTyToStr(IfaceType iface) {
167   switch (iface) {
168     case IfaceType::Invalid:
169       return "invalid";
170     case IfaceType::mtap:
171       return "mtap";
172     case IfaceType::wtap:
173       return "wtap";
174     case IfaceType::etap:
175       return "etap";
176     case IfaceType::wbr:
177       return "wbr";
178     case IfaceType::ebr:
179       return "ebr";
180   }
181 }
182 
StrToIfaceTy(const std::string & iface)183 IfaceType StrToIfaceTy(const std::string& iface) {
184   auto it = StrToIfaceTyMap.find(iface);
185   if (it == StrToIfaceTyMap.end()) {
186     return IfaceType::Invalid;
187   } else {
188     return it->second;
189   }
190 }
191 
192 }  // namespace cuttlefish
193