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 
17 #define LOG_TAG "PipeComm"
18 
19 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
20 #include <log/log.h>
21 
22 #include "PipeComm.h"
23 #include "qemu_pipe.h"
24 
25 #define CAR_SERVICE_NAME "pipe:qemud:car"
26 
27 
28 namespace android {
29 namespace hardware {
30 namespace automotive {
31 namespace vehicle {
32 namespace V2_0 {
33 
34 namespace impl {
35 
PipeComm(MessageProcessor * messageProcessor)36 PipeComm::PipeComm(MessageProcessor* messageProcessor) : CommConn(messageProcessor), mPipeFd(-1) {}
37 
start()38 void PipeComm::start() {
39     int fd = qemu_pipe_open(CAR_SERVICE_NAME);
40 
41     if (fd < 0) {
42         ALOGE("%s: Could not open connection to service: %s %d", __FUNCTION__, strerror(errno), fd);
43         return;
44     }
45 
46     ALOGI("%s: Starting pipe connection, fd=%d", __FUNCTION__, fd);
47     mPipeFd = fd;
48 
49     CommConn::start();
50 }
51 
stop()52 void PipeComm::stop() {
53     if (mPipeFd > 0) {
54         ::close(mPipeFd);
55         mPipeFd = -1;
56     }
57     CommConn::stop();
58 }
59 
read()60 std::vector<uint8_t> PipeComm::read() {
61     static constexpr int MAX_RX_MSG_SZ = 2048;
62     std::vector<uint8_t> msg = std::vector<uint8_t>(MAX_RX_MSG_SZ);
63     int numBytes;
64 
65     numBytes = qemu_pipe_frame_recv(mPipeFd, msg.data(), msg.size());
66 
67     if (numBytes == MAX_RX_MSG_SZ) {
68         ALOGE("%s: Received max size = %d", __FUNCTION__, MAX_RX_MSG_SZ);
69     } else if (numBytes > 0) {
70         msg.resize(numBytes);
71         return msg;
72     } else {
73         ALOGD("%s: Connection terminated on pipe %d, numBytes=%d", __FUNCTION__, mPipeFd, numBytes);
74         mPipeFd = -1;
75     }
76 
77     return std::vector<uint8_t>();
78 }
79 
write(const std::vector<uint8_t> & data)80 int PipeComm::write(const std::vector<uint8_t>& data) {
81     int retVal = 0;
82 
83     if (mPipeFd != -1) {
84         retVal = qemu_pipe_frame_send(mPipeFd, data.data(), data.size());
85     }
86 
87     if (retVal < 0) {
88         retVal = -errno;
89         ALOGE("%s:  send_cmd: (fd=%d): ERROR: %s", __FUNCTION__, mPipeFd, strerror(errno));
90     }
91 
92     return retVal;
93 }
94 
95 
96 }  // impl
97 
98 }  // namespace V2_0
99 }  // namespace vehicle
100 }  // namespace automotive
101 }  // namespace hardware
102 }  // namespace android
103 
104 
105 
106