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