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