1 /*
2 * Copyright (c) 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 * Description: channel manager
15 * Author: sunhong
16 * Create: 2022-01-19
17 */
18
19 #include "channel_manager.h"
20 #include "cast_engine_log.h"
21 #include "softbus/softbus_connection.h"
22 #include "tcp/tcp_connection.h"
23
24 namespace OHOS {
25 namespace CastEngine {
26 namespace CastEngineService {
27 DEFINE_CAST_ENGINE_LABEL("CastEngine-ChannelManager");
28
ChannelManager(const int sessionIndex,std::shared_ptr<IChannelManagerListener> channelManagerListener)29 ChannelManager::ChannelManager(const int sessionIndex, std::shared_ptr<IChannelManagerListener> channelManagerListener)
30 : sessionIndex_(sessionIndex), channelManagerListener_(channelManagerListener)
31 {
32 CLOGD("In, sessionId_ = %{public}d, sessionIndex_ = %{public}d.", sessionId_, sessionIndex_);
33 connectionListener_ = std::make_shared<ConnectionListenerInner>(channelManagerListener_);
34 }
35
~ChannelManager()36 ChannelManager::~ChannelManager()
37 {
38 DestroyAllChannels();
39 };
40
GetConnection(ChannelLinkType linkType)41 std::shared_ptr<Connection> ChannelManager::GetConnection(ChannelLinkType linkType)
42 {
43 std::shared_ptr<Connection> connection;
44 switch (linkType) {
45 case ChannelLinkType::SOFT_BUS:
46 connection = std::make_shared<SoftBusConnection>();
47 CLOGD("GetConnection, Create SoftBus Connection, linkType = %{public}d.", linkType);
48 break;
49 case ChannelLinkType::VTP:
50 case ChannelLinkType::TCP:
51 connection = std::make_shared<TcpConnection>();
52 CLOGD("GetConnection, Create Tcp Connection, linkType = %{public}d.", linkType);
53 break;
54 default:
55 CLOGE("Invalid linkType, linkType = %{public}d.", linkType);
56 break;
57 }
58 return connection;
59 }
60
61 /*
62 * server (start listen) or client (start connection)
63 *
64 * ----------------------------------
65 * | VTP | TCP | SoftBus
66 * ----------------------------------
67 * sink | server| client| client
68 * ----------------------------------
69 * source| client| server| server
70 * ----------------------------------
71 */
CreateChannel(ChannelRequest & request,std::shared_ptr<IChannelListener> channelListener)72 int ChannelManager::CreateChannel(ChannelRequest &request, std::shared_ptr<IChannelListener> channelListener)
73 {
74 CLOGD("CreateChannel Enter.");
75 if (channelListener == nullptr || !IsRequestValid(request)) {
76 CLOGE("CreateChannel, channelListener is null or request is invalid.");
77 return RET_ERR;
78 }
79
80 request.connectionId = ++connectionNum_;
81 std::shared_ptr<Connection> connection = GetConnection(request.linkType);
82 connection->SetConnectionListener(connectionListener_);
83
84 {
85 std::lock_guard<std::mutex> lg(connectionMapMtx_);
86 connectionMap_.insert(std::pair<ChannelRequest, std::shared_ptr<Connection>>(request, connection));
87 }
88
89 bool isVtp = (request.linkType == ChannelLinkType::VTP);
90 bool isSink = (request.sessionProperty.endType == EndType::CAST_SINK);
91 CLOGI("CreateChannel In, linkType = %{public}d, isVtp = %{public}d, isSink = %{public}d.", request.linkType,
92 isVtp, isSink);
93 if ((isVtp && isSink) || (!isVtp && !isSink)) {
94 CLOGV("CreateChannel In, StartListen.");
95 return connection->StartListen(request, channelListener);
96 } else {
97 CLOGV("CreateChannel In, StartConnection.");
98 return connection->StartConnection(request, channelListener);
99 }
100 }
101
CreateChannel(ChannelRequest & request,std::shared_ptr<IChannelListener> channelListener,ChannelFileSchema & fileSchema)102 int ChannelManager::CreateChannel(ChannelRequest &request, std::shared_ptr<IChannelListener> channelListener,
103 ChannelFileSchema &fileSchema)
104 {
105 CLOGD("CreateChannel Enter.");
106 if (channelListener == nullptr || !IsRequestValid(request)) {
107 CLOGE("CreateChannel, channelListener is null or request is invalid.");
108 return RET_ERR;
109 }
110
111 request.connectionId = ++connectionNum_;
112 std::shared_ptr<Connection> connection = GetConnection(request.linkType);
113 connection->SetConnectionListener(connectionListener_);
114
115 {
116 std::lock_guard<std::mutex> lg(connectionMapMtx_);
117 connectionMap_.insert(std::pair<ChannelRequest, std::shared_ptr<Connection>>(request, connection));
118 }
119
120 bool isVtp = (request.linkType == ChannelLinkType::VTP);
121 bool isSink = (request.sessionProperty.endType == EndType::CAST_SINK);
122 CLOGI("CreateChannel In, linkType = %{public}d, isVtp = %{public}d, isSink = %{public}d.", request.linkType,
123 isVtp, isSink);
124 if ((isVtp && isSink) || (!isVtp && !isSink)) {
125 CLOGV("CreateChannel In, StartConnection.");
126 int remotectrlPort = connection->StartConnection(request, channelListener);
127 return remotectrlPort;
128 } else {
129 CLOGV("CreateChannel In, StartListen.");
130 return connection->StartListen(request, channelListener);
131 }
132 }
133
IsRequestValid(const ChannelRequest & request) const134 bool ChannelManager::IsRequestValid(const ChannelRequest &request) const
135 {
136 if (request.linkType != ChannelLinkType::SOFT_BUS && request.remoteDeviceInfo.ipAddress.empty()) {
137 CLOGE("linkType is not SoftBus and remoteIp is empty, linkType = %{public}d.", request.linkType);
138 return false;
139 }
140 CLOGD("IsRequestValid In, remoteIp = %{public}s.", request.remoteDeviceInfo.ipAddress.c_str());
141 if (request.linkType == ChannelLinkType::SOFT_BUS && request.remoteDeviceInfo.deviceId.empty()) {
142 CLOGE("linkType is SoftBus and remoteDeviceId is empty.");
143 return false;
144 }
145 CLOGD("IsRequestValid In, remoteDeviceId = %{public}s.", request.remoteDeviceInfo.deviceId.c_str());
146 return true;
147 }
148
DestroyChannel(const Channel & channel)149 bool ChannelManager::DestroyChannel(const Channel &channel)
150 {
151 CLOGD("DestroyChannel Enter, Specify specific channel.");
152
153 std::lock_guard<std::mutex> lg(connectionMapMtx_);
154 auto it = connectionMap_.find(channel.GetRequest());
155 if (it != connectionMap_.end()) {
156 std::shared_ptr<Connection> connection = it->second;
157 connection->CloseConnection();
158 connectionMap_.erase(it);
159 return true;
160 } else {
161 CLOGE("DestroyChannel, Can't find Channel.");
162 return false;
163 }
164 }
165
DestroyChannel(ModuleType moduleType)166 bool ChannelManager::DestroyChannel(ModuleType moduleType)
167 {
168 CLOGD("DestroyChannel Enter, Specify specific channel type.");
169
170 std::lock_guard<std::mutex> lg(connectionMapMtx_);
171
172 for (auto it = connectionMap_.begin(); it != connectionMap_.end();) {
173 if (it->first.moduleType == moduleType) {
174 it->second->CloseConnection();
175 connectionMap_.erase(it);
176 return true;
177 } else {
178 it++;
179 }
180 }
181 return false;
182 }
183
DestroyAllChannels()184 void ChannelManager::DestroyAllChannels()
185 {
186 CLOGD("DestroyAllChannels Enter.");
187
188 std::lock_guard<std::mutex> lg(connectionMapMtx_);
189
190 for (auto it = connectionMap_.begin(); it != connectionMap_.end();) {
191 it->second->CloseConnection();
192 connectionMap_.erase(it++);
193 }
194 }
195
IsAllChannelOpened() const196 bool ChannelManager::IsAllChannelOpened() const
197 {
198 return true;
199 }
200 } // namespace CastEngineService
201 } // namespace CastEngine
202 } // namespace OHOS