1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "sensor_basic_data_channel.h"
17 
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <unistd.h>
21 
22 #include "hisysevent.h"
23 #include "sensor_errors.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "SensorBasicChannel"
27 
28 namespace OHOS {
29 namespace Sensors {
30 using namespace OHOS::HiviewDFX;
31 
32 namespace {
33 constexpr int32_t SENSOR_READ_DATA_SIZE = sizeof(SensorData) * 100;
34 constexpr int32_t DEFAULT_CHANNEL_SIZE = 2 * 1024;
35 constexpr int32_t MAX_RECV_LIMIT = 32;
36 constexpr int32_t SOCKET_PAIR_SIZE = 2;
37 constexpr int32_t SEND_RETRY_LIMIT = 32;
38 constexpr int32_t SEND_RETRY_SLEEP_TIME = 500;
39 }  // namespace
40 
SensorBasicDataChannel()41 SensorBasicDataChannel::SensorBasicDataChannel() : sendFd_(-1), receiveFd_(-1), isActive_(false)
42 {
43     SEN_HILOGD("isActive_:%{public}d, sendFd:%{public}d", isActive_, sendFd_);
44 }
45 
CreateSensorBasicChannel()46 int32_t SensorBasicDataChannel::CreateSensorBasicChannel()
47 {
48     SEN_HILOGI("In");
49     if ((sendFd_ != -1) || (receiveFd_ != -1)) {
50         SEN_HILOGD("Already create socketpair");
51         return ERR_OK;
52     }
53 
54     int32_t socketPair[SOCKET_PAIR_SIZE] = { 0 };
55     if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketPair) != 0) {
56         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "DATA_CHANNEL_EXCEPTION",
57             HiSysEvent::EventType::FAULT, "PKG_NAME", "CreateSensorBasicChannel", "ERROR_CODE", errno);
58         SEN_HILOGE("Create socketpair failed");
59         sendFd_ = -1;
60         receiveFd_ = -1;
61         return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
62     }
63     // set socket attr
64     if (setsockopt(socketPair[0], SOL_SOCKET, SO_SNDBUF, &SENSOR_READ_DATA_SIZE, sizeof(SENSOR_READ_DATA_SIZE)) != 0) {
65         SEN_HILOGE("setsockopt socketpair 0, SNDBUF failed, errno:%{public}d", errno);
66         goto CLOSE_SOCK;
67     }
68     if (setsockopt(socketPair[1], SOL_SOCKET, SO_RCVBUF, &SENSOR_READ_DATA_SIZE, sizeof(SENSOR_READ_DATA_SIZE)) != 0) {
69         SEN_HILOGE("setsockopt socketpair 1, RCVBUF failed, errno:%{public}d", errno);
70         goto CLOSE_SOCK;
71     }
72     if (setsockopt(socketPair[0], SOL_SOCKET, SO_RCVBUF, &DEFAULT_CHANNEL_SIZE, sizeof(DEFAULT_CHANNEL_SIZE)) != 0) {
73         SEN_HILOGE("setsockopt socketpair 0, RCVBUF failed, errno:%{public}d", errno);
74         goto CLOSE_SOCK;
75     }
76     if (setsockopt(socketPair[1], SOL_SOCKET, SO_SNDBUF, &DEFAULT_CHANNEL_SIZE, sizeof(DEFAULT_CHANNEL_SIZE)) != 0) {
77         SEN_HILOGE("setsockopt socketpair 1, SNDBUF failed, errno:%{public}d", errno);
78         goto CLOSE_SOCK;
79     }
80     if (fcntl(socketPair[0], F_SETFL, O_NONBLOCK) != 0) {
81         SEN_HILOGE("fcntl socketpair 0 failed, errno:%{public}d", errno);
82         goto CLOSE_SOCK;
83     }
84     if (fcntl(socketPair[1], F_SETFL, O_NONBLOCK) != 0) {
85         SEN_HILOGE("fcntl socketpair 1 failed, errno:%{public}d", errno);
86         goto CLOSE_SOCK;
87     }
88     sendFd_ = socketPair[0];
89     receiveFd_ = socketPair[1];
90     SEN_HILOGI("Done");
91     return ERR_OK;
92 
93     CLOSE_SOCK:
94     close(socketPair[0]);
95     close(socketPair[1]);
96     sendFd_ = -1;
97     receiveFd_ = -1;
98     return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
99 }
100 
CreateSensorBasicChannel(MessageParcel & data)101 int32_t SensorBasicDataChannel::CreateSensorBasicChannel(MessageParcel &data)
102 {
103     CALL_LOG_ENTER;
104     if (sendFd_ != -1) {
105         SEN_HILOGD("Already create socketpair");
106         return ERR_OK;
107     }
108     sendFd_ = data.ReadFileDescriptor();
109     if (sendFd_ < 0) {
110         SEN_HILOGE("ReadFileDescriptor is failed");
111         sendFd_ = -1;
112         return SENSOR_CHANNEL_READ_DESCRIPTOR_ERR;
113     }
114     return ERR_OK;
115 }
116 
~SensorBasicDataChannel()117 SensorBasicDataChannel::~SensorBasicDataChannel()
118 {
119     DestroySensorBasicChannel();
120 }
121 
SendToBinder(MessageParcel & data)122 int32_t SensorBasicDataChannel::SendToBinder(MessageParcel &data)
123 {
124     SEN_HILOGD("sendFd:%{public}d", sendFd_);
125     if (sendFd_ < 0) {
126         SEN_HILOGE("sendFd FileDescriptor error");
127         return SENSOR_CHANNEL_SENDFD_ERR;
128     }
129     bool result = data.WriteFileDescriptor(sendFd_);
130     if (!result) {
131         SEN_HILOGE("Send sendFd_ failed");
132         CloseSendFd();
133         return SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR;
134     }
135     return ERR_OK;
136 }
137 
CloseSendFd()138 void SensorBasicDataChannel::CloseSendFd()
139 {
140     if (sendFd_ != -1) {
141         close(sendFd_);
142         sendFd_ = -1;
143         SEN_HILOGD("Close sendFd_");
144     }
145 }
146 
SendData(const void * vaddr,size_t size)147 int32_t SensorBasicDataChannel::SendData(const void *vaddr, size_t size)
148 {
149     CHKPR(vaddr, SENSOR_CHANNEL_SEND_ADDR_ERR);
150     if (sendFd_ < 0) {
151         SEN_HILOGE("Failed, param is invalid");
152         return ERROR;
153     }
154     auto sensorData = reinterpret_cast<const char *>(vaddr);
155     int32_t idx = 0;
156     int32_t retryCount = 0;
157     int32_t buffSize = static_cast<int32_t>(size);
158     int32_t remSize = buffSize;
159     do {
160         retryCount++;
161         ssize_t length = send(sendFd_, &sensorData[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
162         if (length < 0) {
163             if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
164                 SEN_HILOGD("Continue for EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d, sendFd_:%{public}d",
165                     errno, sendFd_);
166                 usleep(SEND_RETRY_SLEEP_TIME);
167                 continue;
168             }
169             SEN_HILOGE("Send fail, errno:%{public}d, length:%{public}d, sendFd: %{public}d",
170                 errno, static_cast<int32_t>(length), sendFd_);
171             return SENSOR_CHANNEL_SEND_DATA_ERR;
172         }
173         idx += length;
174         remSize -= length;
175         if (remSize > 0) {
176             usleep(SEND_RETRY_SLEEP_TIME);
177         }
178     } while (remSize > 0 && retryCount < SEND_RETRY_LIMIT);
179     if ((retryCount >= SEND_RETRY_LIMIT) && (remSize > 0)) {
180         SEN_HILOGE("Send fail, size:%{public}d, retryCount:%{public}d, idx:%{public}d, "
181             "buffSize:%{public}d, errno:%{public}d", buffSize, retryCount, idx, buffSize, errno);
182         return SENSOR_CHANNEL_SEND_DATA_ERR;
183     }
184     return ERR_OK;
185 }
186 
ReceiveData(ClientExcuteCB callBack,void * vaddr,size_t size)187 int32_t SensorBasicDataChannel::ReceiveData(ClientExcuteCB callBack, void *vaddr, size_t size)
188 {
189     if (vaddr == nullptr || callBack == nullptr || receiveFd_ < 0) {
190         SEN_HILOGE("Failed, receiveFd_ invalid, callBack is null or vaddr is null");
191         return ERROR;
192     }
193     ssize_t length = 0;
194     int32_t retryCount = 0;
195     for (int32_t i = 0; i < MAX_RECV_LIMIT; i++) {
196         {
197             length = recv(receiveFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
198         }
199         retryCount++;
200         if (length > 0) {
201             callBack(static_cast<int32_t>(length));
202         } else {
203             if ((length < 0) && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) {
204                 SEN_HILOGD("Continue for EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d, sendFd_:%{public}d",
205                     errno, sendFd_);
206                 continue;
207             }
208             SEN_HILOGE("recv failed:%{public}s", ::strerror(errno));
209             return ERROR;
210         }
211     };
212     return ERR_OK;
213 }
214 
GetSendDataFd() const215 int32_t SensorBasicDataChannel::GetSendDataFd() const
216 {
217     return sendFd_;
218 }
219 
GetReceiveDataFd() const220 int32_t SensorBasicDataChannel::GetReceiveDataFd() const
221 {
222     return receiveFd_;
223 }
224 
DestroySensorBasicChannel()225 int32_t SensorBasicDataChannel::DestroySensorBasicChannel()
226 {
227     if (sendFd_ >= 0) {
228         close(sendFd_);
229         sendFd_ = -1;
230         SEN_HILOGD("Close sendFd_ success");
231     }
232     if (receiveFd_ >= 0) {
233         close(receiveFd_);
234         receiveFd_ = -1;
235         SEN_HILOGD("Close receiveFd_ success");
236     }
237     return ERR_OK;
238 }
239 
GetDataCacheBuf() const240 const std::unordered_map<int32_t, SensorData> &SensorBasicDataChannel::GetDataCacheBuf() const
241 {
242     return dataCacheBuf_;
243 }
244 
GetSensorStatus() const245 bool SensorBasicDataChannel::GetSensorStatus() const
246 {
247     return isActive_;
248 }
249 
SetSensorStatus(bool isActive)250 void SensorBasicDataChannel::SetSensorStatus(bool isActive)
251 {
252     SEN_HILOGD("isActive_:%{public}d", isActive);
253     std::unique_lock<std::mutex> lock(statusLock_);
254     isActive_ = isActive;
255     return;
256 }
257 }  // namespace Sensors
258 }  // namespace OHOS
259