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