1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., 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 #ifndef TEL_RIL_BASE_H
17 #define TEL_RIL_BASE_H
18 
19 #include <any>
20 #include <mutex>
21 
22 #include "event_runner.h"
23 #include "functional"
24 #include "tel_ril_base_parcel.h"
25 #include "tel_ril_types.h"
26 #include "iremote_broker.h"
27 #include "observer_handler.h"
28 #include "radio_event.h"
29 #include "sim_constant.h"
30 #include "tel_ril_common.h"
31 #include "tel_ril_handler.h"
32 #include "telephony_errors.h"
33 #include "telephony_log_wrapper.h"
34 #include "telephony_types.h"
35 #include "v1_3/iril.h"
36 
37 namespace OHOS {
38 namespace Telephony {
39 struct TelRilRequest {
40     int32_t serialId_ = 0;
41     AppExecFwk::InnerEvent::Pointer &pointer_ = nullptr_;
42 
TelRilRequestTelRilRequest43     TelRilRequest(int32_t serialId, const AppExecFwk::InnerEvent::Pointer &pointer)
44     {
45         serialId_ = serialId;
46         pointer_ = std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(pointer));
47     }
48 private:
49     AppExecFwk::InnerEvent::Pointer nullptr_ = AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
50 };
51 
52 class TelRilBase {
53 public:
54     TelRilBase(int32_t slotId, sptr<HDI::Ril::V1_3::IRil> rilInterface,
55         std::shared_ptr<ObserverHandler> observerHandler, std::shared_ptr<TelRilHandler> handler);
56     virtual ~TelRilBase() = default;
57 
58     static std::shared_ptr<TelRilRequest> CreateTelRilRequest(const AppExecFwk::InnerEvent::Pointer &result);
59     void ResetRilInterface(sptr<HDI::Ril::V1_3::IRil> rilInterface);
60     static std::shared_ptr<TelRilRequest> FindTelRilRequest(const RadioResponseInfo &responseInfo);
61     int32_t ErrorResponse(std::shared_ptr<TelRilRequest> telRilRequest, const RadioResponseInfo &responseInfo);
62 
63 protected:
64     template<typename FuncType, typename... ParamTypes>
65     inline int32_t Request(const char *funcName, const AppExecFwk::InnerEvent::Pointer &response, FuncType &&_func,
66         ParamTypes &&... _args);
67     inline RadioResponseInfo BuildHRilRadioResponseInfo(const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo);
68     inline int32_t Response(const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo);
69     template<typename T>
70     inline int32_t Response(const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo, T data);
71     template<typename T>
72     inline int32_t Response(
73         const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo, std::shared_ptr<T> data);
74     template<typename T>
75     inline int32_t Response(const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo,
76         std::function<std::shared_ptr<T>(std::shared_ptr<TelRilRequest>)> getDataFunc);
77     template<typename T>
78     inline int32_t Response(const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo,
79         std::function<T(std::shared_ptr<TelRilRequest>)> getDataFunc);
80     inline int32_t Notify(const char *funcName, RadioEvent notifyId);
81     template<typename T>
82     inline int32_t Notify(const char *funcName, std::shared_ptr<T> data, RadioEvent notifyId);
83     inline int32_t ConfirmSupplementOfTelRilRequestInfo(
84         const char *funcName, std::shared_ptr<TelRilRequest> telRilRequest);
85     template<typename T>
86     inline int32_t SendEventData(
87         const char *funcName, uint32_t eventId, std::shared_ptr<OHOS::AppExecFwk::EventHandler> handler, T data);
88 
89 protected:
90     std::shared_ptr<ObserverHandler> observerHandler_;
91     sptr<HDI::Ril::V1_3::IRil> rilInterface_;
92     int32_t slotId_;
93 
94 private:
95     static int32_t GetNextSerialId(void);
96     int32_t GetSerialId(const AppExecFwk::InnerEvent::Pointer &response);
97     template<typename T>
98     inline int32_t SendHandlerEvent(const char *funcName, std::shared_ptr<TelRilRequest> telRilRequest,
99         std::function<T(std::shared_ptr<TelRilRequest>)> getDataFunc);
100     void DfxWriteCallFaultEvent(std::shared_ptr<TelRilRequest> telRilRequest, const int32_t error);
101 
102 private:
103     static std::atomic_int nextSerialId_;
104     static std::unordered_map<int32_t, std::shared_ptr<TelRilRequest>> requestMap_;
105     static std::mutex requestLock_;
106     static std::shared_ptr<TelRilHandler> handler_;
107 };
108 
109 template<typename FuncType, typename... ParamTypes>
Request(const char * funcName,const AppExecFwk::InnerEvent::Pointer & response,FuncType && _func,ParamTypes &&..._args)110 inline int32_t TelRilBase::Request(const char *funcName, const AppExecFwk::InnerEvent::Pointer &response,
111     FuncType &&_func, ParamTypes &&... _args)
112 {
113     if (rilInterface_ == nullptr) {
114         TELEPHONY_LOGE("%{public}s() rilInterface_ is null", funcName);
115         return TELEPHONY_ERR_LOCAL_PTR_NULL;
116     }
117     std::shared_ptr<TelRilRequest> telRilRequest = CreateTelRilRequest(response);
118     if (telRilRequest == nullptr) {
119         TELEPHONY_LOGE("%{public}s() telRilRequest is null", funcName);
120         return TELEPHONY_ERR_LOCAL_PTR_NULL;
121     }
122     return (rilInterface_->*(_func))(slotId_, telRilRequest->serialId_, std::forward<ParamTypes>(_args)...);
123 }
124 
Response(const char * funcName,const HDI::Ril::V1_1::RilRadioResponseInfo & iResponseInfo)125 inline int32_t TelRilBase::Response(const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo)
126 {
127     auto getDataFunc = [&iResponseInfo](std::shared_ptr<TelRilRequest> telRilRequest) {
128         std::shared_ptr<RadioResponseInfo> result = std::make_shared<RadioResponseInfo>();
129         result->flag = telRilRequest->pointer_->GetParam();
130         result->error = static_cast<ErrType>(iResponseInfo.error);
131         result->serial = iResponseInfo.serial;
132         return result;
133     };
134     return Response<RadioResponseInfo>(funcName, iResponseInfo, getDataFunc);
135 }
136 
137 template<typename T>
Response(const char * funcName,const HDI::Ril::V1_1::RilRadioResponseInfo & iResponseInfo,T data)138 inline int32_t TelRilBase::Response(
139     const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo, T data)
140 {
141     auto getDataFunc = [data](std::shared_ptr<TelRilRequest> telRilRequest) { return data; };
142     return Response<T>(funcName, iResponseInfo, getDataFunc);
143 }
144 
145 template<typename T>
Response(const char * funcName,const HDI::Ril::V1_1::RilRadioResponseInfo & iResponseInfo,std::shared_ptr<T> data)146 inline int32_t TelRilBase::Response(
147     const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo, std::shared_ptr<T> data)
148 {
149     if (data == nullptr) {
150         TELEPHONY_LOGE("Response func %{public}s data  is null", funcName);
151         return TELEPHONY_ERR_LOCAL_PTR_NULL;
152     }
153     auto getDataFunc = [&data](std::shared_ptr<TelRilRequest> telRilRequest) { return data; };
154     return Response<T>(funcName, iResponseInfo, getDataFunc);
155 }
156 
157 template<typename T>
Response(const char * funcName,const HDI::Ril::V1_1::RilRadioResponseInfo & iResponseInfo,std::function<std::shared_ptr<T> (std::shared_ptr<TelRilRequest>)> getDataFunc)158 inline int32_t TelRilBase::Response(const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo,
159     std::function<std::shared_ptr<T>(std::shared_ptr<TelRilRequest>)> getDataFunc)
160 {
161     return Response<std::shared_ptr<T>>(funcName, iResponseInfo, getDataFunc);
162 }
163 
164 template<typename T>
Response(const char * funcName,const HDI::Ril::V1_1::RilRadioResponseInfo & iResponseInfo,std::function<T (std::shared_ptr<TelRilRequest>)> getDataFunc)165 inline int32_t TelRilBase::Response(const char *funcName, const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo,
166     std::function<T(std::shared_ptr<TelRilRequest>)> getDataFunc)
167 {
168     const auto &radioResponseInfo = BuildHRilRadioResponseInfo(iResponseInfo);
169     std::shared_ptr<TelRilRequest> telRilRequest = FindTelRilRequest(radioResponseInfo);
170     if (telRilRequest == nullptr || telRilRequest->pointer_ == nullptr) {
171         TELEPHONY_LOGE("func %{public}s telRilReques or telRilRequest->pointer or data is null", funcName);
172         return TELEPHONY_ERR_ARGUMENT_INVALID;
173     }
174     if (radioResponseInfo.error != ErrType::NONE) {
175         return ErrorResponse(telRilRequest, radioResponseInfo);
176     }
177     return SendHandlerEvent<T>(funcName, telRilRequest, getDataFunc);
178 }
179 
180 template<typename T>
SendHandlerEvent(const char * funcName,std::shared_ptr<TelRilRequest> telRilRequest,std::function<T (std::shared_ptr<TelRilRequest>)> getDataFunc)181 inline int32_t TelRilBase::SendHandlerEvent(const char *funcName, std::shared_ptr<TelRilRequest> telRilRequest,
182     std::function<T(std::shared_ptr<TelRilRequest>)> getDataFunc)
183 {
184     auto handler = telRilRequest->pointer_->GetOwner();
185     if (handler == nullptr && strcmp(funcName, "SetDeviceStateResponse") != 0 &&
186         strcmp(funcName, "SetNotificationFilterResponse") != 0) {
187         TELEPHONY_LOGE("func %{public}s handler == nullptr !!!", funcName);
188         return TELEPHONY_ERR_LOCAL_PTR_NULL;
189     }
190     return SendEventData<T>(funcName, telRilRequest->pointer_->GetInnerEventId(), handler, getDataFunc(telRilRequest));
191 }
192 
193 template<typename T>
SendEventData(const char * funcName,uint32_t eventId,std::shared_ptr<OHOS::AppExecFwk::EventHandler> handler,T data)194 inline int32_t TelRilBase::SendEventData(
195     const char *funcName, uint32_t eventId, std::shared_ptr<OHOS::AppExecFwk::EventHandler> handler, T data)
196 {
197     if (!TelEventHandler::SendTelEvent(handler, eventId, data)) {
198         TELEPHONY_LOGE("func %{public}s Send eventId:%{public}d is failed!", funcName, eventId);
199         return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
200     }
201     TELEPHONY_LOGD("func %{public}s Send eventId:%{public}d finish", funcName, eventId);
202     return TELEPHONY_ERR_SUCCESS;
203 }
204 
205 template<typename T>
Notify(const char * funcName,std::shared_ptr<T> data,RadioEvent notifyId)206 inline int32_t TelRilBase::Notify(const char *funcName, std::shared_ptr<T> data, RadioEvent notifyId)
207 {
208     if (observerHandler_ == nullptr || data == nullptr) {
209         TELEPHONY_LOGE("%{public}s() observerHandler_ or data is nullptr", funcName);
210         return TELEPHONY_ERR_LOCAL_PTR_NULL;
211     }
212     TELEPHONY_LOGD("%{public}s() notify event %{public}d notifyId slotId:%{public}d", funcName, notifyId, slotId_);
213     observerHandler_->NotifyObserver(notifyId, data);
214     return TELEPHONY_ERR_SUCCESS;
215 }
216 
Notify(const char * funcName,RadioEvent notifyId)217 inline int32_t TelRilBase::Notify(const char *funcName, RadioEvent notifyId)
218 {
219     if (observerHandler_ == nullptr) {
220         TELEPHONY_LOGE("%{public}s() observerHandler_  is nullptr", funcName);
221         return TELEPHONY_ERR_LOCAL_PTR_NULL;
222     }
223     TELEPHONY_LOGD("%{public}s() notify event %{public}d notifyId slotId:%{public}d", funcName, notifyId, slotId_);
224     observerHandler_->NotifyObserver(notifyId);
225     return TELEPHONY_ERR_SUCCESS;
226 }
227 
BuildHRilRadioResponseInfo(const HDI::Ril::V1_1::RilRadioResponseInfo & iResponseInfo)228 inline RadioResponseInfo TelRilBase::BuildHRilRadioResponseInfo(
229     const HDI::Ril::V1_1::RilRadioResponseInfo &iResponseInfo)
230 {
231     RadioResponseInfo responseInfo = { 0 };
232     responseInfo.flag = iResponseInfo.flag;
233     responseInfo.serial = iResponseInfo.serial;
234     responseInfo.error = (ErrType)iResponseInfo.error;
235     responseInfo.type = (ResponseTypes)iResponseInfo.type;
236     return responseInfo;
237 }
238 
ConfirmSupplementOfTelRilRequestInfo(const char * funcName,std::shared_ptr<TelRilRequest> telRilRequest)239 inline int32_t TelRilBase::ConfirmSupplementOfTelRilRequestInfo(
240     const char *funcName, std::shared_ptr<TelRilRequest> telRilRequest)
241 {
242     if (telRilRequest == nullptr || telRilRequest->pointer_ == nullptr) {
243         TELEPHONY_LOGE("func %{public}s telRilReques or telRilRequest->pointer or data is null", funcName);
244         return TELEPHONY_ERR_ARGUMENT_INVALID;
245     }
246     auto handler = telRilRequest->pointer_->GetOwner();
247     if (handler == nullptr) {
248         TELEPHONY_LOGE("func %{public}s handler is nullptr !!!", funcName);
249         return TELEPHONY_ERR_LOCAL_PTR_NULL;
250     }
251     return TELEPHONY_SUCCESS;
252 }
253 } // namespace Telephony
254 } // namespace OHOS
255 #endif // TEL_RIL_BASE_H
256