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