• 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     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