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