• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_adapter.h"
17 #include "softbus_error_code.h"
18 
19 #include <securec.h>
20 
21 #undef DH_LOG_TAG
22 #define DH_LOG_TAG "SoftbusAdapter"
23 
24 namespace OHOS {
25 namespace DistributedHardware {
26 IMPLEMENT_SINGLE_INSTANCE(SoftbusAdapter);
AudioOnSoftbusSessionOpened(int32_t sessionId,int32_t result)27 static int32_t AudioOnSoftbusSessionOpened(int32_t sessionId, int32_t result)
28 {
29     return SoftbusAdapter::GetInstance().OnSoftbusSessionOpened(sessionId, result);
30 }
31 
AudioOnSoftbusSessionClosed(int32_t sessionId)32 static void AudioOnSoftbusSessionClosed(int32_t sessionId)
33 {
34     SoftbusAdapter::GetInstance().OnSoftbusSessionClosed(sessionId);
35 }
36 
AudioOnBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)37 static void AudioOnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
38 {
39     SoftbusAdapter::GetInstance().OnBytesReceived(sessionId, data, dataLen);
40 }
41 
AudioOnStreamReceived(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * frameInfo)42 static void AudioOnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext,
43     const StreamFrameInfo *frameInfo)
44 {
45     SoftbusAdapter::GetInstance().OnStreamReceived(sessionId, data, ext, frameInfo);
46 }
47 
AudioOnMessageReceived(int sessionId,const void * data,unsigned int dataLen)48 static void AudioOnMessageReceived(int sessionId, const void *data, unsigned int dataLen)
49 {
50     SoftbusAdapter::GetInstance().OnMessageReceived(sessionId, data, dataLen);
51 }
52 
AudioOnQosEvent(int sessionId,int eventId,int tvCount,const QosTv * tvList)53 static void AudioOnQosEvent(int sessionId, int eventId, int tvCount, const QosTv *tvList)
54 {
55     SoftbusAdapter::GetInstance().OnQosEvent(sessionId, eventId, tvCount, tvList);
56 }
57 
SoftbusAdapter()58 SoftbusAdapter::SoftbusAdapter()
59 {
60     DHLOGD("Softbus adapter constructed.");
61     sessListener_.OnSessionOpened = AudioOnSoftbusSessionOpened;
62     sessListener_.OnSessionClosed = AudioOnSoftbusSessionClosed;
63     sessListener_.OnBytesReceived = AudioOnBytesReceived;
64     sessListener_.OnStreamReceived = AudioOnStreamReceived;
65     sessListener_.OnMessageReceived = AudioOnMessageReceived;
66     sessListener_.OnQosEvent = AudioOnQosEvent;
67 }
68 
~SoftbusAdapter()69 SoftbusAdapter::~SoftbusAdapter()
70 {
71     DHLOGD("Softbus adapter destructed.");
72 }
73 
CreateSoftbusSessionServer(const std::string & pkgName,const std::string & sessionName,const std::string & peerDevId)74 int32_t SoftbusAdapter::CreateSoftbusSessionServer(const std::string &pkgName, const std::string &sessionName,
75     const std::string &peerDevId)
76 {
77     DHLOGI("Create server, sessName: %s peerDevId: %s.", sessionName.c_str(), GetAnonyString(peerDevId).c_str());
78     std::lock_guard<std::mutex> setLock(sessSetMtx_);
79     if (mapSessionSet_.find(sessionName) == mapSessionSet_.end()) {
80         int32_t ret = CreateSessionServer(pkgName.c_str(), sessionName.c_str(), &sessListener_);
81         if (ret != SOFTBUS_OK) {
82             DHLOGE("Create session server failed, ret %d.", ret);
83             return ret;
84         }
85     } else {
86         DHLOGD("Session is already created.");
87         return DH_SUCCESS;
88     }
89 
90     mapSessionSet_[sessionName].insert(peerDevId);
91     DHLOGI("Create session server success.");
92     return DH_SUCCESS;
93 }
94 
RemoveSoftbusSessionServer(const std::string & pkgName,const std::string & sessionName,const std::string & peerDevId)95 int32_t SoftbusAdapter::RemoveSoftbusSessionServer(const std::string &pkgName, const std::string &sessionName,
96     const std::string &peerDevId)
97 {
98     DHLOGI("Remove server, sessName: %s peerDevId: %s.", sessionName.c_str(), GetAnonyString(peerDevId).c_str());
99     std::lock_guard<std::mutex> setLock(sessSetMtx_);
100     if (mapSessionSet_.find(sessionName) == mapSessionSet_.end()) {
101         DHLOGE("Session server already removed.");
102         return DH_SUCCESS;
103     }
104     mapSessionSet_[sessionName].erase(peerDevId);
105     if (mapSessionSet_[sessionName].empty()) {
106         mapSessionSet_.erase(sessionName);
107         int32_t ret = RemoveSessionServer(pkgName.c_str(), sessionName.c_str());
108         if (ret != SOFTBUS_OK) {
109             DHLOGE("Remove session server failed. Error code %d.", ret);
110         }
111     }
112     DHLOGI("Remove session server success.");
113     return DH_SUCCESS;
114 }
115 
OpenSoftbusSession(const std::string & localSessionName,const std::string & peerSessionName,const std::string & peerDevId)116 int32_t SoftbusAdapter::OpenSoftbusSession(const std::string &localSessionName, const std::string &peerSessionName,
117     const std::string &peerDevId)
118 {
119     DHLOGI("Open softbus session, localSess: %s peerSess: %s peerDevId: %s.", localSessionName.c_str(),
120         peerSessionName.c_str(), GetAnonyString(peerDevId).c_str());
121     int dataType = TYPE_BYTES;
122     int streamType = -1;
123     if (localSessionName != CTRL_SESSION_NAME) {
124         dataType = TYPE_STREAM;
125         streamType = RAW_STREAM;
126     }
127 
128     SessionAttribute attr = { 0 };
129     attr.dataType = dataType;
130     attr.linkTypeNum = LINK_TYPE_MAX;
131     LinkType linkTypeList[LINK_TYPE_MAX] = {
132         LINK_TYPE_WIFI_P2P,
133         LINK_TYPE_WIFI_WLAN_5G,
134         LINK_TYPE_WIFI_WLAN_2G,
135         LINK_TYPE_BR,
136     };
137     if (memcpy_s(attr.linkType, sizeof(attr.linkType), linkTypeList, sizeof(linkTypeList)) != EOK) {
138         DHLOGE("Softbus open session params copy failed.");
139         return ERR_DH_AUDIO_FAILED;
140     }
141     attr.attr.streamAttr.streamType = streamType;
142     int32_t sessionId = OpenSession(localSessionName.c_str(), peerSessionName.c_str(), peerDevId.c_str(), "0", &attr);
143     if (sessionId < 0) {
144         DHLOGE("Open softbus session failed sessionId: %d.", sessionId);
145         return ERR_DH_AUDIO_ADAPTER_OPEN_SESSION_FAIL;
146     }
147     DHLOGI("Open softbus session success.");
148     return sessionId;
149 }
150 
CloseSoftbusSession(int32_t sessionId)151 int32_t SoftbusAdapter::CloseSoftbusSession(int32_t sessionId)
152 {
153     DHLOGI("Close softbus session: %d.", sessionId);
154     CloseSession(sessionId);
155     std::lock_guard<std::mutex> LisLock(listenerMtx_);
156     mapListenersI_.erase(sessionId);
157     StopSendDataThread();
158     DHLOGI("Close softbus session success.");
159     return DH_SUCCESS;
160 }
161 
SendSoftbusBytes(int32_t sessionId,const void * data,int32_t dataLen)162 int32_t SoftbusAdapter::SendSoftbusBytes(int32_t sessionId, const void *data, int32_t dataLen)
163 {
164     DHLOGI("Send audio event, sessionId: %d.", sessionId);
165     int32_t ret = SendBytes(sessionId, data, dataLen);
166     if (ret != SOFTBUS_OK) {
167         DHLOGE("Send bytes failed, ret:%d.", ret);
168         return ERR_DH_AUDIO_TRANS_ERROR;
169     }
170     return DH_SUCCESS;
171 }
172 
SendSoftbusStream(int32_t sessionId,const std::shared_ptr<AudioData> & audioData)173 int32_t SoftbusAdapter::SendSoftbusStream(int32_t sessionId, const std::shared_ptr<AudioData> &audioData)
174 {
175     DHLOGI("Send audio data, sessionId: %d.", sessionId);
176     if (audioData == nullptr) {
177         DHLOGE("Audio data is null.");
178         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
179     }
180     std::lock_guard<std::mutex> lck(dataQueueMtx_);
181     while (audioDataQueue_.size() >= DATA_QUEUE_MAX_SIZE) {
182         DHLOGE("Softbus data queue overflow. data queue size: %d", audioDataQueue_.size());
183         audioDataQueue_.pop();
184     }
185     auto data = std::make_shared<SoftbusStreamData>(audioData, sessionId);
186     audioDataQueue_.push(data);
187     sendDataCond_.notify_all();
188     return DH_SUCCESS;
189 }
190 
RegisterSoftbusListener(const std::shared_ptr<ISoftbusListener> & listener,const std::string & sessionName,const std::string & peerDevId)191 int32_t SoftbusAdapter::RegisterSoftbusListener(const std::shared_ptr<ISoftbusListener> &listener,
192     const std::string &sessionName, const std::string &peerDevId)
193 {
194     DHLOGI("Register listener sess: %s peerDevId: %s.", sessionName.c_str(), GetAnonyString(peerDevId).c_str());
195     std::string strListenerKey = sessionName + "_" + peerDevId;
196     std::lock_guard<std::mutex> lisLock(listenerMtx_);
197     if (mapListenersN_.find(strListenerKey) != mapListenersN_.end()) {
198         DHLOGD("Session listener already register.");
199         return DH_SUCCESS;
200     }
201     mapListenersN_.insert(std::make_pair(strListenerKey, listener));
202     return DH_SUCCESS;
203 }
204 
UnRegisterSoftbusListener(const std::string & sessionName,const std::string & peerDevId)205 int32_t SoftbusAdapter::UnRegisterSoftbusListener(const std::string &sessionName, const std::string &peerDevId)
206 {
207     DHLOGI("Unregister listener sess: %s peerDevId: %s.", sessionName.c_str(), GetAnonyString(peerDevId).c_str());
208     std::string strListenerKey = sessionName + "_" + peerDevId;
209     std::lock_guard<std::mutex> lisLock(listenerMtx_);
210     mapListenersN_.erase(strListenerKey);
211     return DH_SUCCESS;
212 }
213 
OnSoftbusSessionOpened(int32_t sessionId,int32_t result)214 int32_t SoftbusAdapter::OnSoftbusSessionOpened(int32_t sessionId, int32_t result)
215 {
216     DHLOGI("On session opened, sessionId: %d, result: %d.", sessionId, result);
217     if (result != SOFTBUS_OK) {
218         DHLOGE("Session open failed.");
219         return ERR_DH_AUDIO_ADAPTER_OPEN_SESSION_FAIL;
220     }
221     auto &listener = GetSoftbusListenerByName(sessionId);
222     if (!listener) {
223         DHLOGE("Get softbus listener failed.");
224         return ERR_DH_AUDIO_TRANS_ERROR;
225     }
226 
227     std::lock_guard<std::mutex> lisLock(listenerMtx_);
228     if (mapListenersI_.empty()) {
229         DHLOGD("Start softbus send thread.");
230         isSessionOpened_.store(true);
231         sendDataThread_ = std::thread(&SoftbusAdapter::SendAudioData, this);
232         if (pthread_setname_np(sendDataThread_.native_handle(), SENDDATA_THREAD) != DH_SUCCESS) {
233             DHLOGE("Send data thread setname failed.");
234         }
235     }
236     mapListenersI_.insert(std::make_pair(sessionId, listener));
237     listener->OnSessionOpened(sessionId, result);
238     return DH_SUCCESS;
239 }
240 
OnSoftbusSessionClosed(int32_t sessionId)241 void SoftbusAdapter::OnSoftbusSessionClosed(int32_t sessionId)
242 {
243     DHLOGI("On session closed, sessionId: %d.", sessionId);
244     auto &listener = GetSoftbusListenerById(sessionId);
245     if (!listener) {
246         DHLOGE("Get softbus listener failed.");
247         return;
248     }
249     listener->OnSessionClosed(sessionId);
250 
251     std::lock_guard<std::mutex> lisLock(listenerMtx_);
252     mapListenersI_.erase(sessionId);
253     StopSendDataThread();
254 }
255 
OnBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)256 void SoftbusAdapter::OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
257 {
258     DHLOGI("On audio event received from session: %d.", sessionId);
259     if (data == nullptr) {
260         DHLOGE("Bytes data is null.");
261         return;
262     } else if (dataLen == 0 || dataLen > DAUDIO_MAX_RECV_DATA_LEN) {
263         DHLOGE("Stream data length is illegal, dataLen: %d.", dataLen);
264         return;
265     }
266 
267     auto &listener = GetSoftbusListenerById(sessionId);
268     if (listener == nullptr) {
269         DHLOGE("Get softbus listener failed.");
270         return;
271     }
272     listener->OnBytesReceived(sessionId, data, dataLen);
273 }
274 
OnStreamReceived(int32_t sessionId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * streamFrameInfo)275 void SoftbusAdapter::OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext,
276     const StreamFrameInfo *streamFrameInfo)
277 {
278     DHLOGI("On audio data received from session: %d.", sessionId);
279     if (data == nullptr) {
280         DHLOGE("Stream data is null.");
281         return;
282     } else if (data->bufLen <= 0 || (uint32_t)(data->bufLen) > DAUDIO_MAX_RECV_DATA_LEN) {
283         DHLOGE("Stream data length is illegal, dataLen: %d.", data->bufLen);
284         return;
285     }
286 
287     auto &listener = GetSoftbusListenerById(sessionId);
288     if (!listener) {
289         DHLOGE("Get softbus listener failed.");
290         return;
291     }
292     listener->OnStreamReceived(sessionId, data, ext, streamFrameInfo);
293 }
294 
OnMessageReceived(int sessionId,const void * data,unsigned int dataLen)295 void SoftbusAdapter::OnMessageReceived(int sessionId, const void *data, unsigned int dataLen)
296 {
297     DHLOGD("On message received, sessionId: %d.", sessionId);
298 }
299 
OnQosEvent(int sessionId,int eventId,int tvCount,const QosTv * tvList)300 void SoftbusAdapter::OnQosEvent(int sessionId, int eventId, int tvCount, const QosTv *tvList)
301 {
302     DHLOGD("On qos event received, sessionId: %d.", sessionId);
303 }
304 
GetSoftbusListenerByName(int32_t sessionId)305 std::shared_ptr<ISoftbusListener> &SoftbusAdapter::GetSoftbusListenerByName(int32_t sessionId)
306 {
307     char sessionName[DAUDIO_MAX_SESSION_NAME_LEN] = "";
308     char peerDevId[DAUDIO_MAX_DEVICE_ID_LEN] = "";
309     int32_t ret = GetPeerSessionName(sessionId, sessionName, sizeof(sessionName));
310     if (ret != SOFTBUS_OK) {
311         DHLOGE("Get peer session name failed ret: %d.", ret);
312         return nullListener_;
313     }
314     ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId));
315     if (ret != SOFTBUS_OK) {
316         DHLOGE("Get peer deviceId failed ret: %d.", ret);
317         return nullListener_;
318     }
319     std::string sessionNameStr(sessionName);
320     std::string peerDevIdStr(peerDevId);
321     std::string strListenerKey = sessionNameStr + "_" + peerDevIdStr;
322 
323     DHLOGI("Get listener sess: %s, peerDevId: %s.", sessionNameStr.c_str(), GetAnonyString(peerDevIdStr).c_str());
324     std::lock_guard<std::mutex> lisLock(listenerMtx_);
325     if (mapListenersN_.find(strListenerKey) == mapListenersN_.end()) {
326         DHLOGE("Find listener failed.");
327         return nullListener_;
328     }
329     return mapListenersN_[strListenerKey];
330 }
331 
GetSoftbusListenerById(int32_t sessionId)332 std::shared_ptr<ISoftbusListener> &SoftbusAdapter::GetSoftbusListenerById(int32_t sessionId)
333 {
334     std::lock_guard<std::mutex> lisLock(listenerMtx_);
335     if (mapListenersI_.find(sessionId) == mapListenersI_.end()) {
336         DHLOGE("Find listener failed.");
337         return nullListener_;
338     }
339     return mapListenersI_[sessionId];
340 }
341 
SendAudioData()342 void SoftbusAdapter::SendAudioData()
343 {
344     constexpr uint8_t DATA_WAIT_TIME = 20;
345     while (isSessionOpened_.load()) {
346         std::shared_ptr<SoftbusStreamData> audioData;
347         {
348             std::unique_lock<std::mutex> lock(dataQueueMtx_);
349             sendDataCond_.wait_for(lock, std::chrono::milliseconds(DATA_WAIT_TIME),
350                 [this]() { return !audioDataQueue_.empty(); });
351             if (audioDataQueue_.empty()) {
352                 continue;
353             }
354             audioData = audioDataQueue_.front();
355             audioDataQueue_.pop();
356         }
357         if (audioData == nullptr || audioData->data_ == nullptr) {
358             DHLOGE("Audio data is null.");
359             continue;
360         }
361 
362         StreamData data = { reinterpret_cast<char *>(audioData->data_->Data()), audioData->data_->Capacity() };
363         StreamData ext;
364         StreamFrameInfo frameInfo;
365         DHLOGI("Send audio data, sessionId: %d.", audioData->sessionId_);
366         int32_t ret = SendStream(audioData->sessionId_, &data, &ext, &frameInfo);
367         if (ret != SOFTBUS_OK) {
368             DHLOGE("Send data failed. ret: %d.", ret);
369         } else {
370             DHLOGI("Send audio data successs.");
371         }
372     }
373 }
374 
StopSendDataThread()375 void SoftbusAdapter::StopSendDataThread()
376 {
377     if (mapListenersI_.empty()) {
378         DHLOGI("Stop softbus send thread.");
379         isSessionOpened_.store(false);
380         if (sendDataThread_.joinable()) {
381             sendDataThread_.join();
382         }
383     }
384 }
385 } // namespace DistributedHardware
386 } // namespace OHOS