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