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