1 /*
2 * Copyright (c) 2022-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 "softbus_channel_adapter.h"
17
18 #include <algorithm>
19 #include <securec.h>
20 #include <thread>
21 #include <unistd.h>
22
23 #include "av_trans_constants.h"
24 #include "av_trans_errno.h"
25 #include "av_trans_log.h"
26
27 namespace OHOS {
28 namespace DistributedHardware {
29 #undef DH_LOG_TAG
30 #define DH_LOG_TAG "SoftbusChannelAdapter"
31
32 IMPLEMENT_SINGLE_INSTANCE(SoftbusChannelAdapter);
33
34 namespace {
35 const static std::pair<std::string, std::string> LOCAL_TO_PEER_SESSION_NAME_MAP[] = {
36 {OWNER_NAME_D_MIC + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX,
37 OWNER_NAME_D_MIC + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX},
38 {OWNER_NAME_D_MIC + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX,
39 OWNER_NAME_D_MIC + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX},
40 {OWNER_NAME_D_SPEAKER + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX,
41 OWNER_NAME_D_SPEAKER + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX},
42 {OWNER_NAME_D_SPEAKER + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX,
43 OWNER_NAME_D_SPEAKER + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX},
44 {OWNER_NAME_D_SCREEN + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX,
45 OWNER_NAME_D_SCREEN + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX},
46 {OWNER_NAME_D_SCREEN + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX,
47 OWNER_NAME_D_SCREEN + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX},
48 {OWNER_NAME_D_VIRMODEM_MIC + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX,
49 OWNER_NAME_D_VIRMODEM_MIC + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX},
50 {OWNER_NAME_D_VIRMODEM_MIC + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX,
51 OWNER_NAME_D_VIRMODEM_MIC + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX},
52 {OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX,
53 OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX},
54 {OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + RECEIVER_CONTROL_SESSION_NAME_SUFFIX,
55 OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + SENDER_CONTROL_SESSION_NAME_SUFFIX},
56
57 {AV_SYNC_SENDER_CONTROL_SESSION_NAME, AV_SYNC_RECEIVER_CONTROL_SESSION_NAME},
58 {AV_SYNC_RECEIVER_CONTROL_SESSION_NAME, AV_SYNC_SENDER_CONTROL_SESSION_NAME},
59
60 {OWNER_NAME_D_MIC + "_" + SENDER_DATA_SESSION_NAME_SUFFIX,
61 OWNER_NAME_D_MIC + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX},
62 {OWNER_NAME_D_MIC + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX,
63 OWNER_NAME_D_MIC + "_" + SENDER_DATA_SESSION_NAME_SUFFIX},
64 {OWNER_NAME_D_SPEAKER + "_" + SENDER_DATA_SESSION_NAME_SUFFIX,
65 OWNER_NAME_D_SPEAKER + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX},
66 {OWNER_NAME_D_SPEAKER + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX,
67 OWNER_NAME_D_SPEAKER + "_" + SENDER_DATA_SESSION_NAME_SUFFIX},
68 {OWNER_NAME_D_SCREEN + "_" + SENDER_DATA_SESSION_NAME_SUFFIX,
69 OWNER_NAME_D_SCREEN + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX},
70 {OWNER_NAME_D_SCREEN + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX,
71 OWNER_NAME_D_SCREEN + "_" + SENDER_DATA_SESSION_NAME_SUFFIX},
72 {OWNER_NAME_D_VIRMODEM_MIC + "_" + SENDER_DATA_SESSION_NAME_SUFFIX,
73 OWNER_NAME_D_VIRMODEM_MIC + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX},
74 {OWNER_NAME_D_VIRMODEM_MIC + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX,
75 OWNER_NAME_D_VIRMODEM_MIC + "_" + SENDER_DATA_SESSION_NAME_SUFFIX},
76 {OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + SENDER_DATA_SESSION_NAME_SUFFIX,
77 OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX},
78 {OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX,
79 OWNER_NAME_D_VIRMODEM_SPEAKER + "_" + SENDER_DATA_SESSION_NAME_SUFFIX},
80 };
81 } // namespace
82
OnSessionOpened(int32_t sessionId,PeerSocketInfo info)83 static void OnSessionOpened(int32_t sessionId, PeerSocketInfo info)
84 {
85 std::string peerDevId(info.networkId);
86 std::string peerSessionName(info.name);
87 SoftbusChannelAdapter::GetInstance().OnSoftbusChannelOpened(peerSessionName, sessionId, peerDevId, 0);
88 }
89
OnSessionClosed(int32_t sessionId,ShutdownReason reason)90 static void OnSessionClosed(int32_t sessionId, ShutdownReason reason)
91 {
92 SoftbusChannelAdapter::GetInstance().OnSoftbusChannelClosed(sessionId, reason);
93 }
94
OnBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)95 static void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
96 {
97 SoftbusChannelAdapter::GetInstance().OnSoftbusBytesReceived(sessionId, data, dataLen);
98 }
99
OnStreamReceived(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * frameInfo)100 static void OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext,
101 const StreamFrameInfo *frameInfo)
102 {
103 SoftbusChannelAdapter::GetInstance().OnSoftbusStreamReceived(sessionId, data, ext, frameInfo);
104 }
105
onDevTimeSyncResult(const TimeSyncResultInfo * info,int32_t result)106 static void onDevTimeSyncResult(const TimeSyncResultInfo *info, int32_t result)
107 {
108 SoftbusChannelAdapter::GetInstance().OnSoftbusTimeSyncResult(info, result);
109 }
110
SoftbusChannelAdapter()111 SoftbusChannelAdapter::SoftbusChannelAdapter()
112 {
113 sessListener_.OnBind = OnSessionOpened;
114 sessListener_.OnShutdown = OnSessionClosed;
115 sessListener_.OnBytes = OnBytesReceived;
116 sessListener_.OnStream = OnStreamReceived;
117 sessListener_.OnMessage = nullptr;
118 sessListener_.OnFile = nullptr;
119 sessListener_.OnQos = nullptr;
120 sessListener_.OnError = nullptr;
121 sessListener_.OnNegotiate = nullptr;
122 }
123
~SoftbusChannelAdapter()124 SoftbusChannelAdapter::~SoftbusChannelAdapter()
125 {
126 listenerMap_.clear();
127 timeSyncSessNames_.clear();
128 devId2SessIdMap_.clear();
129 serverMap_.clear();
130 }
131
TransName2PkgName(const std::string & ownerName)132 std::string SoftbusChannelAdapter::TransName2PkgName(const std::string &ownerName)
133 {
134 const static std::pair<std::string, std::string> mapArray[] = {
135 {OWNER_NAME_D_MIC, PKG_NAME_D_AUDIO},
136 {OWNER_NAME_D_VIRMODEM_MIC, PKG_NAME_D_CALL},
137 {OWNER_NAME_D_CAMERA, PKG_NAME_D_CAMERA},
138 {OWNER_NAME_D_SCREEN, PKG_NAME_D_SCREEN},
139 {OWNER_NAME_D_SPEAKER, PKG_NAME_D_AUDIO},
140 {OWNER_NAME_D_VIRMODEM_SPEAKER, PKG_NAME_D_CALL},
141 {AV_SYNC_SENDER_CONTROL_SESSION_NAME, PKG_NAME_DH_FWK},
142 {AV_SYNC_RECEIVER_CONTROL_SESSION_NAME, PKG_NAME_DH_FWK},
143 };
144 auto foundItem = std::find_if(std::begin(mapArray), std::end(mapArray),
145 [&](const auto& item) { return item.first == ownerName; });
146 if (foundItem != std::end(mapArray)) {
147 return foundItem->second;
148 }
149 return EMPTY_STRING;
150 }
151
FindSessNameByPeerSessName(const std::string peerSessionName)152 std::string SoftbusChannelAdapter::FindSessNameByPeerSessName(const std::string peerSessionName)
153 {
154 auto foundItem = std::find_if(std::begin(LOCAL_TO_PEER_SESSION_NAME_MAP), std::end(LOCAL_TO_PEER_SESSION_NAME_MAP),
155 [&](const auto& item) { return item.first == peerSessionName; });
156 if (foundItem != std::end(LOCAL_TO_PEER_SESSION_NAME_MAP)) {
157 return foundItem->second;
158 }
159 return EMPTY_STRING;
160 }
161
CreateChannelServer(const std::string & pkgName,const std::string & sessName)162 int32_t SoftbusChannelAdapter::CreateChannelServer(const std::string& pkgName, const std::string &sessName)
163 {
164 AVTRANS_LOGI("Create session server for sessionName:%{public}s.", sessName.c_str());
165 TRUE_RETURN_V_MSG_E(pkgName.empty(), ERR_DH_AVT_INVALID_PARAM, "input pkgName is empty.");
166 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessionName is empty.");
167
168 {
169 std::lock_guard<std::mutex> lock(serverMapMtx_);
170 if (serverMap_.count(pkgName + "_" + sessName)) {
171 AVTRANS_LOGI("Session has already created for name:%{public}s", sessName.c_str());
172 return DH_AVT_SUCCESS;
173 }
174 }
175
176 TransDataType dataType = TransDataType::DATA_TYPE_BYTES;
177 if (sessName.find("avtrans.data") != std::string::npos) {
178 dataType = TransDataType::DATA_TYPE_VIDEO_STREAM;
179 }
180
181 SocketInfo serverInfo = {
182 .name = const_cast<char*>(sessName.c_str()),
183 .pkgName = const_cast<char*>(pkgName.c_str()),
184 .dataType = dataType,
185 };
186 int32_t socketId = Socket(serverInfo);
187 if (socketId < 0) {
188 AVTRANS_LOGE("Create Socket fail socketId:%{public}" PRId32, socketId);
189 return ERR_DH_AVT_SESSION_ERROR;
190 }
191 QosTV qos[] = {
192 {.qos = QOS_TYPE_MIN_BW, .value = 40 * 1024 * 1024},
193 {.qos = QOS_TYPE_MAX_LATENCY, .value = 4000},
194 {.qos = QOS_TYPE_MIN_LATENCY, .value = 2000},
195 };
196
197 int32_t ret = Listen(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessListener_);
198 if (ret != 0) {
199 AVTRANS_LOGE("Listen socket error for sessionName:%{public}s", sessName.c_str());
200 return ERR_DH_AVT_SESSION_ERROR;
201 }
202 {
203 std::lock_guard<std::mutex> lock(serverMapMtx_);
204 serverMap_.insert(std::make_pair(pkgName + "_" + sessName, socketId));
205 }
206 AVTRANS_LOGI("Create session server success for sessionName:%{public}s.", sessName.c_str());
207 return DH_AVT_SUCCESS;
208 }
209
RemoveChannelServer(const std::string & pkgName,const std::string & sessName)210 int32_t SoftbusChannelAdapter::RemoveChannelServer(const std::string& pkgName, const std::string &sessName)
211 {
212 AVTRANS_LOGI("Remove session server for sessionName:%{public}s.", sessName.c_str());
213 TRUE_RETURN_V_MSG_E(pkgName.empty(), ERR_DH_AVT_INVALID_PARAM, "input pkgName is empty.");
214 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessionName is empty.");
215
216 std::string serverMapKey = pkgName + "_" + sessName;
217 int32_t serverSocketId = INVALID_SESSION_ID;
218 {
219 std::lock_guard<std::mutex> lock(serverMapMtx_);
220 for (auto it = serverMap_.begin(); it != serverMap_.end(); it++) {
221 if (((it->first).find(serverMapKey) != std::string::npos)) {
222 serverSocketId = it->second;
223 serverMap_.erase(it->first);
224 break;
225 }
226 }
227 }
228 AVTRANS_LOGI("Remove session server success for serverSocketId:%{public}" PRId32, serverSocketId);
229 Shutdown(serverSocketId);
230 int32_t sessionId = INVALID_SESSION_ID;
231 {
232 std::lock_guard<std::mutex> lock(idMapMutex_);
233 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
234 if ((it->first).find(sessName) != std::string::npos) {
235 sessionId = it->second;
236 devId2SessIdMap_.erase(it->first);
237 break;
238 }
239 }
240 }
241 Shutdown(sessionId);
242 AVTRANS_LOGI("Remove session server success for sessionName:%{public}s.", sessName.c_str());
243 return DH_AVT_SUCCESS;
244 }
245
SendEventChannelOPened(const std::string & mySessName,const std::string & peerDevId)246 void OHOS::DistributedHardware::SoftbusChannelAdapter::SendEventChannelOPened(const std::string & mySessName,
247 const std::string & peerDevId)
248 {
249 EventType type = EventType::EVENT_CHANNEL_OPENED;
250 AVTransEvent event = {type, mySessName, peerDevId};
251 std::lock_guard<std::mutex> lock(listenerMtx_);
252 {
253 for (auto it = listenerMap_.begin(); it != listenerMap_.end(); it++) {
254 if (((it->first).find(mySessName) != std::string::npos) && (it->second != nullptr)) {
255 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
256 }
257 }
258 }
259 }
260
OpenSoftbusChannel(const std::string & mySessName,const std::string & peerSessName,const std::string & peerDevId)261 int32_t SoftbusChannelAdapter::OpenSoftbusChannel(const std::string &mySessName, const std::string &peerSessName,
262 const std::string &peerDevId)
263 {
264 AVTRANS_LOGI("Open softbus channel for mySessName:%{public}s, peerSessName:%{public}s, peerDevId:%{public}s.",
265 mySessName.c_str(), peerSessName.c_str(), GetAnonyString(peerDevId).c_str());
266 TRUE_RETURN_V_MSG_E(mySessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input mySessName is empty.");
267 TRUE_RETURN_V_MSG_E(peerSessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerSessName is empty.");
268 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
269 std::string ownerName = GetOwnerFromSessName(mySessName);
270 std::string PkgName = TransName2PkgName(ownerName);
271 int32_t existSessId = GetSessIdBySessName(mySessName, peerDevId);
272 if (existSessId > 0) {
273 AVTRANS_LOGI("Softbus channel already opened, sessionId:%{public}" PRId32, existSessId);
274 return ERR_DH_AVT_SESSION_HAS_OPENED;
275 }
276
277 QosTV qos[] = {
278 {.qos = QOS_TYPE_MIN_BW, .value = 40 * 1024 * 1024},
279 {.qos = QOS_TYPE_MAX_LATENCY, .value = 4000},
280 {.qos = QOS_TYPE_MIN_LATENCY, .value = 2000},
281 };
282
283 TransDataType dataType = TransDataType::DATA_TYPE_BYTES;
284 if (mySessName.find("avtrans.data") != std::string::npos) {
285 dataType = TransDataType::DATA_TYPE_VIDEO_STREAM;
286 }
287
288 SocketInfo clientInfo = {
289 .name = const_cast<char*>((mySessName.c_str())),
290 .peerName = const_cast<char*>(peerSessName.c_str()),
291 .peerNetworkId = const_cast<char*>(peerDevId.c_str()),
292 .pkgName = const_cast<char*>(PkgName.c_str()),
293 .dataType = dataType,
294 };
295
296 int32_t socketId = Socket(clientInfo);
297 if (socketId <0) {
298 AVTRANS_LOGE("Create OpenSoftbusChannel Socket error");
299 return ERR_DH_AVT_SESSION_ERROR;
300 }
301 int32_t ret = Bind(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessListener_);
302 if (ret != DH_AVT_SUCCESS) {
303 AVTRANS_LOGE("Bind SocketClient error");
304 return ERR_DH_AVT_SESSION_ERROR;
305 }
306 {
307 std::lock_guard<std::mutex> lock(idMapMutex_);
308 devId2SessIdMap_.insert(std::make_pair(mySessName + "_" + peerDevId, socketId));
309 }
310 SendEventChannelOPened(mySessName, peerDevId);
311 AVTRANS_LOGI("Open softbus channel finished for mySessName:%{public}s.", mySessName.c_str());
312 return DH_AVT_SUCCESS;
313 }
314
CloseSoftbusChannel(const std::string & sessName,const std::string & peerDevId)315 int32_t SoftbusChannelAdapter::CloseSoftbusChannel(const std::string& sessName, const std::string &peerDevId)
316 {
317 AVTRANS_LOGI("Close softbus channel for sessName:%{public}s, peerDevId:%{public}s.", sessName.c_str(),
318 GetAnonyString(peerDevId).c_str());
319 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
320 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
321
322 int32_t sessionId = GetSessIdBySessName(sessName, peerDevId);
323 Shutdown(sessionId);
324 {
325 std::lock_guard<std::mutex> lock(idMapMutex_);
326 devId2SessIdMap_.erase(sessName + "_" + peerDevId);
327 }
328
329 AVTRANS_LOGI("Close softbus channel success, sessionId:%{public}" PRId32, sessionId);
330 return DH_AVT_SUCCESS;
331 }
332
SendBytesData(const std::string & sessName,const std::string & peerDevId,const std::string & data)333 int32_t SoftbusChannelAdapter::SendBytesData(const std::string& sessName, const std::string &peerDevId,
334 const std::string &data)
335 {
336 AVTRANS_LOGI("Send bytes data for sessName:%{public}s, peerDevId:%{public}s.",
337 sessName.c_str(), GetAnonyString(peerDevId).c_str());
338 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
339 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
340 TRUE_RETURN_V_MSG_E(data.empty(), ERR_DH_AVT_INVALID_PARAM, "input data string is empty.");
341
342 int32_t existSessId = GetSessIdBySessName(sessName, peerDevId);
343 if (existSessId < 0) {
344 AVTRANS_LOGI("Can not find sessionId for mySessName:%{public}s, peerDevId:%{public}s.",
345 sessName.c_str(), GetAnonyString(peerDevId).c_str());
346 return ERR_DH_AVT_SEND_DATA_FAILED;
347 }
348 int32_t ret = SendBytes(existSessId, data.c_str(), strlen(data.c_str()));
349 if (ret != DH_AVT_SUCCESS) {
350 AVTRANS_LOGE("Send bytes data failed ret:%{public}" PRId32, ret);
351 return ERR_DH_AVT_SEND_DATA_FAILED;
352 }
353 return DH_AVT_SUCCESS;
354 }
355
SendStreamData(const std::string & sessName,const std::string & peerDevId,const StreamData * data,const StreamData * ext)356 int32_t SoftbusChannelAdapter::SendStreamData(const std::string& sessName, const std::string &peerDevId,
357 const StreamData *data, const StreamData *ext)
358 {
359 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
360 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
361 TRUE_RETURN_V_MSG_E(data == nullptr, ERR_DH_AVT_INVALID_PARAM, "input data is nullptr.");
362 TRUE_RETURN_V_MSG_E(ext == nullptr, ERR_DH_AVT_INVALID_PARAM, "input ext data is nullptr.");
363
364 StreamFrameInfo frameInfo = {0};
365 int32_t existSessId = GetSessIdBySessName(sessName, peerDevId);
366 if (existSessId < 0) {
367 AVTRANS_LOGI("Can not find sessionId for mySessName:%{public}s, peerDevId:%{public}s.",
368 sessName.c_str(), GetAnonyString(peerDevId).c_str());
369 return ERR_DH_AVT_SEND_DATA_FAILED;
370 }
371 int32_t ret = SendStream(existSessId, data, ext, &frameInfo);
372 if (ret != DH_AVT_SUCCESS) {
373 AVTRANS_LOGE("Send stream data failed ret:%{public}" PRId32, ret);
374 return ERR_DH_AVT_SEND_DATA_FAILED;
375 }
376 return DH_AVT_SUCCESS;
377 }
378
RegisterChannelListener(const std::string & sessName,const std::string & peerDevId,ISoftbusChannelListener * listener)379 int32_t SoftbusChannelAdapter::RegisterChannelListener(const std::string& sessName, const std::string &peerDevId,
380 ISoftbusChannelListener *listener)
381 {
382 AVTRANS_LOGI("Register channel listener for sessName:%{public}s, peerDevId:%{public}s.",
383 sessName.c_str(), GetAnonyString(peerDevId).c_str());
384 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
385 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
386 TRUE_RETURN_V_MSG_E(listener == nullptr, ERR_DH_AVT_INVALID_PARAM, "input callback is nullptr.");
387
388 std::lock_guard<std::mutex> lock(listenerMtx_);
389 listenerMap_[sessName + "_" + peerDevId] = listener;
390
391 return DH_AVT_SUCCESS;
392 }
393
UnRegisterChannelListener(const std::string & sessName,const std::string & peerDevId)394 int32_t SoftbusChannelAdapter::UnRegisterChannelListener(const std::string& sessName, const std::string &peerDevId)
395 {
396 AVTRANS_LOGI("Unregister channel listener for sessName:%{public}s, peerDevId:%{public}s.",
397 sessName.c_str(), GetAnonyString(peerDevId).c_str());
398 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
399 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
400
401 std::lock_guard<std::mutex> lock(listenerMtx_);
402 listenerMap_.erase(sessName + "_" + peerDevId);
403
404 return DH_AVT_SUCCESS;
405 }
406
StartDeviceTimeSync(const std::string & pkgName,const std::string & sessName,const std::string & peerDevId)407 int32_t SoftbusChannelAdapter::StartDeviceTimeSync(const std::string &pkgName, const std::string& sessName,
408 const std::string &peerDevId)
409 {
410 AVTRANS_LOGI("Start device time sync for peerDeviceId:%{public}s.", GetAnonyString(peerDevId).c_str());
411 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
412
413 ITimeSyncCb timeSyncCbk = {.onTimeSyncResult = onDevTimeSyncResult};
414 int32_t ret = StartTimeSync(pkgName.c_str(), peerDevId.c_str(), TimeSyncAccuracy::SUPER_HIGH_ACCURACY,
415 TimeSyncPeriod::SHORT_PERIOD, &timeSyncCbk);
416 if (ret != 0) {
417 AVTRANS_LOGE("StartTimeSync failed ret:%{public}" PRId32, ret);
418 return ERR_DH_AVT_TIME_SYNC_FAILED;
419 }
420
421 std::lock_guard<std::mutex> lock(timeSyncMtx_);
422 timeSyncSessNames_.insert(sessName + "_" + peerDevId);
423
424 return DH_AVT_SUCCESS;
425 }
426
StopDeviceTimeSync(const std::string & pkgName,const std::string & sessName,const std::string & peerDevId)427 int32_t SoftbusChannelAdapter::StopDeviceTimeSync(const std::string &pkgName, const std::string& sessName,
428 const std::string &peerDevId)
429 {
430 AVTRANS_LOGI("Stop device time sync for peerDeviceId:%{public}s.", GetAnonyString(peerDevId).c_str());
431 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
432
433 int32_t ret = StopTimeSync(pkgName.c_str(), peerDevId.c_str());
434 if (ret != 0) {
435 AVTRANS_LOGE("StopTimeSync failed ret:%{public}" PRId32, ret);
436 return ERR_DH_AVT_TIME_SYNC_FAILED;
437 }
438
439 std::lock_guard<std::mutex> lock(timeSyncMtx_);
440 timeSyncSessNames_.erase(sessName + "_" + peerDevId);
441
442 return DH_AVT_SUCCESS;
443 }
444
GetSessIdBySessName(const std::string & sessName,const std::string & peerDevId)445 int32_t SoftbusChannelAdapter::GetSessIdBySessName(const std::string& sessName, const std::string &peerDevId)
446 {
447 std::lock_guard<std::mutex> lock(idMapMutex_);
448 std::string idMapKey = sessName + "_" + peerDevId;
449 if (devId2SessIdMap_.find(idMapKey) == devId2SessIdMap_.end()) {
450 AVTRANS_LOGI("Can not find sessionId for sessName:%{public}s, peerDevId:%{public}s.",
451 sessName.c_str(), GetAnonyString(peerDevId).c_str());
452 return -1;
453 }
454 return devId2SessIdMap_[idMapKey];
455 }
456
GetSessionNameById(int32_t sessionId)457 std::string SoftbusChannelAdapter::GetSessionNameById(int32_t sessionId)
458 {
459 std::lock_guard<std::mutex> lock(idMapMutex_);
460 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
461 if (it->second == sessionId) {
462 return it->first;
463 }
464 }
465
466 AVTRANS_LOGE("No available channel or invalid sessionId:%{public}" PRId32, sessionId);
467 return EMPTY_STRING;
468 }
469
OnSoftbusChannelOpened(std::string peerSessionName,int32_t sessionId,std::string peerDevId,int32_t result)470 int32_t SoftbusChannelAdapter::OnSoftbusChannelOpened(std::string peerSessionName, int32_t sessionId,
471 std::string peerDevId, int32_t result)
472 {
473 AVTRANS_LOGI("On softbus channel opened, sessionId: %{public}" PRId32", result: %{public}" PRId32
474 " peerSessionName: %{public}s", sessionId, result, peerSessionName.c_str());
475 TRUE_RETURN_V_MSG_E(peerSessionName.empty(), ERR_DH_AVT_INVALID_PARAM, "peerSessionName is empty().");
476 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "peerDevId is empty().");
477
478 std::lock_guard<std::mutex> lock(idMapMutex_);
479 std::string mySessionName = FindSessNameByPeerSessName(peerSessionName);
480 TRUE_RETURN_V_MSG_E(mySessionName.empty(), ERR_DH_AVT_INVALID_PARAM, "mySessionName is empty().");
481 EventType type = (result == 0) ? EventType::EVENT_CHANNEL_OPENED : EventType::EVENT_CHANNEL_OPEN_FAIL;
482 AVTransEvent event = {type, mySessionName, peerDevId};
483 {
484 std::lock_guard<std::mutex> lock(listenerMtx_);
485 for (auto it = listenerMap_.begin(); it != listenerMap_.end(); it++) {
486 if (((it->first).find(mySessionName) != std::string::npos) && (it->second != nullptr)) {
487 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
488 devId2SessIdMap_.erase(it->first);
489 devId2SessIdMap_.insert(std::make_pair(it->first, sessionId));
490 }
491 }
492 }
493 std::string idMapKey = mySessionName + "_" + peerDevId;
494 if (devId2SessIdMap_.find(idMapKey) == devId2SessIdMap_.end()) {
495 AVTRANS_LOGI("Can not find sessionId for mySessionName:%{public}s, peerDevId:%{public}s. try to insert it.",
496 mySessionName.c_str(), GetAnonyString(peerDevId).c_str());
497 devId2SessIdMap_.insert(std::make_pair(idMapKey, sessionId));
498 }
499 return DH_AVT_SUCCESS;
500 }
501
OnSoftbusChannelClosed(int32_t sessionId,ShutdownReason reason)502 void SoftbusChannelAdapter::OnSoftbusChannelClosed(int32_t sessionId, ShutdownReason reason)
503 {
504 (void)reason;
505 AVTRANS_LOGI("On softbus channel closed, sessionId:%{public}" PRId32, sessionId);
506
507 std::string peerDevId = GetPeerDevIdBySessId(sessionId);
508 AVTransEvent event = {EventType::EVENT_CHANNEL_CLOSED, "", peerDevId};
509
510 std::lock_guard<std::mutex> lock(idMapMutex_);
511 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end();) {
512 if (it->second == sessionId) {
513 event.content = GetOwnerFromSessName(it->first);
514 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
515 it = devId2SessIdMap_.erase(it);
516 } else {
517 it++;
518 }
519 }
520 }
521
OnSoftbusBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)522 void SoftbusChannelAdapter::OnSoftbusBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
523 {
524 AVTRANS_LOGI("On softbus channel bytes received, sessionId:%{public}" PRId32, sessionId);
525 TRUE_RETURN(data == nullptr, "input data is nullptr.");
526 TRUE_RETURN(dataLen == 0, "input dataLen is 0.");
527 TRUE_RETURN(dataLen > DSOFTBUS_INPUT_MAX_RECV_DATA_LEN, "input dataLen is over size.");
528
529 std::string peerDevId = GetPeerDevIdBySessId(sessionId);
530 AVTRANS_LOGI("OnSoftbusBytesReceived peerDevId:%{public}s.", GetAnonyString(peerDevId).c_str());
531
532 std::string dataStr = std::string(reinterpret_cast<const char *>(data), dataLen);
533 AVTransEvent event = {EventType::EVENT_DATA_RECEIVED, dataStr, peerDevId};
534
535 std::lock_guard<std::mutex> lock(idMapMutex_);
536 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
537 if (it->second == sessionId) {
538 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
539 }
540 }
541 }
542
OnSoftbusStreamReceived(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * frameInfo)543 void SoftbusChannelAdapter::OnSoftbusStreamReceived(int32_t sessionId, const StreamData *data,
544 const StreamData *ext, const StreamFrameInfo *frameInfo)
545 {
546 (void)frameInfo;
547 TRUE_RETURN(data == nullptr, "input data is nullptr.");
548 TRUE_RETURN(ext == nullptr, "input ext data is nullptr.");
549
550 std::lock_guard<std::mutex> lock(idMapMutex_);
551 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
552 if (it->second == sessionId) {
553 std::lock_guard<std::mutex> lock(listenerMtx_);
554 ISoftbusChannelListener *listener = listenerMap_[it->first];
555 TRUE_RETURN(listener == nullptr, "Can not find channel listener.");
556 listener->OnStreamReceived(data, ext);
557 }
558 }
559 }
560
OnSoftbusTimeSyncResult(const TimeSyncResultInfo * info,int32_t result)561 void SoftbusChannelAdapter::OnSoftbusTimeSyncResult(const TimeSyncResultInfo *info, int32_t result)
562 {
563 AVTRANS_LOGI("On softbus channel time sync result:%{public}" PRId32, result);
564 TRUE_RETURN(result == 0, "On softbus channel time sync failed");
565
566 if (info == nullptr) {
567 AVTRANS_LOGE("info id nullptr");
568 return;
569 }
570 int32_t millisecond = info->result.millisecond;
571 int32_t microsecond = info->result.microsecond;
572 TimeSyncAccuracy accuracy = info->result.accuracy;
573 AVTRANS_LOGI("Time sync success, flag:%{public}" PRId32", millisecond:%{public}" PRId32 ", microsecond:%{public}"
574 PRId32 ", accuracy:%{public}" PRId32, info->flag, millisecond, microsecond, accuracy);
575
576 std::string targetDevId(info->target.targetNetworkId);
577 std::string masterDevId(info->target.masterNetworkId);
578 std::lock_guard<std::mutex> lock(timeSyncMtx_);
579 for (auto sessName : timeSyncSessNames_) {
580 std::lock_guard<std::mutex> lock(listenerMtx_);
581 ISoftbusChannelListener *listener = listenerMap_[sessName];
582 if (listener != nullptr) {
583 listener->OnChannelEvent({EventType::EVENT_TIME_SYNC_RESULT, std::to_string(millisecond), targetDevId});
584 }
585 }
586 }
587
GetPeerDevIdBySessId(int32_t sessionId)588 std::string SoftbusChannelAdapter::GetPeerDevIdBySessId(int32_t sessionId)
589 {
590 std::lock_guard<std::mutex> lock(idMapMutex_);
591 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
592 if (it->second != sessionId) {
593 continue;
594 }
595 std::string::size_type position = (it->first).find_last_of("_");
596 if (position == std::string::npos) {
597 continue;
598 }
599 std::string peerDevId = (it->first).substr(position + 1);
600 if (peerDevId != AV_TRANS_SPECIAL_DEVICE_ID) {
601 return peerDevId;
602 }
603 }
604 return EMPTY_STRING;
605 }
606
GetOwnerFromSessName(const std::string & sessName)607 std::string SoftbusChannelAdapter::GetOwnerFromSessName(const std::string &sessName)
608 {
609 std::string::size_type position = sessName.find_first_of("_");
610 if (position != std::string::npos) {
611 return sessName.substr(0, position);
612 }
613 if (sessName == AV_SYNC_SENDER_CONTROL_SESSION_NAME || sessName == AV_SYNC_RECEIVER_CONTROL_SESSION_NAME) {
614 return sessName;
615 }
616 return EMPTY_STRING;
617 }
618
SendChannelEvent(const std::string & sessName,const AVTransEvent event)619 void SoftbusChannelAdapter::SendChannelEvent(const std::string &sessName, const AVTransEvent event)
620 {
621 AVTRANS_LOGI("SendChannelEvent event.type_%{public}" PRId32, event.type);
622 pthread_setname_np(pthread_self(), SEND_CHANNEL_EVENT);
623
624 ISoftbusChannelListener *listener = nullptr;
625 {
626 std::lock_guard<std::mutex> lock(listenerMtx_);
627 listener = listenerMap_[sessName];
628 TRUE_RETURN(listener == nullptr, "input listener is nullptr.");
629 }
630 listener->OnChannelEvent(event);
631 }
632 } // namespace DistributedHardware
633 } // namespace OHOS