• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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