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 #include "vtp_instance.h"
17
18 #include <algorithm>
19 #include <cstdarg>
20 #include <thread>
21 #include <unistd.h>
22
23 #include "common_inner.h"
24 #include "fillptypes.h"
25 #include "securec.h"
26 #include "softbus_adapter_crypto.h"
27 #include "stream_common.h"
28 #include "softbus_hisysevt_nstack.h"
29
30 namespace Communication {
31 namespace SoftBus {
32 namespace {
UpdateVtpLogLevel()33 int UpdateVtpLogLevel()
34 {
35 return FILLP_DBG_LVL_DEBUG;
36 }
37 }
38 bool VtpInstance::isDebuged_ = false;
39 std::string VtpInstance::version_ = "VTP_V1.0";
40 bool VtpInstance::isDestroyed_ = true;
41 int VtpInstance::socketStreamCount_ = 0;
42 int VtpInstance::initVtpCount_ = 0;
43 std::mutex VtpInstance::vtpLock_;
44 std::vector<std::string> VtpInstance::packetNameArray_;
45 std::shared_ptr<VtpInstance> VtpInstance::instance_ = nullptr;
46
GetVtpInstance()47 std::shared_ptr<VtpInstance> VtpInstance::GetVtpInstance()
48 {
49 std::shared_ptr<VtpInstance> tmp = instance_;
50 if (tmp == nullptr) {
51 std::lock_guard<std::mutex> guard(vtpLock_);
52 tmp = instance_;
53 if (tmp == nullptr) {
54 tmp = VtpInstance::Create();
55 instance_ = tmp;
56 }
57 }
58 return instance_;
59 }
60
CryptoRand()61 FILLP_UINT32 VtpInstance::CryptoRand()
62 {
63 return SoftBusCryptoRand();
64 }
65
PrintFillpLog(FILLP_UINT32 debugType,FILLP_UINT32 debugLevel,FILLP_UINT32 debugId,FILLP_CHAR * format,...)66 void VtpInstance::PrintFillpLog(FILLP_UINT32 debugType, FILLP_UINT32 debugLevel, FILLP_UINT32 debugId,
67 FILLP_CHAR *format, ...)
68 {
69 /* unused param */
70 static_cast<void>(debugType);
71 static_cast<void>(debugLevel);
72 static_cast<void>(debugId);
73
74 char debugInfo[DEBUG_BUFFER_LEN];
75 (void)memset_s(debugInfo, sizeof(debugInfo), 0, sizeof(debugInfo));
76
77 va_list vaList;
78 va_start(vaList, format);
79 #pragma clang diagnostic push
80 #pragma clang diagnostic ignored "-Wformat-nonliteral"
81 int result = vsprintf_s(debugInfo, DEBUG_BUFFER_LEN, static_cast<const char *>(format), vaList);
82 #pragma clang diagnostic pop
83 if (result < 0) {
84 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "**********fillDebugSend Fail!************");
85 va_end(vaList);
86 return;
87 }
88 va_end(vaList);
89
90 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_DBG, "%s", debugInfo);
91 }
92
PreSetFillpCoreParams(void)93 void VtpInstance::PreSetFillpCoreParams(void)
94 {
95 FillpLmCallbackFunc logCallBack;
96 logCallBack.debugCallbackFunc = static_cast<FillpDebugSendFunc>(PrintFillpLog);
97 FILLP_INT32 err = FillpRegLMCallbackFn(&logCallBack);
98 if (err != ERR_OK) {
99 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to create the log, errno:%d", FtGetErrno());
100 }
101
102 FillpSysLibCallbackFuncStruct adpLibSysFunc;
103 (void)memset_s(&adpLibSysFunc, sizeof(adpLibSysFunc), 0, sizeof(adpLibSysFunc));
104 adpLibSysFunc.sysLibBasicFunc.cryptoRand = CryptoRand;
105 err = FillpApiRegLibSysFunc(&adpLibSysFunc, nullptr);
106 if (err != FILLP_SUCCESS) {
107 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
108 "failed to register fillp callback function, errno:%d", FtGetErrno());
109 }
110
111 FillpApiSetDebugLogLevel(UpdateVtpLogLevel());
112
113 FILLP_UINT16 maxSocketNums = MAX_DEFAULT_SOCKET_NUM;
114 err = FtConfigSet(FT_CONF_MAX_SOCK_NUM, &maxSocketNums, nullptr);
115 if (err != ERR_OK) {
116 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
117 "failed to set MAX_SOCKET_NUM config, ret %d", static_cast<int>(err));
118 }
119
120 FILLP_UINT16 maxConnectionNums = MAX_DEFAULT_SOCKET_NUM; // keep same with the nums of socket.
121 err = FtConfigSet(FT_CONF_MAX_CONNECTION_NUM, &maxConnectionNums, nullptr);
122 if (err != ERR_OK) {
123 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
124 "failed to set MAX_CONNECTION_NUM config, ret %d", static_cast<int>(err));
125 }
126
127 FILLP_INT32 keepAlive = FILLP_KEEP_ALIVE_TIME;
128 FILLP_INT confSock = FILLP_CONFIG_ALL_SOCKET;
129 err = FtConfigSet(FT_CONF_TIMER_KEEP_ALIVE, &keepAlive, &confSock);
130 if (err != ERR_OK) {
131 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to set KA config, ret %d", static_cast<int>(err));
132 }
133 }
134
InitVtp(const std::string & pkgName)135 bool VtpInstance::InitVtp(const std::string &pkgName)
136 {
137 std::lock_guard<std::mutex> guard(vtpLock_);
138
139 if (!isDestroyed_) {
140 if (std::find(packetNameArray_.begin(), packetNameArray_.end(), pkgName) == packetNameArray_.end()) {
141 packetNameArray_.push_back(pkgName);
142 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO,
143 "vtp instance is already created, so increase to packetNameArray");
144 }
145 initVtpCount_++;
146 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO,
147 "vtp instance is already created, return true. PKG(%s)", pkgName.c_str());
148 return true;
149 }
150
151 initVtpCount_++;
152 PreSetFillpCoreParams();
153
154 int err = static_cast<int>(FtInit());
155 if (err != ERR_OK) {
156 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "%s failed to init fillp, ret:%d", pkgName.c_str(), err);
157 return false;
158 }
159 isDestroyed_ = false;
160 #ifdef FILLP_ENHANCED
161 if (static_cast<int>(FtSetDfxEventCb(NULL, DstreamHiEventCb)) != 0) {
162 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "FtSetDfxEventCb set failed!");
163 }
164 #endif
165 packetNameArray_.push_back(pkgName);
166 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "%s success to init vtp instance", pkgName.c_str());
167 return true;
168 }
169
WaitForDestroy(const int & delayTimes)170 void VtpInstance::WaitForDestroy(const int &delayTimes)
171 {
172 sleep(delayTimes);
173 std::lock_guard<std::mutex> guard(vtpLock_);
174 if (!isDestroyed_) {
175 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "call WaitForDestroy");
176 FtDestroyNonblock();
177 isDestroyed_ = true;
178 initVtpCount_ = 0;
179 }
180 }
181
DestroyVtp(const std::string & pkgName)182 void VtpInstance::DestroyVtp(const std::string &pkgName)
183 {
184 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "DestroyVtp start");
185 std::lock_guard<std::mutex> guard(vtpLock_);
186
187 if (isDestroyed_) {
188 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "vtp instance is already destroyed");
189 return;
190 }
191
192 initVtpCount_--;
193 if (initVtpCount_ > 0) {
194 return;
195 }
196 for (unsigned long i = 0; i < packetNameArray_.size(); i++) {
197 if (!strcmp(packetNameArray_[i].c_str(), pkgName.c_str())) {
198 packetNameArray_.erase(packetNameArray_.begin() + i);
199 break;
200 }
201 }
202
203 if (!packetNameArray_.empty()) {
204 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "vtp instance is using by other app");
205 return;
206 }
207
208 if (socketStreamCount_) {
209 // 起线程等待30s,调用FtDestroyNonblock()
210 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_WARN, "some socket is not destroyed, wait 30s and destroy vtp.");
211 std::thread delay(WaitForDestroy, DESTROY_TIMEOUT_SECOND);
212 delay.detach();
213 return;
214 }
215
216 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "begin to destroy vtp instance");
217 FtDestroy();
218 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "success to destroy vtp instance");
219 isDestroyed_ = true;
220 initVtpCount_ = 0;
221 }
222
GetVersion()223 std::string VtpInstance::GetVersion()
224 {
225 return version_;
226 }
227
UpdateSocketStreamCount(bool add)228 void VtpInstance::UpdateSocketStreamCount(bool add)
229 {
230 std::lock_guard<std::mutex> guard(vtpLock_);
231
232 if (add) {
233 socketStreamCount_++;
234 return;
235 }
236
237 if (!socketStreamCount_) {
238 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_WARN, "SocketStreamCount is already 0.");
239 } else {
240 socketStreamCount_--;
241 }
242
243 if (!socketStreamCount_ && !packetNameArray_.size() && !isDestroyed_) {
244 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "start destroying vtp instance");
245 FtDestroy();
246 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "success to destroy vtp instance");
247 isDestroyed_ = true;
248 }
249 }
250 } // namespace SoftBus
251 } // namespace Communication
252