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