1 /*
2 * Copyright (c) 2021-2024 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 "client_trans_udp_stream_interface.h"
17
18 #include <map>
19 #include <mutex>
20 #include <string>
21
22 #include "securec.h"
23 #include "softbus_errcode.h"
24 #include "stream_adaptor.h"
25 #include "stream_adaptor_listener.h"
26 #include "stream_common.h"
27 #include "trans_log.h"
28
29 using namespace OHOS;
30
31 namespace {
32 std::map<int, std::shared_ptr<StreamAdaptor>> g_adaptorMap;
33 std::mutex g_mutex;
34 }
35
ConvertStreamFrameInfo(const StreamFrameInfo * inFrameInfo,Communication::SoftBus::StreamFrameInfo * outFrameInfo)36 static inline void ConvertStreamFrameInfo(const StreamFrameInfo *inFrameInfo,
37 Communication::SoftBus::StreamFrameInfo *outFrameInfo)
38 {
39 outFrameInfo->streamId = 0;
40 outFrameInfo->seqNum = (uint32_t)(inFrameInfo->seqNum);
41 outFrameInfo->level = (uint32_t)(inFrameInfo->level);
42 outFrameInfo->frameType = (Communication::SoftBus::FrameType)(inFrameInfo->frameType);
43 outFrameInfo->seqSubNum = (uint32_t)inFrameInfo->seqSubNum;
44 outFrameInfo->bitMap = (uint32_t)inFrameInfo->bitMap;
45 outFrameInfo->timeStamp = (uint32_t)inFrameInfo->timeStamp;
46 outFrameInfo->bitrate = 0;
47 }
48
CreateRawStream(const std::shared_ptr<StreamAdaptor> & adaptor,const char * buf,ssize_t bufLen,std::unique_ptr<IStream> & stream)49 static int32_t CreateRawStream(const std::shared_ptr<StreamAdaptor> &adaptor, const char *buf, ssize_t bufLen,
50 std::unique_ptr<IStream> &stream)
51 {
52 bool isEncrypt = adaptor->IsEncryptedRawStream();
53 if (!isEncrypt) {
54 TRANS_LOGD(TRANS_STREAM, "isEncrypt=%{public}d, bufLen=%{public}zd", isEncrypt, bufLen);
55 stream = IStream::MakeRawStream(buf, bufLen, {}, Communication::SoftBus::Scene::SOFTBUS_SCENE);
56 return SOFTBUS_OK;
57 }
58
59 ssize_t dataLen = bufLen + adaptor->GetEncryptOverhead();
60 TRANS_LOGD(TRANS_STREAM, "isEncrypt=%{public}d, bufLen=%{public}zd, encryptOverhead=%{public}zd", isEncrypt,
61 bufLen, adaptor->GetEncryptOverhead());
62 std::unique_ptr<char[]> data = std::make_unique<char[]>(dataLen);
63 ssize_t encLen = adaptor->Encrypt(buf, bufLen, data.get(), dataLen, adaptor->GetSessionKey());
64 if (encLen != dataLen) {
65 TRANS_LOGE(TRANS_STREAM, "encrypted failed, dataLen=%{public}zd, encLen=%{public}zd", dataLen, encLen);
66 return SOFTBUS_TRANS_ENCRYPT_ERR;
67 }
68 stream = IStream::MakeRawStream(data.get(), dataLen, {}, Communication::SoftBus::Scene::SOFTBUS_SCENE);
69 return SOFTBUS_OK;
70 }
71
ProcessAdaptorAndEncrypt(const StreamFrameInfo * param,const StreamData * inData,std::shared_ptr<StreamAdaptor> & adaptor,std::unique_ptr<IStream> & stream,const StreamData * ext)72 static int32_t ProcessAdaptorAndEncrypt(const StreamFrameInfo *param, const StreamData *inData,
73 std::shared_ptr<StreamAdaptor> &adaptor, std::unique_ptr<IStream> &stream, const StreamData *ext)
74 {
75 if (adaptor->GetStreamType() == RAW_STREAM) {
76 int32_t ret = CreateRawStream(adaptor, inData->buf, inData->bufLen, stream);
77 if (ret != SOFTBUS_OK) {
78 TRANS_LOGE(TRANS_STREAM, "failed to create raw stream, ret=%{public}d", ret);
79 return ret;
80 }
81 } else if (adaptor->GetStreamType() == COMMON_VIDEO_STREAM || adaptor->GetStreamType() == COMMON_AUDIO_STREAM) {
82 if (inData->bufLen < 0 || inData->bufLen > Communication::SoftBus::MAX_STREAM_LEN ||
83 (ext != nullptr && (ext->bufLen < 0 || ext->bufLen > Communication::SoftBus::MAX_STREAM_LEN))) {
84 return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
85 }
86 Communication::SoftBus::StreamData data = {
87 .buffer = std::make_unique<char[]>(inData->bufLen),
88 .bufLen = inData->bufLen,
89 .extBuffer = nullptr,
90 .extLen = 0,
91 };
92 int32_t ret = memcpy_s(data.buffer.get(), data.bufLen, inData->buf, inData->bufLen);
93 if (ret != EOK) {
94 TRANS_LOGE(TRANS_STREAM, "Failed to memcpy data! ret=%{public}d", ret);
95 return SOFTBUS_MEM_ERR;
96 }
97 if (ext != nullptr && ext->bufLen > 0) {
98 data.extBuffer = std::make_unique<char[]>(ext->bufLen);
99 data.extLen = ext->bufLen;
100 ret = memcpy_s(data.extBuffer.get(), data.extLen, ext->buf, ext->bufLen);
101 if (ret != EOK) {
102 TRANS_LOGE(TRANS_STREAM, "Failed to memcpy ext! ret=%{public}d", ret);
103 return SOFTBUS_MEM_ERR;
104 }
105 }
106 Communication::SoftBus::StreamFrameInfo outFrameInfo;
107 ConvertStreamFrameInfo(param, &outFrameInfo);
108 stream = IStream::MakeCommonStream(data, outFrameInfo);
109 } else {
110 TRANS_LOGE(TRANS_STREAM, "Do not support");
111 return SOFTBUS_FUNC_NOT_SUPPORT;
112 }
113 return SOFTBUS_OK;
114 }
115
SendVtpStream(int32_t channelId,const StreamData * inData,const StreamData * ext,const StreamFrameInfo * param)116 int32_t SendVtpStream(int32_t channelId, const StreamData *inData, const StreamData *ext, const StreamFrameInfo *param)
117 {
118 if (inData == nullptr || inData->buf == nullptr || param == nullptr) {
119 TRANS_LOGE(TRANS_STREAM, "invalid argument inData or param");
120 return SOFTBUS_INVALID_PARAM;
121 }
122 std::shared_ptr<StreamAdaptor> adaptor = nullptr;
123 {
124 std::lock_guard<std::mutex> lock(g_mutex);
125 auto it = g_adaptorMap.find(channelId);
126 if (it == g_adaptorMap.end()) {
127 TRANS_LOGE(TRANS_STREAM, "adaptor not existed!");
128 return SOFTBUS_TRANS_ADAPTOR_NOT_EXISTED;
129 }
130 adaptor = it->second;
131 }
132
133 std::unique_ptr<IStream> stream = nullptr;
134 int32_t result = ProcessAdaptorAndEncrypt(param, inData, adaptor, stream, ext);
135 if (result != SOFTBUS_OK) {
136 TRANS_LOGE(TRANS_STREAM, "obtain adapters encrypted data failed, result = %{public}d", result);
137 return result;
138 }
139 if (stream == nullptr) {
140 TRANS_LOGE(TRANS_STREAM, "make stream failed, stream is nullptr");
141 return SOFTBUS_TRANS_MAKE_STREAM_FAILED;
142 }
143 return adaptor->GetStreamManager()->Send(std::move(stream)) ? SOFTBUS_OK : SOFTBUS_TRANS_MAKE_STREAM_FAILED;
144 }
145
SetVtpStreamMultiLayerOpt(int32_t channelId,const void * optValue)146 int32_t SetVtpStreamMultiLayerOpt(int32_t channelId, const void *optValue)
147 {
148 if (optValue == nullptr) {
149 TRANS_LOGE(TRANS_STREAM, "invalid argument optValue channelId %{public}d", channelId);
150 return SOFTBUS_INVALID_PARAM;
151 }
152 std::shared_ptr<StreamAdaptor> adaptor = nullptr;
153 {
154 std::lock_guard<std::mutex> lock(g_mutex);
155 auto it = g_adaptorMap.find(channelId);
156 if (it == g_adaptorMap.end()) {
157 TRANS_LOGE(TRANS_STREAM, "channelId %{public}d adaptor not existed!", channelId);
158 return SOFTBUS_TRANS_ADAPTOR_NOT_EXISTED;
159 }
160 adaptor = it->second;
161 }
162 return adaptor->GetStreamManager()->SetMultiLayer(optValue);
163 }
164
StartVtpStreamChannelServer(int32_t channelId,const VtpStreamOpenParam * param,const IStreamListener * callback)165 int32_t StartVtpStreamChannelServer(int32_t channelId, const VtpStreamOpenParam *param, const IStreamListener *callback)
166 {
167 if (channelId < 0 || param == nullptr || param->pkgName == nullptr || callback == nullptr) {
168 TRANS_LOGE(TRANS_STREAM, "invalid channelId or pkgName");
169 return SOFTBUS_INVALID_PARAM;
170 }
171 TRANS_LOGI(TRANS_STREAM, "Start Channel Server. channelId=%{public}d ", channelId);
172 auto it = g_adaptorMap.find(channelId);
173 if (it != g_adaptorMap.end()) {
174 TRANS_LOGE(TRANS_STREAM, "adaptor already existed!");
175 return SOFTBUS_TRANS_ADAPTOR_ALREADY_EXISTED;
176 }
177
178 {
179 std::lock_guard<std::mutex> lock(g_mutex);
180 it = g_adaptorMap.find(channelId);
181 if (it == g_adaptorMap.end()) {
182 std::string pkgStr(param->pkgName);
183 it = g_adaptorMap.emplace(std::pair<int, std::shared_ptr<StreamAdaptor>>(channelId,
184 std::make_shared<StreamAdaptor>(pkgStr))).first;
185 } else {
186 TRANS_LOGE(TRANS_STREAM, "adaptor already existed!");
187 return SOFTBUS_TRANS_ADAPTOR_ALREADY_EXISTED;
188 }
189 }
190
191 auto newAdaptor = it->second;
192 newAdaptor->InitAdaptor(channelId, param, true, callback);
193
194 Communication::SoftBus::IpAndPort ipPort;
195 ipPort.ip = param->myIp;
196 ipPort.port = 0;
197
198 int32_t ret = newAdaptor->GetStreamManager()->CreateStreamServerChannel(ipPort, Communication::SoftBus::VTP,
199 param->type, newAdaptor->GetSessionKey());
200 if (ret > 0) {
201 newAdaptor->SetAliveState(true);
202 } else {
203 CloseVtpStreamChannel(channelId, param->pkgName);
204 }
205
206 return ret;
207 }
208
StartVtpStreamChannelClient(int32_t channelId,const VtpStreamOpenParam * param,const IStreamListener * callback)209 int32_t StartVtpStreamChannelClient(int32_t channelId, const VtpStreamOpenParam *param, const IStreamListener *callback)
210 {
211 if (channelId < 0 || param == nullptr || param->pkgName == nullptr || callback == nullptr) {
212 TRANS_LOGE(TRANS_STREAM, "invalid channelId or pkgName");
213 return SOFTBUS_INVALID_PARAM;
214 }
215
216 TRANS_LOGI(TRANS_STREAM, "StartChannelClient channelId=%{public}d.", channelId);
217 auto it = g_adaptorMap.find(channelId);
218 if (it != g_adaptorMap.end()) {
219 TRANS_LOGE(TRANS_STREAM, "adaptor already existed!");
220 return SOFTBUS_TRANS_ADAPTOR_ALREADY_EXISTED;
221 }
222
223 {
224 std::lock_guard<std::mutex> lock(g_mutex);
225 it = g_adaptorMap.find(channelId);
226 if (it == g_adaptorMap.end()) {
227 std::string pkgStr(param->pkgName);
228 it = g_adaptorMap.emplace(std::pair<int, std::shared_ptr<StreamAdaptor>>(channelId,
229 std::make_shared<StreamAdaptor>(pkgStr))).first;
230 } else {
231 TRANS_LOGE(TRANS_STREAM, "adaptor already existed!");
232 return SOFTBUS_TRANS_ADAPTOR_ALREADY_EXISTED;
233 }
234 }
235
236 auto newAdaptor = it->second;
237 newAdaptor->InitAdaptor(channelId, param, false, callback);
238
239 Communication::SoftBus::IpAndPort ipPort;
240 ipPort.ip = param->myIp;
241 ipPort.port = 0;
242
243 Communication::SoftBus::IpAndPort peerIpPort;
244 peerIpPort.ip = param->peerIp;
245 peerIpPort.port = param->peerPort;
246
247 int32_t ret = newAdaptor->GetStreamManager()->CreateStreamClientChannel(ipPort, peerIpPort,
248 Communication::SoftBus::VTP, param->type, newAdaptor->GetSessionKey());
249 if (ret > 0) {
250 newAdaptor->SetAliveState(true);
251 } else {
252 TRANS_LOGE(TRANS_STREAM, "CreateStreamClientChannel failed, ret=%{public}d", ret);
253 CloseVtpStreamChannel(channelId, param->pkgName);
254 }
255
256 return ret;
257 }
258
CloseVtpStreamChannel(int32_t channelId,const char * pkgName)259 int32_t CloseVtpStreamChannel(int32_t channelId, const char *pkgName)
260 {
261 TRANS_LOGI(TRANS_STREAM, "close stream channelId=%{public}d", channelId);
262 std::shared_ptr<StreamAdaptor> adaptor = nullptr;
263
264 if (channelId < 0 || pkgName == nullptr) {
265 TRANS_LOGE(TRANS_STREAM, "invalid channelId or pkgName");
266 return SOFTBUS_INVALID_PARAM;
267 }
268
269 {
270 std::lock_guard<std::mutex> lock(g_mutex);
271 auto it = g_adaptorMap.find(channelId);
272 if (it == g_adaptorMap.end()) {
273 TRANS_LOGE(TRANS_STREAM, "adaptor not existed!");
274 return SOFTBUS_TRANS_ADAPTOR_NOT_EXISTED;
275 }
276 adaptor = it->second;
277 g_adaptorMap.erase(it);
278 }
279
280 bool alive = adaptor->GetAliveState();
281 if (!alive) {
282 TRANS_LOGE(TRANS_STREAM, "VtpStreamChannel already closed");
283 return SOFTBUS_ALREADY_TRIGGERED;
284 }
285
286 adaptor->ReleaseAdaptor();
287
288 return SOFTBUS_OK;
289 }
290