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