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