• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Chipsea Technologies (Shenzhen) Corp., 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 "medical_sensor_basic_data_channel.h"
17 
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <unistd.h>
21 
22 #include "dmd_report.h"
23 #include "medical_errors.h"
24 #include "medical_log_domain.h"
25 
26 namespace OHOS {
27 namespace Sensors {
28 using namespace OHOS::HiviewDFX;
29 
30 namespace {
31 constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::MEDICAL_SENSOR_UTILS, "SensorBasicChannel" };
32 constexpr int32_t DEFAULT_CHANNEL_SIZE = 2 * 1024;
33 constexpr int32_t SOCKET_PAIR_SIZE = 2;
34 }  // namespace
35 
MedicalSensorBasicDataChannel()36 MedicalSensorBasicDataChannel::MedicalSensorBasicDataChannel()
37     : sendFd_(INVALID_FD), receiveFd_(INVALID_FD), isActive_(false)
38 {
39     HiLog::Debug(LABEL, "%{public}s isActive_ : %{public}d, sendFd: %{public}d", __func__, isActive_, sendFd_);
40 }
41 
CreateSensorBasicChannel(size_t sendSize,size_t receiveSize)42 int32_t MedicalSensorBasicDataChannel::CreateSensorBasicChannel(size_t sendSize, size_t receiveSize)
43 {
44     if ((sendFd_ != INVALID_FD) || (receiveFd_ != INVALID_FD)) {
45         HiLog::Debug(LABEL, "%{public}s already create socketpair", __func__);
46         return ERR_OK;
47     }
48 
49     int32_t socketPair[SOCKET_PAIR_SIZE] = { 0 };
50     if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketPair) != 0) {
51         DmdReport::ReportException(SENSOR_DATA_CHANNEL_EXCEPTION, "CreateSensorBasicChannel",
52                                    SENSOR_CHANNEL_SOCKET_CREATE_ERR);
53         HiLog::Error(LABEL, "%{public}s create socketpair failed", __func__);
54         sendFd_ = INVALID_FD;
55         receiveFd_ = INVALID_FD;
56         return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
57     }
58     // set socket attr
59     setsockopt(socketPair[0], SOL_SOCKET, SO_SNDBUF, &sendSize, sizeof(sendSize));
60     setsockopt(socketPair[1], SOL_SOCKET, SO_RCVBUF, &receiveSize, sizeof(receiveSize));
61     int32_t bufferSize = DEFAULT_CHANNEL_SIZE;
62     int32_t ret = setsockopt(socketPair[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
63     if (ret != 0) {
64         HiLog::Error(LABEL, "%{public}s setsockopt socketpair 0 failed", __func__);
65         return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
66     }
67     ret = setsockopt(socketPair[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
68     if (ret != 0) {
69         HiLog::Error(LABEL, "%{public}s setsockopt socketpair 1 failed", __func__);
70         return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
71     }
72     ret = fcntl(socketPair[0], F_SETFL, O_NONBLOCK);
73     if (ret != 0) {
74         HiLog::Error(LABEL, "%{public}s fcntl socketpair 0 failed", __func__);
75         return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
76     }
77     ret = fcntl(socketPair[1], F_SETFL, O_NONBLOCK);
78     if (ret != 0) {
79         HiLog::Error(LABEL, "%{public}s fcntl socketpair 1 failed", __func__);
80         return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
81     }
82     sendFd_ = socketPair[0];
83     receiveFd_ = socketPair[1];
84     HiLog::Debug(LABEL, "%{public}s create socketpair success, receiveFd_ : %{public}d, sendFd_ : %{public}d", __func__,
85                  receiveFd_, sendFd_);
86     return ERR_OK;
87 }
88 
CreateSensorBasicChannel(MessageParcel & data)89 int32_t MedicalSensorBasicDataChannel::CreateSensorBasicChannel(MessageParcel &data)
90 {
91     HiLog::Debug(LABEL, "%{public}s begin", __func__);
92     if ((sendFd_ != INVALID_FD) || (receiveFd_ != INVALID_FD)) {
93         HiLog::Debug(LABEL, "%{public}s already create socketpair", __func__);
94         return ERR_OK;
95     }
96     int32_t tmpFd = data.ReadFileDescriptor();
97     if (tmpFd < 0) {
98         HiLog::Error(LABEL, "%{public}s ReadFileDescriptor failed", __func__);
99         sendFd_ = INVALID_FD;
100         return SENSOR_CHANNEL_DUP_ERR;
101     }
102     sendFd_ = dup(tmpFd);
103     if (sendFd_ < 0) {
104         HiLog::Error(LABEL, "%{public}s dup FileDescriptor failed", __func__);
105         sendFd_ = INVALID_FD;
106         return SENSOR_CHANNEL_DUP_ERR;
107     }
108     return ERR_OK;
109 }
110 
~MedicalSensorBasicDataChannel()111 MedicalSensorBasicDataChannel::~MedicalSensorBasicDataChannel()
112 {
113     DestroySensorBasicChannel();
114 }
115 
SendToBinder(MessageParcel & data)116 int32_t MedicalSensorBasicDataChannel::SendToBinder(MessageParcel &data)
117 {
118     HiLog::Debug(LABEL, "%{public}s sendFd: %{public}d", __func__, sendFd_);
119     if (sendFd_ < 0) {
120         HiLog::Error(LABEL, "%{public}s sendFd FileDescriptor error", __func__);
121         return SENSOR_CHANNEL_SENDFD_ERR;
122     }
123     bool result = data.WriteFileDescriptor(sendFd_);
124     if (!result) {
125         HiLog::Error(LABEL, "%{public}s send sendFd_ failed", __func__);
126         CloseSendFd();
127         return SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR;
128     }
129     return ERR_OK;
130 }
131 
CloseSendFd()132 void MedicalSensorBasicDataChannel::CloseSendFd()
133 {
134     if (sendFd_ != INVALID_FD) {
135         close(sendFd_);
136         sendFd_ = INVALID_FD;
137         HiLog::Debug(LABEL, "%{public}s close sendFd_", __func__);
138     }
139 }
140 
SendData(const void * vaddr,size_t size)141 int32_t MedicalSensorBasicDataChannel::SendData(const void *vaddr, size_t size)
142 {
143     if (vaddr == nullptr || sendFd_ < 0) {
144         HiLog::Error(LABEL, "%{public}s failed, param is invalid", __func__);
145         return SENSOR_CHANNEL_SEND_ADDR_ERR;
146     }
147     ssize_t length;
148     do {
149         length = send(sendFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
150     } while (errno == EINTR);
151     if (length < 0) {
152         HiLog::Error(LABEL, "%{public}s send fail : %{public}d, length = %{public}d", __func__, errno, (int32_t)length);
153         return SENSOR_CHANNEL_SEND_DATA_ERR;
154     }
155     return ERR_OK;
156 }
157 
ReceiveData(void * vaddr,size_t size)158 int32_t MedicalSensorBasicDataChannel::ReceiveData(void *vaddr, size_t size)
159 {
160     if (vaddr == nullptr || (receiveFd_ == INVALID_FD)) {
161         HiLog::Error(LABEL, "%{public}s failed, vaddr is null or receiveFd_ invalid", __func__);
162         return SENSOR_CHANNEL_RECEIVE_ADDR_ERR;
163     }
164     ssize_t length;
165     do {
166         length = recv(receiveFd_, vaddr, size, MSG_DONTWAIT);
167     } while (errno == EINTR);
168     if (length < 0) {
169         return 0;
170     }
171     return length;
172 }
173 
GetSendDataFd() const174 int32_t MedicalSensorBasicDataChannel::GetSendDataFd() const
175 {
176     return sendFd_;
177 }
178 
GetReceiveDataFd() const179 int32_t MedicalSensorBasicDataChannel::GetReceiveDataFd() const
180 {
181     return receiveFd_;
182 }
183 
DestroySensorBasicChannel()184 int32_t MedicalSensorBasicDataChannel::DestroySensorBasicChannel()
185 {
186     if (sendFd_ >= 0) {
187         close(sendFd_);
188         sendFd_ = INVALID_FD;
189         HiLog::Debug(LABEL, "%{public}s close sendFd_ success", __func__);
190     }
191     if (receiveFd_ >= 0) {
192         close(receiveFd_);
193         receiveFd_ = INVALID_FD;
194         HiLog::Debug(LABEL, "%{public}s close receiveFd_ success", __func__);
195     }
196     return ERR_OK;
197 }
198 
GetDataCacheBuf() const199 const std::unordered_map<uint32_t, struct SensorEvent> &MedicalSensorBasicDataChannel::GetDataCacheBuf() const
200 {
201     return dataCacheBuf_;
202 }
203 
GetSensorStatus() const204 bool MedicalSensorBasicDataChannel::GetSensorStatus() const
205 {
206     return isActive_;
207 }
208 
SetSensorStatus(bool isActive)209 void MedicalSensorBasicDataChannel::SetSensorStatus(bool isActive)
210 {
211     HiLog::Debug(LABEL, "%{public}s isActive_ : %{public}d", __func__, isActive);
212     std::unique_lock<std::mutex> lock(statusLock_);
213     isActive_ = isActive;
214     return;
215 }
216 }  // namespace Sensors
217 }  // namespace OHOS
218