• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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