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