• 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     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