1 /*
2 * Copyright (C) 2021 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 "socket_service.h"
17 #include "class_creator.h"
18 #include "log.h"
19 #include "socket_listener.h"
20
21 namespace OHOS {
22 namespace bluetooth {
23 const std::string SPP_VERSION = "0.4.1";
24
SocketService()25 SocketService::SocketService() : utility::Context(PROFILE_NAME_SPP, SPP_VERSION)
26 {
27 LOG_INFO("ProfileService:%{public}s Create", Name().c_str());
28 }
29
~SocketService()30 SocketService::~SocketService()
31 {
32 LOG_INFO("ProfileService:%{public}s Destroy", Name().c_str());
33 }
34
GetContext()35 utility::Context *SocketService::GetContext()
36 {
37 return this;
38 }
39
Enable()40 void SocketService::Enable()
41 {
42 LOG_INFO("[SocketService] %{public}s", __func__);
43
44 SocketThread::GetInstance().Initialize();
45 GetDispatcher()->PostTask(std::bind(&SocketService::EnableNative, this));
46 }
47
EnableNative()48 void SocketService::EnableNative()
49 {
50 LOG_INFO("[SocketService] %{public}s", __func__);
51
52 GetContext()->OnEnable(PROFILE_NAME_SPP, true);
53 }
54
Disable()55 void SocketService::Disable()
56 {
57 LOG_INFO("[SocketService] %{public}s", __func__);
58
59 SocketThread::GetInstance().Uninitialize();
60 GetDispatcher()->PostTask(std::bind(&SocketService::DisableNative, this));
61 }
62
DisableNative()63 void SocketService::DisableNative()
64 {
65 LOG_INFO("[SocketService] %{public}s", __func__);
66
67 ShutDownInternal();
68 }
69
Connect(const RawAddress & device)70 int SocketService::Connect(const RawAddress &device)
71 {
72 (void)device;
73 return 0;
74 }
75
Disconnect(const RawAddress & device)76 int SocketService::Disconnect(const RawAddress &device)
77 {
78 (void)device;
79 return 0;
80 }
81
GetConnectDevices()82 std::list<RawAddress> SocketService::GetConnectDevices()
83 {
84 std::list<RawAddress> devList;
85
86 return devList;
87 }
88
GetConnectState()89 int SocketService::GetConnectState()
90 {
91 return 0;
92 }
93
GetMaxConnectNum()94 int SocketService::GetMaxConnectNum()
95 {
96 return 0;
97 }
98
Connect(const std::string & addr,const Uuid & uuid,int securityFlag,int type)99 int SocketService::Connect(const std::string &addr, const Uuid &uuid, int securityFlag, int type)
100 {
101 LOG_INFO("[SocketService]%{public}s", __func__);
102
103 int socketFd = SOCK_INVALID_FD;
104 auto socket = std::make_unique<Socket>();
105 if (socket->Connect(addr, uuid, securityFlag, socketFd) < 0) {
106 socketFd = SOCK_INVALID_FD;
107 }
108
109 {
110 std::lock_guard<std::mutex> lock(mutex_);
111 clientSockets_.push_back(std::move(socket));
112 isClientPush_ = true;
113 }
114
115 return socketFd;
116 }
117
Listen(const std::string & name,const Uuid & uuid,int securityFlag,int type)118 int SocketService::Listen(const std::string &name, const Uuid &uuid, int securityFlag, int type)
119 {
120 LOG_INFO("[SocketService]%{public}s", __func__);
121
122 int socketFd = SOCK_INVALID_FD;
123 auto socket = std::make_unique<Socket>();
124 if (socket->Listen(name, uuid, securityFlag, socketFd) < 0) {
125 socketFd = SOCK_INVALID_FD;
126 }
127
128 {
129 std::lock_guard<std::mutex> lock(mutex_);
130 serverSockets_.push_back(std::move(socket));
131 }
132
133 return socketFd;
134 }
135
ShutDownInternal()136 void SocketService::ShutDownInternal()
137 {
138 LOG_INFO("[SocketService]%{public}s", __func__);
139
140 isShutdown_ = true;
141 if (clientSockets_.empty() && acceptSockets_.empty()) {
142 if (!serverSockets_.empty()) {
143 CleanupServerSocket();
144 }
145 LOG_INFO("[SocketService]%{public}s shutdown end", __func__);
146 Socket::ClearUpAllSocket();
147 GetContext()->OnDisable(PROFILE_NAME_SPP, true);
148 isShutdown_ = false;
149 return;
150 }
151 if (!clientSockets_.empty()) {
152 LOG_INFO("[SocketService]%{public}s close client socket start", __func__);
153 auto cIt = clientSockets_.begin();
154 while (cIt != clientSockets_.end()) {
155 uint16_t totalClient = clientSockets_.size();
156 (*cIt)->CloseSocket(false);
157 if (clientSockets_.size() < totalClient) {
158 continue;
159 }
160 cIt++;
161 }
162 }
163
164 if (!acceptSockets_.empty()) {
165 LOG_INFO("[SocketService]%{public}s close accpet socket start", __func__);
166 auto aIt = acceptSockets_.begin();
167 while (aIt != acceptSockets_.end()) {
168 uint16_t totalAccept = acceptSockets_.size();
169 (*aIt)->CloseSocket(false);
170 if (acceptSockets_.size() < totalAccept) {
171 continue;
172 }
173 aIt++;
174 }
175 }
176 }
177
ProcessMessage(const utility::Message & msg)178 void SocketService::ProcessMessage(const utility::Message &msg)
179 {
180 Socket *socket = static_cast<Socket *>(msg.arg2_);
181 std::lock_guard<std::mutex> lock(mutex_);
182 switch (msg.what_) {
183 case SOCKET_SDP_DISCOVERY_RESULT:
184 if (clientSockets_.empty() && isClientPush_) {
185 isClientPush_ = false;
186 break;
187 }
188 if ((msg.arg1_ <= 0) || (msg.arg1_ > SOCK_MAX_SERVER)) {
189 LOG_ERROR("[SocketService]%{public}s scn invalid", __func__);
190 SocketThread::GetInstance().DeleteSocket(*socket);
191 socket->CloseSocketFd();
192 break;
193 }
194 socket->ReceiveSdpResult(msg.arg1_);
195 break;
196 case SOCKET_ACCEPT_NEW:
197 LOG_INFO("[SocketService]%{public}s SOCKET_ACCEPT_NEW", __func__);
198 acceptSockets_.push_back(socket);
199 break;
200 case SOCKET_CLOSE:
201 LOG_INFO("[SocketService]%{public}s SOCKET_CLOSE", __func__);
202 CleanupClientSocket(socket);
203 break;
204 default:
205 break;
206 }
207 }
208
CleanupServerSocket()209 void SocketService::CleanupServerSocket()
210 {
211 LOG_INFO("[SocketService]%{public}s close server socket end", __func__);
212
213 for (auto &it : serverSockets_) {
214 it->RemoveServerSocket();
215 }
216
217 serverSockets_.clear();
218 }
219
CleanupClientSocket(Socket * socket)220 void SocketService::CleanupClientSocket(Socket *socket)
221 {
222 LOG_INFO("[SocketService]%{public}s", __func__);
223
224 std::vector<std::unique_ptr<Socket>>::iterator clientIt;
225 for (clientIt = clientSockets_.begin(); clientIt != clientSockets_.end(); ++clientIt) {
226 if (clientIt->get() == socket) {
227 LOG_INFO("[SocketService]%{public}s close client socket end", __func__);
228 clientSockets_.erase(clientIt);
229 break;
230 }
231 }
232
233 std::vector<Socket *>::iterator acceptIt;
234 for (acceptIt = acceptSockets_.begin(); acceptIt != acceptSockets_.end(); ++acceptIt) {
235 if (*acceptIt == socket) {
236 LOG_INFO("[SocketService]%{public}s close accept socket end", __func__);
237 acceptSockets_.erase(acceptIt);
238 break;
239 }
240 }
241
242 if (clientSockets_.empty()) {
243 isClientPush_ = false;
244 }
245
246 if (isShutdown_) {
247 if (clientSockets_.empty() && acceptSockets_.empty()) {
248 LOG_INFO("[SocketService]%{public}s shutdown end", __func__);
249 CleanupServerSocket();
250 Socket::ClearUpAllSocket();
251 GetContext()->OnDisable(PROFILE_NAME_SPP, true);
252 isShutdown_ = false;
253 }
254 }
255 }
256 REGISTER_CLASS_CREATOR(SocketService);
257 } // namespace bluetooth
258 } // namespace OHOS