• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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