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_service_client.h"
17 
18 #include <sys/socket.h>
19 #include <thread>
20 #include <unistd.h>
21 #include <vector>
22 
23 #include "death_recipient_template.h"
24 #include "dmd_report.h"
25 #include "ipc_skeleton.h"
26 #include "medical_sensor_service_proxy.h"
27 #include "medical_errors.h"
28 #include "medical_log_domain.h"
29 #include "system_ability_definition.h"
30 
31 namespace OHOS {
32 namespace Sensors {
33 using namespace OHOS::HiviewDFX;
34 
35 namespace {
36 constexpr HiLogLabel LABEL = {
37     LOG_CORE, MedicalSensorLogDomain::MEDICAL_SENSOR_FRAMEWORK, "MedicalSensorServiceClient"
38 };
39 constexpr int32_t GET_SERVICE_MAX_COUNT = 30;
40 constexpr uint32_t WAIT_MS = 200;
41 }  // namespace
42 
InitServiceClient()43 int32_t MedicalSensorServiceClient::InitServiceClient()
44 {
45     HiLog::Debug(LABEL, "%{public}s begin", __func__);
46     std::lock_guard<std::mutex> clientLock(clientMutex_);
47     if (afeServer_ != nullptr) {
48         HiLog::Debug(LABEL, "%{public}s already init", __func__);
49         return ERR_OK;
50     }
51     if (afeClientStub_ == nullptr) {
52         afeClientStub_ = new (std::nothrow) MedicalSensorClientStub();
53     }
54     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
55     if (systemAbilityManager == nullptr) {
56         HiLog::Error(LABEL, "%{public}s systemAbilityManager cannot be null", __func__);
57         return SENSOR_NATIVE_SAM_ERR;
58     }
59     int32_t retry = 0;
60     while (retry < GET_SERVICE_MAX_COUNT) {
61         afeServer_ = iface_cast<IMedicalSensorService>(
62             systemAbilityManager->GetSystemAbility(MEDICAL_SENSOR_SERVICE_ABILITY_ID));
63         if (afeServer_ != nullptr) {
64             HiLog::Debug(LABEL, "%{public}s get service success, retry : %{public}d", __func__, retry);
65             serviceDeathObserver_ =
66                 new (std::nothrow) DeathRecipientTemplate(*const_cast<MedicalSensorServiceClient *>(this));
67             if (serviceDeathObserver_ != nullptr) {
68                 afeServer_->AsObject()->AddDeathRecipient(serviceDeathObserver_);
69             }
70             afeList_ = afeServer_->GetSensorList();
71             return ERR_OK;
72         }
73         HiLog::Warn(LABEL, "%{public}s get service failed, retry : %{public}d", __func__, retry);
74         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
75         retry++;
76     }
77     DmdReport::ReportException(SENSOR_SERVICE_EXCEPTION, "InitServiceClient", SENSOR_NATIVE_GET_SERVICE_ERR);
78     HiLog::Error(LABEL, "%{public}s get service failed", __func__);
79     return SENSOR_NATIVE_GET_SERVICE_ERR;
80 }
81 
IsValidSensorId(uint32_t sensorId)82 bool MedicalSensorServiceClient::IsValidSensorId(uint32_t sensorId)
83 {
84     if (afeList_.empty()) {
85         HiLog::Error(LABEL, "%{public}s afeList_ cannot be empty", __func__);
86         return false;
87     }
88     for (auto &sensor : afeList_) {
89         HiLog::Debug(LABEL, "%{public}s sensor.GetSensorId() = %{public}u", __func__, sensor.GetSensorId());
90         if (sensor.GetSensorId() == sensorId) {
91             return true;
92         }
93     }
94     return false;
95 }
96 
EnableSensor(uint32_t sensorId,int64_t samplingPeriod,int64_t maxReportDelay)97 int32_t MedicalSensorServiceClient::EnableSensor(uint32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay)
98 {
99     HiLog::Debug(LABEL, "%{public}s begin, sensorId = %{public}u", __func__, sensorId);
100     if (!IsValidSensorId(sensorId)) {
101         HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
102         return SENSOR_NATIVE_SAM_ERR;
103     }
104     int32_t ret = InitServiceClient();
105     if (ret != ERR_OK) {
106         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
107         return ret;
108     }
109     ret = afeServer_->EnableSensor(sensorId, samplingPeriod, maxReportDelay);
110     if (ret == ERR_OK) {
111         UpdateSensorInfoMap(sensorId, samplingPeriod, maxReportDelay);
112     }
113     return ret;
114 }
115 
DisableSensor(uint32_t sensorId)116 int32_t MedicalSensorServiceClient::DisableSensor(uint32_t sensorId)
117 {
118     HiLog::Debug(LABEL, "%{public}s begin", __func__);
119     if (!IsValidSensorId(sensorId)) {
120         HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
121         return SENSOR_NATIVE_SAM_ERR;
122     }
123     int32_t ret = InitServiceClient();
124     if (ret != ERR_OK) {
125         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
126         return ret;
127     }
128     ret = afeServer_->DisableSensor(sensorId);
129     if (ret == ERR_OK) {
130         DeleteSensorInfoItem(sensorId);
131     }
132     return ret;
133 }
134 
RunCommand(uint32_t sensorId,int32_t cmdType,int32_t params)135 int32_t MedicalSensorServiceClient::RunCommand(uint32_t sensorId, int32_t cmdType, int32_t params)
136 {
137     HiLog::Debug(LABEL, "%{public}s begin", __func__);
138     if (!IsValidSensorId(sensorId)) {
139         HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
140         return SENSOR_NATIVE_SAM_ERR;
141     }
142     int32_t ret = InitServiceClient();
143     if (ret != ERR_OK) {
144         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
145         return ret;
146     }
147     ret = afeServer_->RunCommand(sensorId, cmdType, params);
148     if (ret != ERR_OK) {
149         HiLog::Error(LABEL, "%{public}s RunCommand failed", __func__);
150         return ret;
151     }
152     return ret;
153 }
154 
GetSensorList()155 std::vector<MedicalSensor> MedicalSensorServiceClient::GetSensorList()
156 {
157     HiLog::Debug(LABEL, "%{public}s begin", __func__);
158     int32_t ret = InitServiceClient();
159     if (ret != ERR_OK) {
160         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
161         return {};
162     }
163     if (afeList_.empty()) {
164         HiLog::Error(LABEL, "%{public}s afeList_ cannot be empty", __func__);
165     }
166     return afeList_;
167 }
168 
TransferDataChannel(sptr<MedicalSensorDataChannel> afeDataChannel)169 int32_t MedicalSensorServiceClient::TransferDataChannel(sptr<MedicalSensorDataChannel> afeDataChannel)
170 {
171     HiLog::Debug(LABEL, "%{public}s begin", __func__);
172     dataChannel_ = afeDataChannel;
173     int32_t ret = InitServiceClient();
174     if (ret != ERR_OK) {
175         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
176         return ret;
177     }
178     return afeServer_->TransferDataChannel(afeDataChannel, afeClientStub_);
179 }
180 
DestroyDataChannel()181 int32_t MedicalSensorServiceClient::DestroyDataChannel()
182 {
183     HiLog::Debug(LABEL, "%{public}s begin", __func__);
184     int32_t ret = InitServiceClient();
185     if (ret != ERR_OK) {
186         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
187         return ret;
188     }
189     return afeServer_->DestroySensorChannel(afeClientStub_);
190 }
191 
ProcessDeathObserver(const wptr<IRemoteObject> & object)192 void MedicalSensorServiceClient::ProcessDeathObserver(const wptr<IRemoteObject> &object)
193 {
194     HiLog::Debug(LABEL, "%{public}s begin", __func__);
195     (void)object;
196     if (dataChannel_ == nullptr) {
197         HiLog::Error(LABEL, "%{public}s dataChannel_ cannot be null", __func__);
198         return;
199     }
200     // STEP1 : Destroy revious data channel
201     dataChannel_->DestroySensorDataChannel();
202 
203     // STEP2 : Restore data channel
204     dataChannel_->RestoreSensorDataChannel();
205 
206     // STEP3 : Clear sensorlist and afeServer_
207     afeList_.clear();
208     afeServer_ = nullptr;
209 
210     // STEP4 : ReGet hsensors  3601 service
211     int32_t ret = InitServiceClient();
212     if (ret != ERR_OK) {
213         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
214         dataChannel_->DestroySensorDataChannel();
215         return;
216     }
217 
218     // STEP5 : Retransfer new channel to hsensors
219     afeServer_->TransferDataChannel(dataChannel_, afeClientStub_);
220 
221     // STEP6 : Restore MedicalSensor status
222     std::lock_guard<std::mutex> mapLock(mapMutex_);
223     for (const auto &it : sensorInfoMap_) {
224         afeServer_->EnableSensor(it.first, it.second.GetSamplingPeriodNs(), it.second.GetMaxReportDelayNs());
225     }
226     HiLog::Debug(LABEL, "%{public}s end", __func__);
227 }
228 
UpdateSensorInfoMap(uint32_t sensorId,int64_t samplingPeriod,int64_t maxReportDelay)229 void MedicalSensorServiceClient::UpdateSensorInfoMap(uint32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay)
230 {
231     HiLog::Debug(LABEL, "%{public}s begin", __func__);
232     std::lock_guard<std::mutex> mapLock(mapMutex_);
233     MedicalSensorBasicInfo sensorInfo;
234     sensorInfo.SetSamplingPeriodNs(samplingPeriod);
235     sensorInfo.SetMaxReportDelayNs(maxReportDelay);
236     sensorInfo.SetSensorState(MedicalSensorState::SENSOR_ENABLED);
237     sensorInfoMap_[sensorId] = sensorInfo;
238     return;
239 }
240 
DeleteSensorInfoItem(uint32_t sensorId)241 void MedicalSensorServiceClient::DeleteSensorInfoItem(uint32_t sensorId)
242 {
243     HiLog::Debug(LABEL, "%{public}s begin", __func__);
244     std::lock_guard<std::mutex> mapLock(mapMutex_);
245     auto it = sensorInfoMap_.find(sensorId);
246     if (it != sensorInfoMap_.end()) {
247         sensorInfoMap_.erase(it);
248     }
249     return;
250 }
251 
SetOption(uint32_t sensorId,uint32_t opt)252 int32_t MedicalSensorServiceClient::SetOption(uint32_t sensorId, uint32_t opt)
253 {
254     HiLog::Debug(LABEL, "%{public}s begin", __func__);
255     if (!IsValidSensorId(sensorId)) {
256         HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
257         return SENSOR_NATIVE_SAM_ERR;
258     }
259     int32_t ret = InitServiceClient();
260     if (ret != ERR_OK) {
261         HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
262         return ret;
263     }
264 
265     return afeServer_->SetOption(sensorId, opt);
266 }
267 }  // namespace Sensors
268 }  // namespace OHOS
269