1 /*
2 * Copyright (C) 2021 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 OHOS_HRIL_BASE_H
17 #define OHOS_HRIL_BASE_H
18
19 #include <any>
20 #include <cstdlib>
21 #include <map>
22 #include <securec.h>
23
24 #include "hdf_remote_service.h"
25 #include "hdf_sbuf_ipc.h"
26 #include "hril_types.h"
27 #include "telephony_log_wrapper.h"
28 #include "v1_2/iril.h"
29 #include "v1_2/iril_callback.h"
30
31 namespace OHOS {
32 namespace Telephony {
33 class IHRilReporter {
34 public:
35 virtual ReqDataInfo *CreateHRilRequest(int32_t serial, int32_t slotId, int32_t request) = 0;
36 virtual void ReleaseHRilRequest(int32_t request, ReqDataInfo *requestInfo) = 0;
37 };
38
39 class HRilBase {
40 public:
41 // The "reply" event processing entry.
42 template<typename T>
43 int32_t ProcessResponse(
44 int32_t code, HRilRadioResponseInfo &responseInfo, const void *response, size_t responseLen);
45 // The "Active reporting" event processing entry.
46 template<typename T>
47 int32_t ProcessNotify(
48 int32_t notifyType, const struct ReportInfo *reportInfo, const void *response, size_t responseLen);
49 void SetRilCallback(const sptr<HDI::Ril::V1_2::IRilCallback> &callback);
50 std::string StringToHex(const char *data, int byteLength);
51
52 protected:
HRilBase(int32_t slotId)53 HRilBase(int32_t slotId) : slotId_(slotId) {}
~HRilBase()54 virtual ~HRilBase() {}
55 HRilNotiType ConvertIntToRadioNoticeType(int32_t indicationType);
56 uint8_t ConvertHexCharToInt(uint8_t c);
57 uint8_t *ConvertHexStringToBytes(const void *response, size_t responseLen);
58 bool ConvertToString(char **dest, const std::string &src);
59 void CopyToCharPoint(char **a, const std::string &temp);
60 HDI::Ril::V1_1::RilRadioResponseInfo BuildIHRilRadioResponseInfo(const HRilRadioResponseInfo &responseInfo);
SafeFrees()61 inline void SafeFrees() {}
62 template<typename M, typename... Ms>
SafeFrees(M & m,Ms &...ms)63 inline void SafeFrees(M &m, Ms &...ms)
64 {
65 if (m != nullptr) {
66 free(m);
67 m = nullptr;
68 }
69 SafeFrees(ms...);
70 }
71
72 template<typename FuncType, typename... ParamTypes>
73 inline int32_t Response(HRilRadioResponseInfo &responseInfo, FuncType &&_func, ParamTypes &&... _args);
74 template<typename FuncType, typename... ParamTypes>
75 inline int32_t Notify(int32_t notifyType, const HRilErrNumber error, FuncType &&_func, ParamTypes &&... _args);
76 int32_t ConvertHexStringToInt(char **response, int32_t index, int32_t length);
StringToCString(const std::string & src)77 inline char *StringToCString(const std::string &src)
78 {
79 return static_cast<char *>(const_cast<char *>(src.c_str()));
80 }
81
82 // get slotid
GetSlotId()83 int32_t GetSlotId() const
84 {
85 return slotId_;
86 }
87 ReqDataInfo *CreateHRilRequest(int32_t serial, int32_t request);
88 template<typename ReqFuncSet, typename FuncPointer, typename... ValueTypes>
89 int32_t RequestVendor(
90 int32_t serial, int32_t requestId, ReqFuncSet reqFuncSet, FuncPointer func, ValueTypes &&... vals);
91
92 protected:
93 std::map<uint32_t, std::any> respMemberFuncMap_;
94 std::map<uint32_t, std::any> notiMemberFuncMap_;
95 sptr<HDI::Ril::V1_2::IRilCallback> callback_ = nullptr;
96
97 private:
98 // Get the function pointer of the event handler.
99 template<typename F>
100 F GetFunc(std::map<uint32_t, std::any> &funcs, uint32_t code);
101
102 private:
103 int32_t slotId_;
104 };
105
106 template<typename ReqFuncSet, typename FuncPointer, typename... ValueTypes>
RequestVendor(int32_t serial,int32_t requestId,ReqFuncSet reqFuncSet,FuncPointer func,ValueTypes &&...vals)107 int32_t HRilBase::RequestVendor(
108 int32_t serial, int32_t requestId, ReqFuncSet reqFuncSet, FuncPointer func, ValueTypes &&... vals)
109 {
110 if (reqFuncSet == nullptr || (reqFuncSet->*func) == nullptr) {
111 TELEPHONY_LOGE("reqFunSet or reqFuncSet->*fun is null");
112 if (callback_ == nullptr) {
113 TELEPHONY_LOGE("callback is null");
114 return HRIL_ERR_NULL_POINT;
115 }
116 HDI::Ril::V1_1::RilRadioResponseInfo responseInfo = { 0 };
117 responseInfo.slotId = GetSlotId();
118 responseInfo.serial = serial;
119 responseInfo.error = HDI::Ril::V1_1::RilErrType::RIL_ERR_VENDOR_NOT_IMPLEMENT;
120 callback_->CommonErrorResponse(responseInfo);
121 return HRIL_ERR_NULL_POINT;
122 }
123
124 ReqDataInfo *requestInfo = CreateHRilRequest(serial, requestId);
125 if (requestInfo == nullptr) {
126 TELEPHONY_LOGE("requestInfo == nullptr: serial=%{public}d, request=%{public}d", serial, requestId);
127 return HRIL_ERR_MEMORY_FULL;
128 }
129
130 (reqFuncSet->*func)(requestInfo, std::forward<ValueTypes>(vals)...);
131 return HRIL_ERR_SUCCESS;
132 }
133
134 template<typename F>
GetFunc(std::map<uint32_t,std::any> & funcs,uint32_t code)135 F HRilBase::GetFunc(std::map<uint32_t, std::any> &funcs, uint32_t code)
136 {
137 auto itFunc = funcs.find(code);
138 if (itFunc != funcs.end()) {
139 return std::any_cast<F>(itFunc->second);
140 }
141 TELEPHONY_LOGE("Can not find Request code in func map: %{public}d!", code);
142 return nullptr;
143 }
144
145 template<typename T>
ProcessResponse(int32_t code,HRilRadioResponseInfo & responseInfo,const void * response,size_t responseLen)146 int32_t HRilBase::ProcessResponse(
147 int32_t code, HRilRadioResponseInfo &responseInfo, const void *response, size_t responseLen)
148 {
149 using RespFunc = int32_t (T::*)(
150 int32_t requestNum, HRilRadioResponseInfo & responseInfo, const void *response, size_t responseLen);
151 auto func = GetFunc<RespFunc>(respMemberFuncMap_, code);
152 if (func != nullptr) {
153 return (static_cast<T *>(this)->*func)(code, responseInfo, response, responseLen);
154 }
155 return HRIL_ERR_INVALID_PARAMETER;
156 }
157
158 template<typename T>
ProcessNotify(int32_t notifyType,const struct ReportInfo * reportInfo,const void * response,size_t responseLen)159 int32_t HRilBase::ProcessNotify(
160 int32_t notifyType, const struct ReportInfo *reportInfo, const void *response, size_t responseLen)
161 {
162 if (reportInfo == nullptr) {
163 return HRIL_ERR_INVALID_PARAMETER;
164 }
165 using NotiFunc = int32_t (T::*)(int32_t notifyType, HRilErrNumber error, const void *response, size_t responseLen);
166 int32_t code = reportInfo->notifyId;
167 HRilErrNumber error = (HRilErrNumber)reportInfo->error;
168 auto func = GetFunc<NotiFunc>(notiMemberFuncMap_, code);
169 if (func != nullptr) {
170 return (static_cast<T *>(this)->*func)(notifyType, error, response, responseLen);
171 }
172 return HRIL_ERR_INVALID_PARAMETER;
173 }
174
175 template<typename FuncType, typename... ParamTypes>
Response(HRilRadioResponseInfo & responseInfo,FuncType && _func,ParamTypes &&..._args)176 inline int32_t HRilBase::Response(HRilRadioResponseInfo &responseInfo, FuncType &&_func, ParamTypes &&... _args)
177 {
178 if (callback_ == nullptr || _func == nullptr) {
179 TELEPHONY_LOGE("callback_ or _func is null");
180 return HRIL_ERR_NULL_POINT;
181 }
182 (callback_->*(_func))(BuildIHRilRadioResponseInfo(responseInfo), std::forward<ParamTypes>(_args)...);
183 return HRIL_ERR_SUCCESS;
184 }
185
186 template<typename FuncType, typename... ParamTypes>
Notify(int32_t notifyType,const HRilErrNumber error,FuncType && _func,ParamTypes &&..._args)187 inline int32_t HRilBase::Notify(int32_t notifyType, const HRilErrNumber error, FuncType &&_func, ParamTypes &&... _args)
188 {
189 if (callback_ == nullptr) {
190 TELEPHONY_LOGE("callback_ is null");
191 return HRIL_ERR_NULL_POINT;
192 }
193 HDI::Ril::V1_1::RilRadioResponseInfo mResponseInfo = { 0 };
194 mResponseInfo.slotId = GetSlotId();
195 mResponseInfo.type = (HDI::Ril::V1_1::RilResponseTypes)notifyType;
196 (callback_->*(_func))(mResponseInfo, std::forward<ParamTypes>(_args)...);
197 return HRIL_ERR_SUCCESS;
198 }
199 } // namespace Telephony
200 } // namespace OHOS
201 #endif // OHOS_HRIL_UTILS_H
202