• 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}, {"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