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