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_native_impl.h"
17
18 #include "securec.h"
19 #include "medical_errors.h"
20 #include "medical_log_domain.h"
21 #include "medical_sensor_service_client.h"
22 #include "medical_sensor_data_channel.h"
23
24 using OHOS::HiviewDFX::HiLog;
25 using OHOS::HiviewDFX::HiLogLabel;
26 using OHOS::Sensors::MedicalSensorDataChannel;
27 using OHOS::Sensors::MedicalSensorServiceClient;
28 using OHOS::Sensors::INVALID_POINTER;
29 using OHOS::Sensors::SUCCESS;
30
31 static const HiLogLabel LABEL = {LOG_CORE, OHOS::MedicalSensorLogDomain::MEDICAL_SENSOR_NATIVE, "AfeNativeAPI"};
32 static bool g_isChannelCreated;
33 static int64_t g_samplingInterval;
34 static int64_t g_reportInterval;
35 static std::mutex subscribeMutex_;
36 static std::mutex chanelMutex_;
37 static std::map<int32_t, const MedicalSensorUser *> g_subscribeMap;
38 static std::map<int32_t, const MedicalSensorUser *> g_unsubscribeMap;
39 static OHOS::sptr<MedicalSensorDataChannel> g_dataChannel;
40
HandleSensorData(struct SensorEvent * events,int32_t num,void * data)41 static void HandleSensorData(struct SensorEvent *events, int32_t num, void *data)
42 {
43 if (events == nullptr || num <= 0) {
44 HiLog::Error(LABEL, "%{public}s events is null or num is invalid", __func__);
45 return;
46 }
47 SensorEvent eventStream;
48 for (int32_t i = 0; i < num; ++i) {
49 eventStream = events[i];
50 if (eventStream.data == nullptr || g_subscribeMap[eventStream.sensorTypeId] == nullptr) {
51 HiLog::Error(LABEL, "%{public}s data or sensorUser is nullptr", __func__);
52 return;
53 }
54 if (g_subscribeMap.find(eventStream.sensorTypeId) == g_subscribeMap.end()) {
55 HiLog::Error(LABEL, "%{public}s sensorTypeId not in g_subscribeMap", __func__);
56 return;
57 }
58 g_subscribeMap[eventStream.sensorTypeId]->callback(&eventStream);
59 }
60 }
61
CreateSensorDataChannel()62 static int32_t CreateSensorDataChannel()
63 {
64 HiLog::Debug(LABEL, "%{public}s", __func__);
65 std::lock_guard<std::mutex> chanelLock(chanelMutex_);
66 if (g_isChannelCreated) {
67 HiLog::Info(LABEL, "%{public}s the channel has already been created", __func__);
68 return SUCCESS;
69 }
70 if (g_dataChannel == nullptr) {
71 g_dataChannel = new (std::nothrow) MedicalSensorDataChannel();
72 if (g_dataChannel == nullptr) {
73 HiLog::Error(LABEL, "%{public}s g_dataChannel is null", __func__);
74 return OHOS::Sensors::ERROR;
75 }
76 }
77 auto ret = g_dataChannel->CreateSensorDataChannel(HandleSensorData, nullptr);
78 if (ret != SUCCESS) {
79 HiLog::Error(LABEL, "%{public}s create data channel failed, ret : %{public}d", __func__, ret);
80 return ret;
81 }
82 auto &client = MedicalSensorServiceClient::GetInstance();
83 ret = client.TransferDataChannel(g_dataChannel);
84 if (ret != SUCCESS) {
85 auto destoryRet = g_dataChannel->DestroySensorDataChannel();
86 HiLog::Error(LABEL, "%{public}s transfer data channel failed, ret : %{public}d, destoryRet : %{public}d",
87 __func__, ret, destoryRet);
88 return ret;
89 }
90 g_isChannelCreated = true;
91 return SUCCESS;
92 }
93
DestroyAfeDataChannel()94 static int32_t DestroyAfeDataChannel()
95 {
96 HiLog::Debug(LABEL, "%{public}s", __func__);
97 std::lock_guard<std::mutex> chanelLock(chanelMutex_);
98 if (!g_isChannelCreated) {
99 HiLog::Info(LABEL, "%{public}s channel has been destroyed", __func__);
100 return SUCCESS;
101 }
102 if (g_dataChannel == nullptr) {
103 HiLog::Error(LABEL, "%{public}s data channel cannot be null", __func__);
104 return INVALID_POINTER;
105 }
106 int32_t ret = g_dataChannel->DestroySensorDataChannel();
107 if (ret != SUCCESS) {
108 HiLog::Error(LABEL, "%{public}s destory data channel failed, ret : %{public}d", __func__, ret);
109 return ret;
110 }
111 MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
112 ret = client.DestroyDataChannel();
113 if (ret != SUCCESS) {
114 HiLog::Error(LABEL, "%{public}s destory service data channel fail, ret : %{public}d", __func__, ret);
115 return ret;
116 }
117 g_isChannelCreated = false;
118 delete g_dataChannel;
119 g_dataChannel = nullptr;
120 return SUCCESS;
121 }
122
GetAllSensors(MedicalSensorInfo ** sensorInfo,int32_t * count)123 int32_t GetAllSensors(MedicalSensorInfo **sensorInfo, int32_t *count)
124 {
125 HiLog::Info(LABEL, "%{public}s begin", __func__);
126 if (sensorInfo == nullptr || count == nullptr) {
127 HiLog::Error(LABEL, "%{public}s sensorInfo or count is null", __func__);
128 return OHOS::Sensors::ERROR;
129 }
130 MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
131 std::vector<OHOS::Sensors::MedicalSensor> sensorList_ = client.GetSensorList();
132 if (sensorList_.empty()) {
133 HiLog::Error(LABEL, "%{public}s get sensor lists failed", __func__);
134 return OHOS::Sensors::ERROR;
135 }
136 *count = sensorList_.size();
137 *sensorInfo = (MedicalSensorInfo *)malloc(sizeof(MedicalSensorInfo) * (*count));
138 if (*sensorInfo == nullptr) {
139 HiLog::Error(LABEL, "%{public}s malloc sensorInfo failed", __func__);
140 return OHOS::Sensors::ERROR;
141 }
142 for (int32_t index = 0; index < *count; index++) {
143 errno_t ret = strcpy_s((*sensorInfo + index)->sensorName, AFE_NAME_MAX_LEN2,
144 sensorList_[index].GetName().c_str());
145 if (ret != EOK) {
146 HiLog::Error(LABEL, "%{public}s strcpy sensorName failed", __func__);
147 return OHOS::Sensors::ERROR;
148 }
149 ret = strcpy_s((*sensorInfo + index)->vendorName, AFE_NAME_MAX_LEN2, sensorList_[index].GetVendor().c_str());
150 if (ret != EOK) {
151 HiLog::Error(LABEL, "%{public}s strcpy vendorName failed", __func__);
152 return OHOS::Sensors::ERROR;
153 }
154 const char *version = std::to_string(sensorList_[index].GetVersion()).c_str();
155 ret = strcpy_s((*sensorInfo + index)->hardwareVersion, AFE_NAME_MAX_LEN2, version);
156 if (ret != EOK) {
157 HiLog::Error(LABEL, "%{public}s strcpy hardwareVersion failed", __func__);
158 return OHOS::Sensors::ERROR;
159 }
160 (*sensorInfo + index)->sensorId = sensorList_[index].GetSensorId();
161 (*sensorInfo + index)->sensorTypeId = sensorList_[index].GetSensorId();
162 }
163 return OHOS::Sensors::SUCCESS;
164 }
165
ActivateSensor(int32_t sensorId,const MedicalSensorUser * user)166 int32_t ActivateSensor(int32_t sensorId, const MedicalSensorUser *user)
167 {
168 HiLog::Info(LABEL, "%{public}s begin", __func__);
169 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
170 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
171 return OHOS::Sensors::ERROR;
172 }
173 if (g_samplingInterval < 0 || g_reportInterval < 0) {
174 HiLog::Error(LABEL, "%{public}s samplingPeroid or g_reportInterval is invalid", __func__);
175 return OHOS::Sensors::ERROR;
176 }
177 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
178 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
179 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
180 return OHOS::Sensors::ERROR;
181 }
182 MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
183 int32_t ret = client.EnableSensor(sensorId, g_samplingInterval, g_reportInterval);
184 g_samplingInterval = -1;
185 g_reportInterval = -1;
186 if (ret != 0) {
187 HiLog::Error(LABEL, "%{public}s enable sensor failed, ret: %{public}d", __func__, ret);
188 g_subscribeMap.erase(sensorId);
189 return OHOS::Sensors::ERROR;
190 }
191 return OHOS::Sensors::SUCCESS;
192 }
193
DeactivateSensor(int32_t sensorId,const MedicalSensorUser * user)194 int32_t DeactivateSensor(int32_t sensorId, const MedicalSensorUser *user)
195 {
196 HiLog::Info(LABEL, "%{public}s begin", __func__);
197 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
198 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
199 return OHOS::Sensors::ERROR;
200 }
201 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
202 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap[sensorId] != user)) {
203 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
204 return OHOS::Sensors::ERROR;
205 }
206 g_subscribeMap.erase(sensorId);
207 g_unsubscribeMap[sensorId] = user;
208 MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
209 int32_t ret = client.DisableSensor(sensorId);
210 if (ret != 0) {
211 HiLog::Error(LABEL, "%{public}s disable sensor failed, ret: %{public}d", __func__, ret);
212 return OHOS::Sensors::ERROR;
213 }
214 return OHOS::Sensors::SUCCESS;
215 }
216
SetBatch(int32_t sensorId,const MedicalSensorUser * user,int64_t samplingInterval,int64_t reportInterval)217 int32_t SetBatch(int32_t sensorId, const MedicalSensorUser *user, int64_t samplingInterval, int64_t reportInterval)
218 {
219 HiLog::Info(LABEL, "%{public}s begin", __func__);
220 if (user == nullptr || sensorId < 0) {
221 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
222 return OHOS::Sensors::ERROR;
223 }
224 if (samplingInterval < 0 || reportInterval < 0) {
225 HiLog::Error(LABEL, "%{public}s samplingInterval or reportInterval is invalid", __func__);
226 return OHOS::Sensors::ERROR;
227 }
228 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
229 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
230 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
231 return OHOS::Sensors::ERROR;
232 }
233 g_samplingInterval = samplingInterval;
234 g_reportInterval = reportInterval;
235 return OHOS::Sensors::SUCCESS;
236 }
237
SubscribeSensor(int32_t sensorId,const MedicalSensorUser * user)238 int32_t SubscribeSensor(int32_t sensorId, const MedicalSensorUser *user)
239 {
240 HiLog::Info(LABEL, "%{public}s begin", __func__);
241 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
242 HiLog::Error(LABEL, "%{public}s user or sensorId is invalid", __func__);
243 return OHOS::Sensors::ERROR;
244 }
245 int32_t ret = CreateSensorDataChannel();
246 if (ret != SUCCESS) {
247 HiLog::Error(LABEL, "%{public}s create sensor data chanel failed", __func__);
248 return OHOS::Sensors::ERROR;
249 }
250 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
251 g_subscribeMap[sensorId] = user;
252 return OHOS::Sensors::SUCCESS;
253 }
254
UnsubscribeSensor(int32_t sensorId,const MedicalSensorUser * user)255 int32_t UnsubscribeSensor(int32_t sensorId, const MedicalSensorUser *user)
256 {
257 HiLog::Info(LABEL, "%{public}s in, sensorId: %{public}d", __func__, sensorId);
258 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
259 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
260 return OHOS::Sensors::ERROR;
261 }
262 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
263 if (g_unsubscribeMap.find(sensorId) == g_unsubscribeMap.end() || g_unsubscribeMap[sensorId] != user) {
264 HiLog::Error(LABEL, "%{public}s deactivate sensorId first", __func__);
265 return OHOS::Sensors::ERROR;
266 }
267 if (g_subscribeMap.empty()) {
268 int32_t ret = DestroyAfeDataChannel();
269 if (ret != SUCCESS) {
270 HiLog::Error(LABEL, "%{public}s destory data channel fail, ret : %{public}d", __func__, ret);
271 return ret;
272 }
273 }
274 g_unsubscribeMap.erase(sensorId);
275 return OHOS::Sensors::SUCCESS;
276 }
277
SetMode(int32_t sensorId,const MedicalSensorUser * user,int32_t mode)278 int32_t SetMode(int32_t sensorId, const MedicalSensorUser *user, int32_t mode)
279 {
280 HiLog::Info(LABEL, "%{public}s begin", __func__);
281 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
282 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
283 return OHOS::Sensors::ERROR;
284 }
285 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
286 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
287 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
288 return OHOS::Sensors::ERROR;
289 }
290 return OHOS::Sensors::SUCCESS;
291 }
292
SetOption(int32_t sensorId,const MedicalSensorUser * user,int32_t option)293 int32_t SetOption(int32_t sensorId, const MedicalSensorUser *user, int32_t option)
294 {
295 HiLog::Info(LABEL, "%{public}s begin, sensorId: %{public}d, opt: %{public}d", __func__, sensorId, option);
296 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
297 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
298 return OHOS::Sensors::ERROR;
299 }
300 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
301 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
302 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
303 return OHOS::Sensors::ERROR;
304 }
305 return OHOS::Sensors::SUCCESS;
306 }