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 if (sizeof(qos[0]) == 0) {
200 AVTRANS_LOGE("qos[0] siez of zero");
201 return ERR_DH_AVT_SESSION_ERROR;
202 }
203 int32_t ret = Listen(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessListener_);
204 if (ret != 0) {
205 AVTRANS_LOGE("Listen socket error for sessionName:%{public}s", sessName.c_str());
206 return ERR_DH_AVT_SESSION_ERROR;
207 }
208 {
209 std::lock_guard<std::mutex> lock(serverMapMtx_);
210 serverMap_.insert(std::make_pair(pkgName + "_" + sessName, socketId));
211 }
212 AVTRANS_LOGI("Create session server success for sessionName:%{public}s.", sessName.c_str());
213 return DH_AVT_SUCCESS;
214 }
215
RemoveChannelServer(const std::string & pkgName,const std::string & sessName)216 int32_t SoftbusChannelAdapter::RemoveChannelServer(const std::string& pkgName, const std::string &sessName)
217 {
218 AVTRANS_LOGI("Remove session server for sessionName:%{public}s.", sessName.c_str());
219 TRUE_RETURN_V_MSG_E(pkgName.empty(), ERR_DH_AVT_INVALID_PARAM, "input pkgName is empty.");
220 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessionName is empty.");
221
222 std::string serverMapKey = pkgName + "_" + sessName;
223 int32_t serverSocketId = INVALID_SESSION_ID;
224 {
225 std::lock_guard<std::mutex> lock(serverMapMtx_);
226 for (auto it = serverMap_.begin(); it != serverMap_.end(); it++) {
227 if (((it->first).find(serverMapKey) != std::string::npos)) {
228 serverSocketId = it->second;
229 serverMap_.erase(it->first);
230 break;
231 }
232 }
233 }
234 AVTRANS_LOGI("Remove session server success for serverSocketId:%{public}" PRId32, serverSocketId);
235 Shutdown(serverSocketId);
236 int32_t sessionId = INVALID_SESSION_ID;
237 {
238 std::lock_guard<std::mutex> lock(idMapMutex_);
239 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
240 if ((it->first).find(sessName) != std::string::npos) {
241 sessionId = it->second;
242 devId2SessIdMap_.erase(it->first);
243 break;
244 }
245 }
246 }
247 Shutdown(sessionId);
248 AVTRANS_LOGI("Remove session server success for sessionName:%{public}s.", sessName.c_str());
249 return DH_AVT_SUCCESS;
250 }
251
SendEventChannelOPened(const std::string & mySessName,const std::string & peerDevId)252 void OHOS::DistributedHardware::SoftbusChannelAdapter::SendEventChannelOPened(const std::string & mySessName,
253 const std::string & peerDevId)
254 {
255 EventType type = EventType::EVENT_CHANNEL_OPENED;
256 AVTransEvent event = {type, mySessName, peerDevId};
257 std::lock_guard<std::mutex> lock(listenerMtx_);
258 {
259 for (auto it = listenerMap_.begin(); it != listenerMap_.end(); it++) {
260 if (((it->first).find(mySessName) != std::string::npos) && (it->second != nullptr)) {
261 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
262 }
263 }
264 }
265 }
266
OpenSoftbusChannel(const std::string & mySessName,const std::string & peerSessName,const std::string & peerDevId)267 int32_t SoftbusChannelAdapter::OpenSoftbusChannel(const std::string &mySessName, const std::string &peerSessName,
268 const std::string &peerDevId)
269 {
270 AVTRANS_LOGI("Open softbus channel for mySessName:%{public}s, peerSessName:%{public}s, peerDevId:%{public}s.",
271 mySessName.c_str(), peerSessName.c_str(), GetAnonyString(peerDevId).c_str());
272 TRUE_RETURN_V_MSG_E(mySessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input mySessName is empty.");
273 TRUE_RETURN_V_MSG_E(peerSessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerSessName is empty.");
274 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
275 std::string ownerName = GetOwnerFromSessName(mySessName);
276 std::string PkgName = TransName2PkgName(ownerName);
277 int32_t existSessId = GetSessIdBySessName(mySessName, peerDevId);
278 if (existSessId > 0) {
279 AVTRANS_LOGI("Softbus channel already opened, sessionId:%{public}" PRId32, existSessId);
280 return ERR_DH_AVT_SESSION_HAS_OPENED;
281 }
282 QosTV qos[] = {
283 {.qos = QOS_TYPE_MIN_BW, .value = 40 * 1024 * 1024},
284 {.qos = QOS_TYPE_MAX_LATENCY, .value = 4000},
285 {.qos = QOS_TYPE_MIN_LATENCY, .value = 2000},
286 };
287 TransDataType dataType = TransDataType::DATA_TYPE_BYTES;
288 if (mySessName.find("avtrans.data") != std::string::npos) {
289 dataType = TransDataType::DATA_TYPE_VIDEO_STREAM;
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 int32_t socketId = Socket(clientInfo);
299 if (socketId <0) {
300 return ERR_DH_AVT_SESSION_ERROR;
301 }
302 if (sizeof(qos[0]) == 0) {
303 return ERR_DH_AVT_SESSION_ERROR;
304 }
305 int32_t ret = Bind(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessListener_);
306 if (ret != DH_AVT_SUCCESS) {
307 AVTRANS_LOGE("Bind SocketClient error");
308 return ERR_DH_AVT_SESSION_ERROR;
309 }
310 {
311 std::lock_guard<std::mutex> lock(idMapMutex_);
312 devId2SessIdMap_.insert(std::make_pair(mySessName + "_" + peerDevId, socketId));
313 }
314 SendEventChannelOPened(mySessName, peerDevId);
315 AVTRANS_LOGI("Open softbus channel finished for mySessName:%{public}s.", mySessName.c_str());
316 return DH_AVT_SUCCESS;
317 }
318
CloseSoftbusChannel(const std::string & sessName,const std::string & peerDevId)319 int32_t SoftbusChannelAdapter::CloseSoftbusChannel(const std::string& sessName, const std::string &peerDevId)
320 {
321 AVTRANS_LOGI("Close softbus channel for sessName:%{public}s, peerDevId:%{public}s.", sessName.c_str(),
322 GetAnonyString(peerDevId).c_str());
323 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
324 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
325
326 int32_t sessionId = GetSessIdBySessName(sessName, peerDevId);
327 Shutdown(sessionId);
328 {
329 std::lock_guard<std::mutex> lock(idMapMutex_);
330 devId2SessIdMap_.erase(sessName + "_" + peerDevId);
331 }
332
333 AVTRANS_LOGI("Close softbus channel success, sessionId:%{public}" PRId32, sessionId);
334 return DH_AVT_SUCCESS;
335 }
336
SendBytesData(const std::string & sessName,const std::string & peerDevId,const std::string & data)337 int32_t SoftbusChannelAdapter::SendBytesData(const std::string& sessName, const std::string &peerDevId,
338 const std::string &data)
339 {
340 AVTRANS_LOGI("Send bytes data for sessName:%{public}s, peerDevId:%{public}s.",
341 sessName.c_str(), GetAnonyString(peerDevId).c_str());
342 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
343 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
344 TRUE_RETURN_V_MSG_E(data.empty(), ERR_DH_AVT_INVALID_PARAM, "input data string is empty.");
345
346 int32_t existSessId = GetSessIdBySessName(sessName, peerDevId);
347 if (existSessId < 0) {
348 AVTRANS_LOGI("Can not find sessionId for mySessName:%{public}s, peerDevId:%{public}s.",
349 sessName.c_str(), GetAnonyString(peerDevId).c_str());
350 return ERR_DH_AVT_SEND_DATA_FAILED;
351 }
352 int32_t ret = SendBytes(existSessId, data.c_str(), strlen(data.c_str()));
353 if (ret != DH_AVT_SUCCESS) {
354 AVTRANS_LOGE("Send bytes data failed ret:%{public}" PRId32, ret);
355 return ERR_DH_AVT_SEND_DATA_FAILED;
356 }
357 return DH_AVT_SUCCESS;
358 }
359
SendStreamData(const std::string & sessName,const std::string & peerDevId,const StreamData * data,const StreamData * ext)360 int32_t SoftbusChannelAdapter::SendStreamData(const std::string& sessName, const std::string &peerDevId,
361 const StreamData *data, const StreamData *ext)
362 {
363 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
364 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
365 TRUE_RETURN_V_MSG_E(data == nullptr, ERR_DH_AVT_INVALID_PARAM, "input data is nullptr.");
366 TRUE_RETURN_V_MSG_E(ext == nullptr, ERR_DH_AVT_INVALID_PARAM, "input ext data is nullptr.");
367
368 StreamFrameInfo frameInfo = {0};
369 int32_t existSessId = GetSessIdBySessName(sessName, peerDevId);
370 if (existSessId < 0) {
371 AVTRANS_LOGI("Can not find sessionId for mySessName:%{public}s, peerDevId:%{public}s.",
372 sessName.c_str(), GetAnonyString(peerDevId).c_str());
373 return ERR_DH_AVT_SEND_DATA_FAILED;
374 }
375 int32_t ret = SendStream(existSessId, data, ext, &frameInfo);
376 if (ret != DH_AVT_SUCCESS) {
377 AVTRANS_LOGE("Send stream data failed ret:%{public}" PRId32, ret);
378 return ERR_DH_AVT_SEND_DATA_FAILED;
379 }
380 return DH_AVT_SUCCESS;
381 }
382
RegisterChannelListener(const std::string & sessName,const std::string & peerDevId,ISoftbusChannelListener * listener)383 int32_t SoftbusChannelAdapter::RegisterChannelListener(const std::string& sessName, const std::string &peerDevId,
384 ISoftbusChannelListener *listener)
385 {
386 AVTRANS_LOGI("Register channel listener for sessName:%{public}s, peerDevId:%{public}s.",
387 sessName.c_str(), GetAnonyString(peerDevId).c_str());
388 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
389 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
390 TRUE_RETURN_V_MSG_E(listener == nullptr, ERR_DH_AVT_INVALID_PARAM, "input callback is nullptr.");
391
392 std::lock_guard<std::mutex> lock(listenerMtx_);
393 listenerMap_[sessName + "_" + peerDevId] = listener;
394
395 return DH_AVT_SUCCESS;
396 }
397
UnRegisterChannelListener(const std::string & sessName,const std::string & peerDevId)398 int32_t SoftbusChannelAdapter::UnRegisterChannelListener(const std::string& sessName, const std::string &peerDevId)
399 {
400 AVTRANS_LOGI("Unregister channel listener for sessName:%{public}s, peerDevId:%{public}s.",
401 sessName.c_str(), GetAnonyString(peerDevId).c_str());
402 TRUE_RETURN_V_MSG_E(sessName.empty(), ERR_DH_AVT_INVALID_PARAM, "input sessName is empty.");
403 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
404
405 std::lock_guard<std::mutex> lock(listenerMtx_);
406 listenerMap_.erase(sessName + "_" + peerDevId);
407
408 return DH_AVT_SUCCESS;
409 }
410
StartDeviceTimeSync(const std::string & pkgName,const std::string & sessName,const std::string & peerDevId)411 int32_t SoftbusChannelAdapter::StartDeviceTimeSync(const std::string &pkgName, const std::string& sessName,
412 const std::string &peerDevId)
413 {
414 AVTRANS_LOGI("Start device time sync for peerDeviceId:%{public}s.", GetAnonyString(peerDevId).c_str());
415 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
416
417 ITimeSyncCb timeSyncCbk = {.onTimeSyncResult = onDevTimeSyncResult};
418 int32_t ret = StartTimeSync(pkgName.c_str(), peerDevId.c_str(), TimeSyncAccuracy::SUPER_HIGH_ACCURACY,
419 TimeSyncPeriod::SHORT_PERIOD, &timeSyncCbk);
420 if (ret != 0) {
421 AVTRANS_LOGE("StartTimeSync failed ret:%{public}" PRId32, ret);
422 return ERR_DH_AVT_TIME_SYNC_FAILED;
423 }
424
425 std::lock_guard<std::mutex> lock(timeSyncMtx_);
426 timeSyncSessNames_.insert(sessName + "_" + peerDevId);
427
428 return DH_AVT_SUCCESS;
429 }
430
StopDeviceTimeSync(const std::string & pkgName,const std::string & sessName,const std::string & peerDevId)431 int32_t SoftbusChannelAdapter::StopDeviceTimeSync(const std::string &pkgName, const std::string& sessName,
432 const std::string &peerDevId)
433 {
434 AVTRANS_LOGI("Stop device time sync for peerDeviceId:%{public}s.", GetAnonyString(peerDevId).c_str());
435 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "input peerDevId is empty.");
436
437 int32_t ret = StopTimeSync(pkgName.c_str(), peerDevId.c_str());
438 if (ret != 0) {
439 AVTRANS_LOGE("StopTimeSync failed ret:%{public}" PRId32, ret);
440 return ERR_DH_AVT_TIME_SYNC_FAILED;
441 }
442
443 std::lock_guard<std::mutex> lock(timeSyncMtx_);
444 timeSyncSessNames_.erase(sessName + "_" + peerDevId);
445
446 return DH_AVT_SUCCESS;
447 }
448
GetSessIdBySessName(const std::string & sessName,const std::string & peerDevId)449 int32_t SoftbusChannelAdapter::GetSessIdBySessName(const std::string& sessName, const std::string &peerDevId)
450 {
451 std::lock_guard<std::mutex> lock(idMapMutex_);
452 std::string idMapKey = sessName + "_" + peerDevId;
453 if (devId2SessIdMap_.find(idMapKey) == devId2SessIdMap_.end()) {
454 AVTRANS_LOGI("Can not find sessionId for sessName:%{public}s, peerDevId:%{public}s.",
455 sessName.c_str(), GetAnonyString(peerDevId).c_str());
456 return -1;
457 }
458 return devId2SessIdMap_[idMapKey];
459 }
460
GetSessionNameById(int32_t sessionId)461 std::string SoftbusChannelAdapter::GetSessionNameById(int32_t sessionId)
462 {
463 std::lock_guard<std::mutex> lock(idMapMutex_);
464 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
465 if (it->second == sessionId) {
466 return it->first;
467 }
468 }
469
470 AVTRANS_LOGE("No available channel or invalid sessionId:%{public}" PRId32, sessionId);
471 return EMPTY_STRING;
472 }
473
OnSoftbusChannelOpened(std::string peerSessionName,int32_t sessionId,std::string peerDevId,int32_t result)474 int32_t SoftbusChannelAdapter::OnSoftbusChannelOpened(std::string peerSessionName, int32_t sessionId,
475 std::string peerDevId, int32_t result)
476 {
477 AVTRANS_LOGI("On softbus channel opened, sessionId: %{public}" PRId32", result: %{public}" PRId32
478 " peerSessionName: %{public}s", sessionId, result, peerSessionName.c_str());
479 TRUE_RETURN_V_MSG_E(peerSessionName.empty(), ERR_DH_AVT_INVALID_PARAM, "peerSessionName is empty().");
480 TRUE_RETURN_V_MSG_E(peerDevId.empty(), ERR_DH_AVT_INVALID_PARAM, "peerDevId is empty().");
481
482 std::lock_guard<std::mutex> lock(idMapMutex_);
483 std::string mySessionName = FindSessNameByPeerSessName(peerSessionName);
484 TRUE_RETURN_V_MSG_E(mySessionName.empty(), ERR_DH_AVT_INVALID_PARAM, "mySessionName is empty().");
485 EventType type = (result == 0) ? EventType::EVENT_CHANNEL_OPENED : EventType::EVENT_CHANNEL_OPEN_FAIL;
486 AVTransEvent event = {type, mySessionName, peerDevId};
487 {
488 std::lock_guard<std::mutex> subLock(listenerMtx_);
489 for (auto it = listenerMap_.begin(); it != listenerMap_.end(); it++) {
490 if (((it->first).find(mySessionName) != std::string::npos) && (it->second != nullptr)) {
491 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
492 devId2SessIdMap_.erase(it->first);
493 devId2SessIdMap_.insert(std::make_pair(it->first, sessionId));
494 }
495 }
496 }
497 std::string idMapKey = mySessionName + "_" + peerDevId;
498 if (devId2SessIdMap_.find(idMapKey) == devId2SessIdMap_.end()) {
499 AVTRANS_LOGI("Can not find sessionId for mySessionName:%{public}s, peerDevId:%{public}s. try to insert it.",
500 mySessionName.c_str(), GetAnonyString(peerDevId).c_str());
501 devId2SessIdMap_.insert(std::make_pair(idMapKey, sessionId));
502 }
503 return DH_AVT_SUCCESS;
504 }
505
OnSoftbusChannelClosed(int32_t sessionId,ShutdownReason reason)506 void SoftbusChannelAdapter::OnSoftbusChannelClosed(int32_t sessionId, ShutdownReason reason)
507 {
508 (void)reason;
509 AVTRANS_LOGI("On softbus channel closed, sessionId:%{public}" PRId32, sessionId);
510
511 std::string peerDevId = GetPeerDevIdBySessId(sessionId);
512 AVTransEvent event = {EventType::EVENT_CHANNEL_CLOSED, "", peerDevId};
513
514 std::lock_guard<std::mutex> lock(idMapMutex_);
515 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end();) {
516 if (it->second == sessionId) {
517 event.content = GetOwnerFromSessName(it->first);
518 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
519 it = devId2SessIdMap_.erase(it);
520 } else {
521 it++;
522 }
523 }
524 }
525
OnSoftbusBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)526 void SoftbusChannelAdapter::OnSoftbusBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
527 {
528 AVTRANS_LOGI("On softbus channel bytes received, sessionId:%{public}" PRId32, sessionId);
529 TRUE_RETURN(data == nullptr, "input data is nullptr.");
530 TRUE_RETURN(dataLen == 0, "input dataLen is 0.");
531 TRUE_RETURN(dataLen > DSOFTBUS_INPUT_MAX_RECV_DATA_LEN, "input dataLen is over size.");
532
533 std::string peerDevId = GetPeerDevIdBySessId(sessionId);
534 AVTRANS_LOGI("OnSoftbusBytesReceived peerDevId:%{public}s.", GetAnonyString(peerDevId).c_str());
535
536 std::string dataStr = std::string(reinterpret_cast<const char *>(data), dataLen);
537 AVTransEvent event = {EventType::EVENT_DATA_RECEIVED, dataStr, peerDevId};
538
539 std::lock_guard<std::mutex> lock(idMapMutex_);
540 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
541 if (it->second == sessionId) {
542 std::thread(&SoftbusChannelAdapter::SendChannelEvent, this, it->first, event).detach();
543 }
544 }
545 }
546
OnSoftbusStreamReceived(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * frameInfo)547 void SoftbusChannelAdapter::OnSoftbusStreamReceived(int32_t sessionId, const StreamData *data,
548 const StreamData *ext, const StreamFrameInfo *frameInfo)
549 {
550 (void)frameInfo;
551 TRUE_RETURN(data == nullptr, "input data is nullptr.");
552 TRUE_RETURN(ext == nullptr, "input ext data is nullptr.");
553
554 std::lock_guard<std::mutex> lock(idMapMutex_);
555 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
556 if (it->second == sessionId) {
557 std::lock_guard<std::mutex> subLock(listenerMtx_);
558 ISoftbusChannelListener *listener = listenerMap_[it->first];
559 TRUE_RETURN(listener == nullptr, "Can not find channel listener.");
560 listener->OnStreamReceived(data, ext);
561 }
562 }
563 }
564
OnSoftbusTimeSyncResult(const TimeSyncResultInfo * info,int32_t result)565 void SoftbusChannelAdapter::OnSoftbusTimeSyncResult(const TimeSyncResultInfo *info, int32_t result)
566 {
567 AVTRANS_LOGI("On softbus channel time sync result:%{public}" PRId32, result);
568 TRUE_RETURN(result == 0, "On softbus channel time sync failed");
569
570 if (info == nullptr) {
571 AVTRANS_LOGE("info id nullptr");
572 return;
573 }
574 int32_t millisecond = info->result.millisecond;
575 int32_t microsecond = info->result.microsecond;
576 TimeSyncAccuracy accuracy = info->result.accuracy;
577 AVTRANS_LOGI("Time sync success, flag:%{public}" PRId32", millisecond:%{public}" PRId32 ", microsecond:%{public}"
578 PRId32 ", accuracy:%{public}" PRId32, info->flag, millisecond, microsecond, accuracy);
579
580 std::string targetDevId(info->target.targetNetworkId);
581 std::string masterDevId(info->target.masterNetworkId);
582 std::lock_guard<std::mutex> lock(timeSyncMtx_);
583 for (auto sessName : timeSyncSessNames_) {
584 std::lock_guard<std::mutex> subLock(listenerMtx_);
585 ISoftbusChannelListener *listener = listenerMap_[sessName];
586 if (listener != nullptr) {
587 listener->OnChannelEvent({EventType::EVENT_TIME_SYNC_RESULT, std::to_string(millisecond), targetDevId});
588 }
589 }
590 }
591
GetPeerDevIdBySessId(int32_t sessionId)592 std::string SoftbusChannelAdapter::GetPeerDevIdBySessId(int32_t sessionId)
593 {
594 std::lock_guard<std::mutex> lock(idMapMutex_);
595 for (auto it = devId2SessIdMap_.begin(); it != devId2SessIdMap_.end(); it++) {
596 if (it->second != sessionId) {
597 continue;
598 }
599 std::string::size_type position = (it->first).find_last_of("_");
600 if (position == std::string::npos) {
601 continue;
602 }
603 std::string peerDevId = (it->first).substr(position + 1);
604 if (peerDevId != AV_TRANS_SPECIAL_DEVICE_ID) {
605 return peerDevId;
606 }
607 }
608 return EMPTY_STRING;
609 }
610
GetOwnerFromSessName(const std::string & sessName)611 std::string SoftbusChannelAdapter::GetOwnerFromSessName(const std::string &sessName)
612 {
613 std::string::size_type position = sessName.find_first_of("_");
614 if (position != std::string::npos) {
615 return sessName.substr(0, position);
616 }
617 if (sessName == AV_SYNC_SENDER_CONTROL_SESSION_NAME || sessName == AV_SYNC_RECEIVER_CONTROL_SESSION_NAME) {
618 return sessName;
619 }
620 return EMPTY_STRING;
621 }
622
SendChannelEvent(const std::string & sessName,const AVTransEvent event)623 void SoftbusChannelAdapter::SendChannelEvent(const std::string &sessName, const AVTransEvent event)
624 {
625 AVTRANS_LOGI("SendChannelEvent event.type_%{public}" PRId32, event.type);
626 pthread_setname_np(pthread_self(), SEND_CHANNEL_EVENT);
627
628 ISoftbusChannelListener *listener = nullptr;
629 {
630 std::lock_guard<std::mutex> lock(listenerMtx_);
631 listener = listenerMap_[sessName];
632 TRUE_RETURN(listener == nullptr, "input listener is nullptr.");
633 }
634 listener->OnChannelEvent(event);
635 }
636 } // namespace DistributedHardware
637 } // namespace OHOS