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