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