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 newAdaptor->InitAdaptor(channelId, param, true, callback);
191
192 Communication::SoftBus::IpAndPort ipPort;
193 ipPort.ip = param->myIp;
194 ipPort.port = 0;
195
196 int32_t ret = newAdaptor->GetStreamManager()->CreateStreamServerChannel(ipPort, Communication::SoftBus::VTP,
197 param->type, newAdaptor->GetSessionKey());
198 if (ret > 0) {
199 newAdaptor->SetAliveState(true);
200 } else {
201 CloseVtpStreamChannel(channelId, param->pkgName);
202 }
203
204 return ret;
205 }
206
StartVtpStreamChannelClient(int32_t channelId,const VtpStreamOpenParam * param,const IStreamListener * callback)207 int32_t StartVtpStreamChannelClient(int32_t channelId, const VtpStreamOpenParam *param, const IStreamListener *callback)
208 {
209 if (channelId < 0 || param == nullptr || param->pkgName == nullptr || callback == nullptr) {
210 TRANS_LOGE(TRANS_STREAM, "invalid channelId or pkgName");
211 return SOFTBUS_INVALID_PARAM;
212 }
213
214 TRANS_LOGI(TRANS_STREAM, "StartChannelClient channelId=%{public}d.", channelId);
215 auto it = g_adaptorMap.find(channelId);
216 if (it != g_adaptorMap.end()) {
217 TRANS_LOGE(TRANS_STREAM, "adaptor already existed!");
218 return SOFTBUS_TRANS_ADAPTOR_ALREADY_EXISTED;
219 }
220
221 {
222 std::lock_guard<std::mutex> lock(g_mutex);
223 it = g_adaptorMap.find(channelId);
224 if (it == g_adaptorMap.end()) {
225 std::string pkgStr(param->pkgName);
226 it = g_adaptorMap.emplace(std::pair<int, std::shared_ptr<StreamAdaptor>>(channelId,
227 std::make_shared<StreamAdaptor>(pkgStr))).first;
228 } else {
229 TRANS_LOGE(TRANS_STREAM, "adaptor already existed!");
230 return SOFTBUS_TRANS_ADAPTOR_ALREADY_EXISTED;
231 }
232 }
233
234 auto newAdaptor = it->second;
235 newAdaptor->InitAdaptor(channelId, param, false, callback);
236
237 Communication::SoftBus::IpAndPort ipPort;
238 ipPort.ip = param->myIp;
239 ipPort.port = 0;
240
241 Communication::SoftBus::IpAndPort peerIpPort;
242 peerIpPort.ip = param->peerIp;
243 peerIpPort.port = param->peerPort;
244
245 int32_t ret = newAdaptor->GetStreamManager()->CreateStreamClientChannel(ipPort, peerIpPort,
246 Communication::SoftBus::VTP, param->type, newAdaptor->GetSessionKey());
247 if (ret > 0) {
248 newAdaptor->SetAliveState(true);
249 } else {
250 TRANS_LOGE(TRANS_STREAM, "CreateStreamClientChannel failed, ret=%{public}d", ret);
251 CloseVtpStreamChannel(channelId, param->pkgName);
252 }
253
254 return ret;
255 }
256
CloseVtpStreamChannel(int32_t channelId,const char * pkgName)257 int32_t CloseVtpStreamChannel(int32_t channelId, const char *pkgName)
258 {
259 TRANS_LOGI(TRANS_STREAM, "close stream channelId=%{public}d", channelId);
260 std::shared_ptr<StreamAdaptor> adaptor = nullptr;
261
262 if (channelId < 0 || pkgName == nullptr) {
263 TRANS_LOGE(TRANS_STREAM, "invalid channelId or pkgName");
264 return SOFTBUS_INVALID_PARAM;
265 }
266
267 {
268 std::lock_guard<std::mutex> lock(g_mutex);
269 auto it = g_adaptorMap.find(channelId);
270 if (it == g_adaptorMap.end()) {
271 TRANS_LOGE(TRANS_STREAM, "adaptor not existed!");
272 return SOFTBUS_TRANS_ADAPTOR_NOT_EXISTED;
273 }
274 adaptor = it->second;
275 g_adaptorMap.erase(it);
276 }
277
278 bool alive = adaptor->GetAliveState();
279 if (!alive) {
280 TRANS_LOGE(TRANS_STREAM, "VtpStreamChannel already closed");
281 return SOFTBUS_ALREADY_TRIGGERED;
282 }
283
284 adaptor->ReleaseAdaptor();
285
286 return SOFTBUS_OK;
287 }
288