• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "av_trans_control_center.h"
17 
18 #include "anonymous_string.h"
19 #include "av_trans_log.h"
20 
21 namespace OHOS {
22 namespace DistributedHardware {
23 #undef DH_LOG_TAG
24 #define DH_LOG_TAG "AVTransControlCenter"
25 
26 IMPLEMENT_SINGLE_INSTANCE(AVTransControlCenter);
27 
AVTransControlCenter()28 AVTransControlCenter::AVTransControlCenter()
29 {
30     AVTRANS_LOGI("AVTransControlCenter ctor.");
31     transRole_ = TransRole::UNKNOWN;
32     rootEngineId_.store(BASE_ENGINE_ID);
33     syncManager_ = std::make_shared<AVSyncManager>();
34 }
35 
~AVTransControlCenter()36 AVTransControlCenter::~AVTransControlCenter()
37 {
38     AVTRANS_LOGI("AVTransControlCenter dtor.");
39     SoftbusChannelAdapter::GetInstance().RemoveChannelServer(PKG_NAME_DH_FWK, AV_SYNC_SENDER_CONTROL_SESSION_NAME);
40     SoftbusChannelAdapter::GetInstance().RemoveChannelServer(PKG_NAME_DH_FWK, AV_SYNC_RECEIVER_CONTROL_SESSION_NAME);
41 
42     sessionName_ = "";
43     initialized_ = false;
44     syncManager_ = nullptr;
45     transRole_ = TransRole::UNKNOWN;
46     rootEngineId_.store(BASE_ENGINE_ID);
47 }
48 
InitializeAVCenter(const TransRole & transRole,int32_t & engineId)49 int32_t AVTransControlCenter::InitializeAVCenter(const TransRole &transRole, int32_t &engineId)
50 {
51     engineId = INVALID_ENGINE_ID;
52     if ((transRole != TransRole::AV_SENDER) && (transRole != TransRole::AV_RECEIVER)) {
53         AVTRANS_LOGE("Invalid trans role=%d", transRole);
54         return ERR_DH_AVT_INVALID_PARAM_VALUE;
55     }
56 
57     if (initialized_.load()) {
58         AVTRANS_LOGI("AV control center already initialized.");
59         engineId = rootEngineId_.load();
60         rootEngineId_++;
61         return DH_AVT_SUCCESS;
62     }
63 
64     int32_t ret = SoftbusChannelAdapter::GetInstance().CreateChannelServer(PKG_NAME_DH_FWK,
65         AV_SYNC_SENDER_CONTROL_SESSION_NAME);
66     TRUE_RETURN_V_MSG_E((ret != DH_AVT_SUCCESS), ret, "Create contro center session server failed, ret=%d", ret);
67 
68     ret = SoftbusChannelAdapter::GetInstance().CreateChannelServer(PKG_NAME_DH_FWK,
69         AV_SYNC_RECEIVER_CONTROL_SESSION_NAME);
70     TRUE_RETURN_V_MSG_E((ret != DH_AVT_SUCCESS), ret, "Create contro center session server failed, ret=%d", ret);
71 
72     ret = SoftbusChannelAdapter::GetInstance().RegisterChannelListener(AV_SYNC_SENDER_CONTROL_SESSION_NAME,
73         AV_TRANS_SPECIAL_DEVICE_ID, this);
74     TRUE_RETURN_V_MSG_E((ret != DH_AVT_SUCCESS), ret, "Register control center channel callback failed, ret=%d", ret);
75 
76     ret = SoftbusChannelAdapter::GetInstance().RegisterChannelListener(AV_SYNC_RECEIVER_CONTROL_SESSION_NAME,
77         AV_TRANS_SPECIAL_DEVICE_ID, this);
78     TRUE_RETURN_V_MSG_E((ret != DH_AVT_SUCCESS), ret, "Register control center channel callback failed, ret=%d", ret);
79 
80     initialized_ = true;
81     transRole_ = transRole;
82     engineId = rootEngineId_.load();
83     rootEngineId_++;
84 
85     return DH_AVT_SUCCESS;
86 }
87 
ReleaseAVCenter(int32_t engineId)88 int32_t AVTransControlCenter::ReleaseAVCenter(int32_t engineId)
89 {
90     AVTRANS_LOGI("Release av control center channel for engineId=%d.", engineId);
91     TRUE_RETURN_V_MSG_E(IsInvalidEngineId(engineId), ERR_DH_AVT_INVALID_PARAM_VALUE,
92         "Invalid input engine id = %d", engineId);
93 
94     {
95         std::lock_guard<std::mutex> lock(callbackMutex_);
96         callbackMap_.erase(engineId);
97     }
98 
99     std::string peerDevId;
100     {
101         std::lock_guard<std::mutex> lock(engineIdMutex_);
102         if (engine2DevIdMap_.find(engineId) == engine2DevIdMap_.end()) {
103             AVTRANS_LOGE("Input engine id is not exist, engineId = %d", engineId);
104             return DH_AVT_SUCCESS;
105         }
106         peerDevId = engine2DevIdMap_[engineId];
107         engine2DevIdMap_.erase(engineId);
108 
109         bool IsDevIdUsedByOthers = false;
110         for (auto it = engine2DevIdMap_.begin(); it != engine2DevIdMap_.end(); it++) {
111             if (it->second == peerDevId) {
112                 IsDevIdUsedByOthers = true;
113                 break;
114             }
115         }
116         if (IsDevIdUsedByOthers) {
117             AVTRANS_LOGI("Control channel is still being used by other engine, peerDevId=%s.",
118                 GetAnonyString(peerDevId).c_str());
119             return DH_AVT_SUCCESS;
120         }
121     }
122 
123     {
124         std::lock_guard<std::mutex> lock(devIdMutex_);
125         auto iter = std::find(connectedDevIds_.begin(), connectedDevIds_.end(), peerDevId);
126         if (iter == connectedDevIds_.end()) {
127             AVTRANS_LOGE("Control channel has not been opened successfully for peerDevId=%s.",
128                 GetAnonyString(peerDevId).c_str());
129             return DH_AVT_SUCCESS;
130         } else {
131             connectedDevIds_.erase(iter);
132         }
133     }
134 
135     SoftbusChannelAdapter::GetInstance().StopDeviceTimeSync(PKG_NAME_DH_FWK, sessionName_, peerDevId);
136     SoftbusChannelAdapter::GetInstance().CloseSoftbusChannel(sessionName_, peerDevId);
137     SoftbusChannelAdapter::GetInstance().UnRegisterChannelListener(AV_SYNC_SENDER_CONTROL_SESSION_NAME,
138         AV_TRANS_SPECIAL_DEVICE_ID);
139     SoftbusChannelAdapter::GetInstance().UnRegisterChannelListener(AV_SYNC_RECEIVER_CONTROL_SESSION_NAME,
140         AV_TRANS_SPECIAL_DEVICE_ID);
141 
142     return DH_AVT_SUCCESS;
143 }
144 
CreateControlChannel(int32_t engineId,const std::string & peerDevId)145 int32_t AVTransControlCenter::CreateControlChannel(int32_t engineId, const std::string &peerDevId)
146 {
147     AVTRANS_LOGI("Create control center channel for engineId=%d, peerDevId=%s.", engineId,
148         GetAnonyString(peerDevId).c_str());
149 
150     TRUE_RETURN_V_MSG_E(IsInvalidEngineId(engineId), ERR_DH_AVT_INVALID_PARAM_VALUE,
151         "Invalid input engine id = %d", engineId);
152 
153     TRUE_RETURN_V_MSG_E(!initialized_.load(), ERR_DH_AVT_CREATE_CHANNEL_FAILED,
154         "AV control center has not been initialized.");
155 
156     {
157         std::lock_guard<std::mutex> devLock(devIdMutex_);
158         auto iter = std::find(connectedDevIds_.begin(), connectedDevIds_.end(), peerDevId);
159         if (iter != connectedDevIds_.end()) {
160             {
161                 std::lock_guard<std::mutex> lock(engineIdMutex_);
162                 engine2DevIdMap_.insert(std::make_pair(engineId, peerDevId));
163             }
164             AVTRANS_LOGE("AV control center channel has already created, peerDevId=%s.",
165                 GetAnonyString(peerDevId).c_str());
166             return ERR_DH_AVT_CHANNEL_ALREADY_CREATED;
167         }
168     }
169 
170     int32_t ret = SoftbusChannelAdapter::GetInstance().OpenSoftbusChannel(AV_SYNC_SENDER_CONTROL_SESSION_NAME,
171         AV_SYNC_RECEIVER_CONTROL_SESSION_NAME, peerDevId);
172     TRUE_RETURN_V_MSG_E(((ret != DH_AVT_SUCCESS) && (ret != ERR_DH_AVT_SESSION_HAS_OPENED)), ret,
173         "Create av control center channel failed, ret=%d", ret);
174 
175     std::lock_guard<std::mutex> lk(engineIdMutex_);
176     engine2DevIdMap_.insert(std::make_pair(engineId, peerDevId));
177 
178     return DH_AVT_SUCCESS;
179 }
180 
NotifyAVCenter(int32_t engineId,const AVTransEvent & event)181 int32_t AVTransControlCenter::NotifyAVCenter(int32_t engineId, const AVTransEvent& event)
182 {
183     TRUE_RETURN_V_MSG_E(IsInvalidEngineId(engineId), ERR_DH_AVT_INVALID_PARAM_VALUE,
184         "Invalid input engine id = %d", engineId);
185 
186     switch (event.type) {
187         case EventType::EVENT_ADD_STREAM: {
188             syncManager_->AddStreamInfo(AVStreamInfo{ event.content, event.peerDevId });
189             break;
190         }
191         case EventType::EVENT_REMOVE_STREAM: {
192             syncManager_->RemoveStreamInfo(AVStreamInfo{ event.content, event.peerDevId });
193             break;
194         }
195         default:
196             AVTRANS_LOGE("Unsupported event type.");
197     }
198     return DH_AVT_SUCCESS;
199 }
200 
RegisterCtlCenterCallback(int32_t engineId,const sptr<IAVTransControlCenterCallback> & callback)201 int32_t AVTransControlCenter::RegisterCtlCenterCallback(int32_t engineId,
202     const sptr<IAVTransControlCenterCallback> &callback)
203 {
204     TRUE_RETURN_V_MSG_E(IsInvalidEngineId(engineId), ERR_DH_AVT_INVALID_PARAM_VALUE,
205         "Invalid input engine id = %d", engineId);
206 
207     if (callback == nullptr) {
208         AVTRANS_LOGE("Input callback is nullptr.");
209         return ERR_DH_AVT_INVALID_PARAM_VALUE;
210     }
211 
212     std::lock_guard<std::mutex> lock(callbackMutex_);
213     callbackMap_.insert(std::make_pair(engineId, callback));
214 
215     return DH_AVT_SUCCESS;
216 }
217 
SendMessage(const std::shared_ptr<AVTransMessage> & message)218 int32_t AVTransControlCenter::SendMessage(const std::shared_ptr<AVTransMessage> &message)
219 {
220     AVTRANS_LOGI("SendMessage enter.");
221     TRUE_RETURN_V_MSG_E(message == nullptr, ERR_DH_AVT_INVALID_PARAM, "Input message is nullptr.");
222 
223     std::string msgData = message->MarshalMessage();
224     return SoftbusChannelAdapter::GetInstance().SendBytesData(sessionName_, message->dstDevId_, msgData);
225 }
226 
SetParam2Engines(AVTransTag tag,const std::string & value)227 void AVTransControlCenter::SetParam2Engines(AVTransTag tag, const std::string &value)
228 {
229     std::lock_guard<std::mutex> lock(callbackMutex_);
230     for (auto iter = callbackMap_.begin(); iter != callbackMap_.end(); iter++) {
231         if (iter->second != nullptr) {
232             iter->second->SetParameter(tag, value);
233         }
234     }
235 }
236 
SetParam2Engines(const AVTransSharedMemory & memory)237 void AVTransControlCenter::SetParam2Engines(const AVTransSharedMemory &memory)
238 {
239     std::lock_guard<std::mutex> lock(callbackMutex_);
240     for (auto iter = callbackMap_.begin(); iter != callbackMap_.end(); iter++) {
241         if (iter->second != nullptr) {
242             iter->second->SetSharedMemory(memory);
243         }
244     }
245 }
246 
OnChannelEvent(const AVTransEvent & event)247 void AVTransControlCenter::OnChannelEvent(const AVTransEvent &event)
248 {
249     AVTRANS_LOGI("OnChannelEvent enter. event type:%d", event.type);
250     switch (event.type) {
251         case EventType::EVENT_CHANNEL_OPENED:
252         case EventType::EVENT_CHANNEL_CLOSED:
253         case EventType::EVENT_CHANNEL_OPEN_FAIL: {
254             HandleChannelEvent(event);
255             break;
256         }
257         case EventType::EVENT_DATA_RECEIVED: {
258             HandleDataReceived(event.content, event.peerDevId);
259             break;
260         }
261         case EventType::EVENT_TIME_SYNC_RESULT: {
262             SetParam2Engines(AVTransTag::TIME_SYNC_RESULT, event.content);
263             break;
264         }
265         default:
266             AVTRANS_LOGE("Unsupported event type.");
267     }
268 }
269 
HandleChannelEvent(const AVTransEvent & event)270 void AVTransControlCenter::HandleChannelEvent(const AVTransEvent &event)
271 {
272     if (event.type == EventType::EVENT_CHANNEL_CLOSED) {
273         AVTRANS_LOGI("Control channel has been closed.");
274         return;
275     }
276 
277     if (event.type == EventType::EVENT_CHANNEL_OPEN_FAIL) {
278         AVTRANS_LOGE("Open control channel failed for peerDevId=%s.", GetAnonyString(event.peerDevId).c_str());
279         return;
280     }
281 
282     if (event.type == EventType::EVENT_CHANNEL_OPENED) {
283         sessionName_ = event.content;
284         if (sessionName_ == AV_SYNC_RECEIVER_CONTROL_SESSION_NAME) {
285             SoftbusChannelAdapter::GetInstance().StartDeviceTimeSync(PKG_NAME_DH_FWK, sessionName_, event.peerDevId);
286         }
287         std::lock_guard<std::mutex> lock(devIdMutex_);
288         connectedDevIds_.push_back(event.peerDevId);
289     }
290 }
291 
HandleDataReceived(const std::string & content,const std::string & peerDevId)292 void AVTransControlCenter::HandleDataReceived(const std::string &content, const std::string &peerDevId)
293 {
294     auto avMessage = std::make_shared<AVTransMessage>();
295     if (!avMessage->UnmarshalMessage(content, peerDevId)) {
296         AVTRANS_LOGE("unmarshal event content to av message failed");
297         return;
298     }
299     AVTRANS_LOGI("Handle data received, av message type = %d", avMessage->type_);
300     if ((avMessage->type_ == (uint32_t)AVTransTag::START_AV_SYNC) ||
301         (avMessage->type_ == (uint32_t)AVTransTag::STOP_AV_SYNC)) {
302         syncManager_->HandleAvSyncMessage(avMessage);
303     }
304 }
305 
OnStreamReceived(const StreamData * data,const StreamData * ext)306 void AVTransControlCenter::OnStreamReceived(const StreamData *data, const StreamData *ext)
307 {
308     (void)data;
309     (void)ext;
310 }
311 
IsInvalidEngineId(int32_t engineId)312 bool AVTransControlCenter::IsInvalidEngineId(int32_t engineId)
313 {
314     return (engineId < BASE_ENGINE_ID) || (engineId > rootEngineId_.load());
315 }
316 }
317 }