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