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