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 fdsan_exchange_owner_tag(sendFd_, 0, TAG);
116 if (sendFd_ < 0) {
117 SEN_HILOGE("ReadFileDescriptor is failed");
118 sendFd_ = -1;
119 return SENSOR_CHANNEL_READ_DESCRIPTOR_ERR;
120 }
121 return ERR_OK;
122 }
123
CreateSensorBasicChannelBySendFd(int32_t sendFd)124 int32_t SensorBasicDataChannel::CreateSensorBasicChannelBySendFd(int32_t sendFd)
125 {
126 CALL_LOG_ENTER;
127 std::unique_lock<std::mutex> lock(fdLock_);
128 if (sendFd_ != -1) {
129 SEN_HILOGD("Already create socketpair");
130 return ERR_OK;
131 }
132 sendFd_ = sendFd;
133 fdsan_exchange_owner_tag(sendFd_, 0, TAG);
134 if (sendFd_ < 0) {
135 SEN_HILOGE("ReadFileDescriptor is failed");
136 sendFd_ = -1;
137 return SENSOR_CHANNEL_READ_DESCRIPTOR_ERR;
138 }
139 return ERR_OK;
140 }
141
~SensorBasicDataChannel()142 SensorBasicDataChannel::~SensorBasicDataChannel()
143 {
144 DestroySensorBasicChannel();
145 }
146
SendToBinder(MessageParcel & data)147 int32_t SensorBasicDataChannel::SendToBinder(MessageParcel &data)
148 {
149 bool result = false;
150 {
151 std::unique_lock<std::mutex> lock(fdLock_);
152 SEN_HILOGD("sendFd:%{public}d", sendFd_);
153 if (sendFd_ < 0) {
154 SEN_HILOGE("sendFd FileDescriptor error");
155 return SENSOR_CHANNEL_SENDFD_ERR;
156 }
157 result = data.WriteFileDescriptor(sendFd_);
158 }
159 if (!result) {
160 SEN_HILOGE("Send sendFd_ failed");
161 CloseSendFd();
162 return SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR;
163 }
164 return ERR_OK;
165 }
166
CloseSendFd()167 void SensorBasicDataChannel::CloseSendFd()
168 {
169 std::unique_lock<std::mutex> lock(fdLock_);
170 if (sendFd_ != -1) {
171 fdsan_close_with_tag(sendFd_, TAG);
172 sendFd_ = -1;
173 SEN_HILOGD("Close sendFd_");
174 }
175 }
176
SendData(const void * vaddr,size_t size)177 int32_t SensorBasicDataChannel::SendData(const void *vaddr, size_t size)
178 {
179 CHKPR(vaddr, SENSOR_CHANNEL_SEND_ADDR_ERR);
180 auto sensorData = reinterpret_cast<const char *>(vaddr);
181 int32_t idx = 0;
182 int32_t retryCount = 0;
183 int32_t buffSize = static_cast<int32_t>(size);
184 int32_t remSize = buffSize;
185 do {
186 std::unique_lock<std::mutex> lock(fdLock_);
187 if (sendFd_ < 0) {
188 SEN_HILOGE("Failed, param is invalid");
189 return SENSOR_CHANNEL_SEND_ADDR_ERR;
190 }
191 retryCount++;
192 ssize_t length = send(sendFd_, &sensorData[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
193 if (length < 0) {
194 if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
195 SEN_HILOGD("Continue for EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d, sendFd_:%{public}d",
196 errno, sendFd_);
197 usleep(SEND_RETRY_SLEEP_TIME);
198 continue;
199 }
200 SEN_HILOGE("Send fail, errno:%{public}d, length:%{public}d, sendFd: %{public}d",
201 errno, static_cast<int32_t>(length), sendFd_);
202 return SENSOR_CHANNEL_SEND_DATA_ERR;
203 }
204 idx += length;
205 remSize -= length;
206 if (remSize > 0) {
207 usleep(SEND_RETRY_SLEEP_TIME);
208 }
209 } while (remSize > 0 && retryCount < SEND_RETRY_LIMIT);
210 if ((retryCount >= SEND_RETRY_LIMIT) && (remSize > 0)) {
211 SEN_HILOGE("Send fail, size:%{public}d, retryCount:%{public}d, idx:%{public}d, "
212 "buffSize:%{public}d, errno:%{public}d", buffSize, retryCount, idx, buffSize, errno);
213 return SENSOR_CHANNEL_SEND_DATA_ERR;
214 }
215 return ERR_OK;
216 }
217
ReceiveData(ClientExcuteCB callBack,void * vaddr,size_t size)218 int32_t SensorBasicDataChannel::ReceiveData(ClientExcuteCB callBack, void *vaddr, size_t size)
219 {
220 if (vaddr == nullptr || callBack == nullptr) {
221 SEN_HILOGE("Failed, callBack is null or vaddr is null");
222 return ERROR;
223 }
224 ssize_t length = 0;
225 for (int32_t i = 0; i < MAX_RECV_LIMIT; i++) {
226 {
227 std::unique_lock<std::mutex> lock(fdLock_);
228 if (receiveFd_ < 0) {
229 SEN_HILOGE("Failed, receiveFd_ invalid");
230 return ERROR;
231 }
232 length = recv(receiveFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
233 }
234 if (length > 0) {
235 callBack(static_cast<int32_t>(length));
236 }
237 if (length < 0) {
238 if (errno == EINTR) {
239 SEN_HILOGD("Continue for EINTR, errno:%{public}d, sendFd_:%{public}d", errno, sendFd_);
240 continue;
241 }
242 if (errno == EAGAIN || errno == EWOULDBLOCK) {
243 SEN_HILOGD("No available data");
244 } else {
245 SEN_HILOGE("recv failed:%{public}s", ::strerror(errno));
246 return ERROR;
247 }
248 return ERR_OK;
249 }
250 };
251 return ERR_OK;
252 }
253
GetSendDataFd()254 int32_t SensorBasicDataChannel::GetSendDataFd()
255 {
256 std::unique_lock<std::mutex> lock(fdLock_);
257 return sendFd_;
258 }
259
GetReceiveDataFd()260 int32_t SensorBasicDataChannel::GetReceiveDataFd()
261 {
262 std::unique_lock<std::mutex> lock(fdLock_);
263 return receiveFd_;
264 }
265
DestroySensorBasicChannel()266 int32_t SensorBasicDataChannel::DestroySensorBasicChannel()
267 {
268 std::unique_lock<std::mutex> lock(fdLock_);
269 if (sendFd_ >= 0) {
270 fdsan_close_with_tag(sendFd_, TAG);
271 sendFd_ = -1;
272 SEN_HILOGD("Close sendFd_ success");
273 }
274 if (receiveFd_ >= 0) {
275 fdsan_close_with_tag(receiveFd_, TAG);
276 receiveFd_ = -1;
277 SEN_HILOGD("Close receiveFd_ success");
278 }
279 return ERR_OK;
280 }
281
GetDataCacheBuf() const282 const std::unordered_map<SensorDescription, SensorData> &SensorBasicDataChannel::GetDataCacheBuf() const
283 {
284 return dataCacheBuf_;
285 }
286
GetSensorStatus() const287 bool SensorBasicDataChannel::GetSensorStatus() const
288 {
289 return isActive_;
290 }
291
SetSensorStatus(bool isActive)292 void SensorBasicDataChannel::SetSensorStatus(bool isActive)
293 {
294 SEN_HILOGD("isActive_:%{public}d", isActive);
295 std::unique_lock<std::mutex> lock(statusLock_);
296 isActive_ = isActive;
297 return;
298 }
299
GetPackageName()300 std::string SensorBasicDataChannel::GetPackageName()
301 {
302 std::unique_lock<std::mutex> lock(pkNameLock_);
303 return packageName_;
304 }
305
SetPackageName(std::string packageName)306 void SensorBasicDataChannel::SetPackageName(std::string packageName)
307 {
308 SEN_HILOGD("SetPackageName in, packageName:%{public}s", packageName.c_str());
309 std::unique_lock<std::mutex> lock(pkNameLock_);
310 packageName_ = packageName;
311 }
312 } // namespace Sensors
313 } // namespace OHOS
314