• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 #pragma once
17 
18 #include <stdlib.h>
19 
20 #include <cutils/sockets.h>
21 #include <log/log.h>
22 
23 #include "common/libs/fs/shared_fd.h"
24 
25 // #define DEBUG_CONNECTIONS
26 
27 /*
28  * Packet structures for commands sent to the remoter from the GCE HAL.
29  * This is a private protocol between the HAL and the remoter.
30  */
31 
32 static const size_t kSensorNameMaxLen = 64;
33 // Don't use PATH_MAX here because it would increate the size of every
34 // packet that we send to the remoter.
35 static const size_t kScreenRecordFilePathMaxLen = 128;
36 static const size_t kUnixSocketPathMaxLen = 128;
37 
38 struct remoter_request_packet {
39   /* Length of the packet in bytes. */
40   uint32_t length;
41 
42   /* Operation to perform. */
43   uint8_t operation;
44 
45   /* Set to '1' if a response packet is desired */
46   uint8_t send_response;
47 
48   /* Operation arguments. */
49   union {
50     /* Arguments for the frame buffer 'post' operation. */
51     struct {
52       /* Y offset in the double-buffer where this frame starts. */
53       uint32_t y_offset;
54     } fb_post_params;
55     /* Arguments for the frame buffer 'update rect' operation. */
56     struct {
57       uint32_t left;
58       uint32_t top;
59       uint32_t width;
60       uint32_t height;
61     } fb_update_rect_params;
62     struct {
63       uint32_t type;
64       bool enabled;
65       int64_t delay_ns;
66       int handle;
67     } sensor_state_params;
68     struct {
69       char filepath[kScreenRecordFilePathMaxLen];
70     } screenrecord_params;
71     struct {
72       char unix_socket[kUnixSocketPathMaxLen];
73     } hal_ready_params;
74   } params;
75 } __attribute__((packed));
76 
77 enum {
78   kRemoterHALReady = 1,
79   kRemoterSensorState
80 };
81 
82 /*
83  * If 'send_response' is set in a request then the remoter will respond
84  * with the following structure.
85  */
86 struct remoter_response_packet {
87   uint32_t length;
88   uint8_t status;
89   union {
90     struct {
91       /* Number of 'struct sensor_list_element_packet's to follow */
92       uint8_t num_sensors;
93     } sensor_list_data;
94   } data;
95 } __attribute__((packed));
96 
97 struct sensor_list_element_packet {
98   int handle;
99   int type;
100   char name[kSensorNameMaxLen];
101   char vendor[kSensorNameMaxLen];
102   int version;
103   float max_range;
104   float resolution;
105   float power;
106 } __attribute__((packed));
107 
108 enum {
109   kResponseStatusOk = 1,
110   kResponseStatusFailed
111 };
112 
remoter_request_packet_init(struct remoter_request_packet * pkt,uint8_t operation,uint8_t send_response)113 static inline void remoter_request_packet_init(
114     struct remoter_request_packet* pkt, uint8_t operation,
115     uint8_t send_response) {
116   memset(pkt, 0, sizeof(*pkt));
117   pkt->length = sizeof(*pkt);
118   pkt->operation = operation;
119   pkt->send_response = send_response;
120 }
121 
remoter_response_packet_init(struct remoter_response_packet * pkt,uint8_t status)122 static inline void remoter_response_packet_init(
123     struct remoter_response_packet* pkt, uint8_t status) {
124   memset(pkt, 0, sizeof(*pkt));
125   pkt->length = sizeof(*pkt);
126   pkt->status = status;
127 }
128 
129 void remoter_connect(cvd::SharedFD* dest);
130 int remoter_connect();
131 
remoter_read_request(const cvd::SharedFD & socket,struct remoter_request_packet * request)132 static inline int remoter_read_request(
133     const cvd::SharedFD& socket,
134     struct remoter_request_packet* request) {
135   int len;
136   int remaining_data;
137   /* Packets start with a 4 byte length (which includes the length). */
138 
139   if ((len = socket->Read(request, sizeof(request->length))) < 0) {
140     ALOGE("%s: Failed to read remoter request (%s)",
141           __FUNCTION__, socket->StrError());
142     return -1;
143   } else if (len == 0) {
144     return 0;
145   } else if (len != sizeof(request->length)) {
146     ALOGE("%s: Failed to read remoter request (Short read)", __FUNCTION__);
147     return -1;
148   }
149 
150   /* Extra paranoia. */
151   if (request->length != sizeof(*request)) {
152     ALOGE("%s: Malformed remoter request", __FUNCTION__);
153     return -1;
154   }
155   remaining_data = request->length - sizeof(request->length);
156   uint8_t* cursor = ((uint8_t*)request) + sizeof(request->length);
157   if ((len = socket->Read(cursor, remaining_data)) < 0) {
158     ALOGE("%s: Failed to read remoter request (%s)",
159           __FUNCTION__, socket->StrError());
160     return -1;
161   } else if (len == 0) {
162     return 0;
163   } else if (len != (int) remaining_data) {
164     ALOGE("%s: Failed to read remoter request (Short read)", __FUNCTION__);
165     return -1;
166   }
167   return 1;
168 }
169 
remoter_read_response(int socket,struct remoter_response_packet * response)170 static inline int remoter_read_response(
171     int socket, struct remoter_response_packet* response) {
172   int len;
173   int remaining_data;
174   /* Packets start with a 4 byte length (which includes the length). */
175 
176 #ifdef DEBUG_CONNECTIONS
177   ALOGI("remoter_read_response(): socket %d, length length = %d", socket,
178         sizeof(response->length));
179 #endif
180   if ((len = TEMP_FAILURE_RETRY(
181       read(socket, response, sizeof(response->length)))) < 0) {
182     ALOGE("%s: Failed to read remoter response (%s)",
183           __FUNCTION__, strerror(errno));
184     return -1;
185   } else if (len == 0) {
186     return 0;
187   } else if (len != sizeof(response->length)) {
188     ALOGE("%s: Failed to read remoter response (Short read)", __FUNCTION__);
189     return -1;
190   }
191 
192   /* Extra paranoia. */
193   if (response->length != sizeof(*response)) {
194     ALOGE("%s: Malformed remoter response", __FUNCTION__);
195     return -1;
196   }
197   remaining_data = response->length - sizeof(response->length);
198   uint8_t* cursor = ((uint8_t*)response) + sizeof(response->length);
199 #ifdef DEBUG_CONNECTIONS
200   ALOGI("remoter_read_request(): socket %d, data length = %d",
201         socket, remaining_data);
202 #endif
203   if ((len = TEMP_FAILURE_RETRY(read(socket, cursor, remaining_data))) < 0) {
204     ALOGE("%s: Failed to read remoter response (%s)",
205           __FUNCTION__, strerror(errno));
206     return -1;
207   } else if (len == 0) {
208     return 0;
209   } else if (len != (int) remaining_data) {
210     ALOGE("%s: Failed to read remoter response (Short read)", __FUNCTION__);
211     return -1;
212   }
213   return 1;
214 }
215 
remoter_send_request(int socket,struct remoter_request_packet * request)216 static inline int remoter_send_request(
217     int socket, struct remoter_request_packet* request) {
218 #ifdef DEBUG_CONNECTIONS
219   ALOGI(
220       "remoter_send_request(): socket %d, length %u", socket, sizeof(*request));
221 #endif
222   int len = TEMP_FAILURE_RETRY(write(socket, request, sizeof(*request)));
223   if (len <= 0) {
224     ALOGE("Failed to write request to remoter (%s)", strerror(errno));
225     return -1;
226   } else if (len != sizeof(*request)) {
227     ALOGE("Failed to write request to remoter (short write)");
228     return -1;
229   }
230   return 0;
231 }
232 
remoter_send_response(const cvd::SharedFD & socket,struct remoter_response_packet * response)233 static inline int remoter_send_response(
234     const cvd::SharedFD& socket,
235     struct remoter_response_packet* response) {
236   int len = socket->Write(response, sizeof(*response));
237   if (len <=0) {
238     ALOGE("%s: Failed to send response to remoter (%s)",
239           __FUNCTION__, strerror(errno));
240     return -1;
241   }
242   return 0;
243 }
244 
remoter_do_single_request_with_socket(int socket,struct remoter_request_packet * request,struct remoter_response_packet * response)245 static inline int remoter_do_single_request_with_socket(
246     int socket, struct remoter_request_packet* request,
247     struct remoter_response_packet* response) {
248 
249   if (request->send_response && !response) {
250     ALOGE("%s: Request specifies a response but no response ptr set",
251           __FUNCTION__);
252     return -1;
253   } else if (!request->send_response && response) {
254     ALOGE("%s: Request specifies no response but has response ptr set",
255           __FUNCTION__);
256     return -1;
257   }
258 
259   if (remoter_send_request(socket, request) < 0) {
260     return -1;
261   }
262 
263   if (response && (remoter_read_response(socket, response) <= 0)) {
264     return -1;
265   }
266   return 0;
267 }
268 
remoter_do_single_request(struct remoter_request_packet * request,struct remoter_response_packet * response)269 static inline int remoter_do_single_request(
270     struct remoter_request_packet* request,
271     struct remoter_response_packet* response) {
272   int socket;
273   if ((socket = remoter_connect()) < 0) {
274     return -1;
275   }
276 
277   if (remoter_do_single_request_with_socket(socket, request, response) < 0) {
278     close(socket);
279     return -1;
280   }
281   close(socket);
282   return 0;
283 }
284 
285