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 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
23 #include "hisysevent.h"
24 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
25 #include "sensor_errors.h"
26
27 #undef LOG_TAG
28 #define LOG_TAG "SensorBasicChannel"
29
30 namespace OHOS {
31 namespace Sensors {
32 using namespace OHOS::HiviewDFX;
33
34 namespace {
35 constexpr int32_t SENSOR_READ_DATA_SIZE = sizeof(SensorData) * 100;
36 constexpr int32_t DEFAULT_CHANNEL_SIZE = 2 * 1024;
37 constexpr int32_t MAX_RECV_LIMIT = 32;
38 constexpr int32_t SOCKET_PAIR_SIZE = 2;
39 constexpr int32_t SEND_RETRY_LIMIT = 5;
40 constexpr int32_t SEND_RETRY_SLEEP_TIME = 500;
41 } // namespace
42
SensorBasicDataChannel()43 SensorBasicDataChannel::SensorBasicDataChannel() : sendFd_(-1), receiveFd_(-1), isActive_(false)
44 {
45 SEN_HILOGD("isActive_:%{public}d, sendFd:%{public}d", isActive_, sendFd_);
46 }
47
CreateSensorBasicChannel()48 int32_t SensorBasicDataChannel::CreateSensorBasicChannel()
49 {
50 SEN_HILOGI("In");
51 std::unique_lock<std::mutex> lock(fdLock_);
52 if ((sendFd_ != -1) || (receiveFd_ != -1)) {
53 SEN_HILOGD("Already create socketpair");
54 return ERR_OK;
55 }
56 int32_t socketPair[SOCKET_PAIR_SIZE] = { 0 };
57 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketPair) != 0) {
58 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
59 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "DATA_CHANNEL_EXCEPTION",
60 HiSysEvent::EventType::FAULT, "PKG_NAME", "CreateSensorBasicChannel", "ERROR_CODE", errno);
61 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
62 SEN_HILOGE("Create socketpair failed");
63 sendFd_ = -1;
64 receiveFd_ = -1;
65 return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
66 }
67 fdsan_exchange_owner_tag(socketPair[0], 0, TAG);
68 fdsan_exchange_owner_tag(socketPair[1], 0, TAG);
69 if (setsockopt(socketPair[0], SOL_SOCKET, SO_SNDBUF, &SENSOR_READ_DATA_SIZE, sizeof(SENSOR_READ_DATA_SIZE)) != 0) {
70 SEN_HILOGE("setsockopt socketpair 0, SNDBUF failed, errno:%{public}d", errno);
71 goto CLOSE_SOCK;
72 }
73 if (setsockopt(socketPair[1], SOL_SOCKET, SO_RCVBUF, &SENSOR_READ_DATA_SIZE, sizeof(SENSOR_READ_DATA_SIZE)) != 0) {
74 SEN_HILOGE("setsockopt socketpair 1, RCVBUF failed, errno:%{public}d", errno);
75 goto CLOSE_SOCK;
76 }
77 if (setsockopt(socketPair[0], SOL_SOCKET, SO_RCVBUF, &DEFAULT_CHANNEL_SIZE, sizeof(DEFAULT_CHANNEL_SIZE)) != 0) {
78 SEN_HILOGE("setsockopt socketpair 0, RCVBUF failed, errno:%{public}d", errno);
79 goto CLOSE_SOCK;
80 }
81 if (setsockopt(socketPair[1], SOL_SOCKET, SO_SNDBUF, &DEFAULT_CHANNEL_SIZE, sizeof(DEFAULT_CHANNEL_SIZE)) != 0) {
82 SEN_HILOGE("setsockopt socketpair 1, SNDBUF failed, errno:%{public}d", errno);
83 goto CLOSE_SOCK;
84 }
85 if (fcntl(socketPair[0], F_SETFL, O_NONBLOCK) != 0) {
86 SEN_HILOGE("fcntl socketpair 0 failed, errno:%{public}d", errno);
87 goto CLOSE_SOCK;
88 }
89 if (fcntl(socketPair[1], F_SETFL, O_NONBLOCK) != 0) {
90 SEN_HILOGE("fcntl socketpair 1 failed, errno:%{public}d", errno);
91 goto CLOSE_SOCK;
92 }
93 sendFd_ = socketPair[0];
94 receiveFd_ = socketPair[1];
95 SEN_HILOGI("Done");
96 return ERR_OK;
97
98 CLOSE_SOCK:
99 fdsan_close_with_tag(socketPair[0], TAG);
100 fdsan_close_with_tag(socketPair[1], TAG);
101 sendFd_ = -1;
102 receiveFd_ = -1;
103 return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
104 }
105
CreateSensorBasicChannel(MessageParcel & data)106 int32_t SensorBasicDataChannel::CreateSensorBasicChannel(MessageParcel &data)
107 {
108 CALL_LOG_ENTER;
109 std::unique_lock<std::mutex> lock(fdLock_);
110 if (sendFd_ != -1) {
111 SEN_HILOGD("Already create socketpair");
112 return ERR_OK;
113 }
114 sendFd_ = data.ReadFileDescriptor();
115 if (sendFd_ < 0) {
116 SEN_HILOGE("ReadFileDescriptor is failed");
117 sendFd_ = -1;
118 return SENSOR_CHANNEL_READ_DESCRIPTOR_ERR;
119 }
120 return ERR_OK;
121 }
122
CreateSensorBasicChannelBySendFd(int32_t sendFd)123 int32_t SensorBasicDataChannel::CreateSensorBasicChannelBySendFd(int32_t sendFd)
124 {
125 CALL_LOG_ENTER;
126 std::unique_lock<std::mutex> lock(fdLock_);
127 if (sendFd_ != -1) {
128 SEN_HILOGD("Already create socketpair");
129 return ERR_OK;
130 }
131 sendFd_ = sendFd;
132 fdsan_exchange_owner_tag(sendFd_, 0, TAG);
133 if (sendFd_ < 0) {
134 SEN_HILOGE("ReadFileDescriptor is failed");
135 sendFd_ = -1;
136 return SENSOR_CHANNEL_READ_DESCRIPTOR_ERR;
137 }
138 return ERR_OK;
139 }
140
~SensorBasicDataChannel()141 SensorBasicDataChannel::~SensorBasicDataChannel()
142 {
143 DestroySensorBasicChannel();
144 }
145
SendToBinder(MessageParcel & data)146 int32_t SensorBasicDataChannel::SendToBinder(MessageParcel &data)
147 {
148 bool result = false;
149 {
150 std::unique_lock<std::mutex> lock(fdLock_);
151 SEN_HILOGD("sendFd:%{public}d", sendFd_);
152 if (sendFd_ < 0) {
153 SEN_HILOGE("sendFd FileDescriptor error");
154 return SENSOR_CHANNEL_SENDFD_ERR;
155 }
156 result = data.WriteFileDescriptor(sendFd_);
157 }
158 if (!result) {
159 SEN_HILOGE("Send sendFd_ failed");
160 CloseSendFd();
161 return SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR;
162 }
163 return ERR_OK;
164 }
165
CloseSendFd()166 void SensorBasicDataChannel::CloseSendFd()
167 {
168 std::unique_lock<std::mutex> lock(fdLock_);
169 if (sendFd_ != -1) {
170 fdsan_close_with_tag(sendFd_, TAG);
171 sendFd_ = -1;
172 SEN_HILOGD("Close sendFd_");
173 }
174 }
175
SendData(const void * vaddr,size_t size)176 int32_t SensorBasicDataChannel::SendData(const void *vaddr, size_t size)
177 {
178 CHKPR(vaddr, SENSOR_CHANNEL_SEND_ADDR_ERR);
179 auto sensorData = reinterpret_cast<const char *>(vaddr);
180 int32_t idx = 0;
181 int32_t retryCount = 0;
182 int32_t buffSize = static_cast<int32_t>(size);
183 int32_t remSize = buffSize;
184 do {
185 std::unique_lock<std::mutex> lock(fdLock_);
186 if (sendFd_ < 0) {
187 SEN_HILOGE("Failed, param is invalid");
188 return SENSOR_CHANNEL_SEND_ADDR_ERR;
189 }
190 retryCount++;
191 ssize_t length = send(sendFd_, &sensorData[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
192 if (length < 0) {
193 if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
194 SEN_HILOGD("Continue for EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d, sendFd_:%{public}d",
195 errno, sendFd_);
196 usleep(SEND_RETRY_SLEEP_TIME);
197 continue;
198 }
199 SEN_HILOGE("Send fail, errno:%{public}d, length:%{public}d, sendFd: %{public}d",
200 errno, static_cast<int32_t>(length), sendFd_);
201 return SENSOR_CHANNEL_SEND_DATA_ERR;
202 }
203 idx += length;
204 remSize -= length;
205 if (remSize > 0) {
206 usleep(SEND_RETRY_SLEEP_TIME);
207 }
208 } while (remSize > 0 && retryCount < SEND_RETRY_LIMIT);
209 if ((retryCount >= SEND_RETRY_LIMIT) && (remSize > 0)) {
210 SEN_HILOGE("Send fail, size:%{public}d, retryCount:%{public}d, idx:%{public}d, "
211 "buffSize:%{public}d, errno:%{public}d", buffSize, retryCount, idx, buffSize, errno);
212 return SENSOR_CHANNEL_SEND_DATA_ERR;
213 }
214 return ERR_OK;
215 }
216
ReceiveData(ClientExcuteCB callBack,void * vaddr,size_t size)217 int32_t SensorBasicDataChannel::ReceiveData(ClientExcuteCB callBack, void *vaddr, size_t size)
218 {
219 if (vaddr == nullptr || callBack == nullptr) {
220 SEN_HILOGE("Failed, callBack is null or vaddr is null");
221 return ERROR;
222 }
223 ssize_t length = 0;
224 for (int32_t i = 0; i < MAX_RECV_LIMIT; i++) {
225 {
226 std::unique_lock<std::mutex> lock(fdLock_);
227 if (receiveFd_ < 0) {
228 SEN_HILOGE("Failed, receiveFd_ invalid");
229 return ERROR;
230 }
231 length = recv(receiveFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
232 }
233 if (length > 0) {
234 callBack(static_cast<int32_t>(length));
235 }
236 if (length < 0) {
237 if (errno == EINTR) {
238 SEN_HILOGD("Continue for EINTR, errno:%{public}d, sendFd_:%{public}d", errno, sendFd_);
239 continue;
240 }
241 if (errno == EAGAIN || errno == EWOULDBLOCK) {
242 SEN_HILOGD("No available data");
243 } else {
244 SEN_HILOGE("recv failed:%{public}s", ::strerror(errno));
245 return ERROR;
246 }
247 return ERR_OK;
248 }
249 };
250 return ERR_OK;
251 }
252
GetSendDataFd()253 int32_t SensorBasicDataChannel::GetSendDataFd()
254 {
255 std::unique_lock<std::mutex> lock(fdLock_);
256 return sendFd_;
257 }
258
GetReceiveDataFd()259 int32_t SensorBasicDataChannel::GetReceiveDataFd()
260 {
261 std::unique_lock<std::mutex> lock(fdLock_);
262 return receiveFd_;
263 }
264
DestroySensorBasicChannel()265 int32_t SensorBasicDataChannel::DestroySensorBasicChannel()
266 {
267 std::unique_lock<std::mutex> lock(fdLock_);
268 if (sendFd_ >= 0) {
269 fdsan_close_with_tag(sendFd_, TAG);
270 sendFd_ = -1;
271 SEN_HILOGD("Close sendFd_ success");
272 }
273 if (receiveFd_ >= 0) {
274 fdsan_close_with_tag(receiveFd_, TAG);
275 receiveFd_ = -1;
276 SEN_HILOGD("Close receiveFd_ success");
277 }
278 return ERR_OK;
279 }
280
GetDataCacheBuf() const281 const std::unordered_map<int32_t, SensorData> &SensorBasicDataChannel::GetDataCacheBuf() const
282 {
283 return dataCacheBuf_;
284 }
285
GetSensorStatus() const286 bool SensorBasicDataChannel::GetSensorStatus() const
287 {
288 return isActive_;
289 }
290
SetSensorStatus(bool isActive)291 void SensorBasicDataChannel::SetSensorStatus(bool isActive)
292 {
293 SEN_HILOGD("isActive_:%{public}d", isActive);
294 std::unique_lock<std::mutex> lock(statusLock_);
295 isActive_ = isActive;
296 return;
297 }
298 } // namespace Sensors
299 } // namespace OHOS
300