• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 <sys/socket.h>
17 #include <string>
18 #include <unistd.h>
19 #include "bluetooth_log.h"
20 #include "bluetooth_host.h"
21 #include "bluetooth_host_proxy.h"
22 #include "bluetooth_utils.h"
23 #include "bluetooth_socket_proxy.h"
24 #include "hisysevent.h"
25 #include "ipc_skeleton.h"
26 #include "iservice_registry.h"
27 #include "securec.h"
28 #include "system_ability_definition.h"
29 #include "raw_address.h"
30 #include "bluetooth_socket.h"
31 
32 namespace OHOS {
33 namespace Bluetooth {
34 const int LENGTH = 18;
35 const int MIN_BUFFER_SIZE_TO_SET = 4 * 1024; // 4KB
36 const int MAX_BUFFER_SIZE_TO_SET = 50 * 1024; // 50KB
37 const int PSM_BUFFER_SIZE = 4;
38 struct ClientSocket::impl {
39     impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth);
40     impl(int fd, std::string address, BtSocketType type);
~implOHOS::Bluetooth::ClientSocket::impl41     ~impl()
42     {
43         if (proxy_ != nullptr && proxy_->AsObject() != nullptr) {
44             proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
45         } else {
46             HILOGI("failed: no proxy_");
47         }
48 
49         if (fd_ > 0) {
50             shutdown(fd_, SHUT_RD);
51             shutdown(fd_, SHUT_WR);
52             HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
53                 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty",
54                 "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
55             HILOGI("fd closed, fd_: %{pubilc}d", fd_);
56             close(fd_);
57             fd_ = -1;
58         }
59     }
60 
CloseOHOS::Bluetooth::ClientSocket::impl61     void Close()
62     {
63         HILOGI("starts");
64         if (socketStatus_ == SOCKET_CLOSED) {
65             HILOGW("The socketStatus_ is already SOCKET_CLOSED");
66             return;
67         } else {
68             socketStatus_ = SOCKET_CLOSED;
69             if (fd_ > 0) {
70                 shutdown(fd_, SHUT_RD);
71                 shutdown(fd_, SHUT_WR);
72                 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
73                     HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty",
74                     "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
75                 HILOGI("fd closed, fd_: %{pubilc}d", fd_);
76                 close(fd_);
77                 fd_ = -1;
78             } else {
79                 HILOGE("socket not created");
80                 return;
81             }
82         }
83     }
84 
RecvSocketSignalOHOS::Bluetooth::ClientSocket::impl85     bool RecvSocketSignal()
86     {
87         uint8_t recvStateBuf[1];
88 #ifdef DARWIN_PLATFORM
89         int recvBufSize = recv(fd_, recvStateBuf, sizeof(recvStateBuf), 0);
90 #else
91         int recvBufSize = recv(fd_, recvStateBuf, sizeof(recvStateBuf), MSG_WAITALL);
92 #endif
93         if (recvBufSize <= 0) {
94             HILOGE("service closed");
95             return false;
96         }
97         bool state = recvStateBuf[0];
98 
99         uint8_t buf[6] = {0}; // addr buffer len
100 #ifdef DARWIN_PLATFORM
101         int recvAddrSize = recv(fd_, buf, sizeof(buf), 0);
102 #else
103         int recvAddrSize = recv(fd_, buf, sizeof(buf), MSG_WAITALL);
104 #endif
105         if (recvAddrSize <= 0) {
106             HILOGE("service closed");
107             return false;
108         }
109         char token[LENGTH] = {0};
110         (void)sprintf_s(token, sizeof(token), "%02X:%02X:%02X:%02X:%02X:%02X",
111             buf[0x05], buf[0x04], buf[0x03], buf[0x02], buf[0x01], buf[0x00]);
112         BluetoothRawAddress rawAddr {
113             token
114         };
115         std::string address = rawAddr.GetAddress().c_str();
116         return state;
117     }
118 
getSecurityFlagsOHOS::Bluetooth::ClientSocket::impl119     int getSecurityFlags()
120     {
121         int flags = 0;
122         if (auth_) {
123             flags |= FLAG_AUTH;
124             flags |= FLAG_ENCRYPT;
125         }
126         return flags;
127     }
128 
GetInputStreamOHOS::Bluetooth::ClientSocket::impl129     InputStream &GetInputStream()
130     {
131         HILOGI("starts");
132         if (inputStream_ == nullptr) {
133             HILOGE("inputStream is NULL, failed. please Connect");
134         }
135         return *inputStream_;
136     }
137 
GetOutputStreamOHOS::Bluetooth::ClientSocket::impl138     OutputStream &GetOutputStream()
139     {
140         HILOGI("starts");
141         if (outputStream_ == nullptr) {
142             HILOGE("outputStream is NULL, failed. please Connect");
143         }
144         return *outputStream_;
145     }
146 
GetRemoteDeviceOHOS::Bluetooth::ClientSocket::impl147     BluetoothRemoteDevice &GetRemoteDevice()
148     {
149         HILOGI("starts");
150         return remoteDevice_;
151     }
152 
IsConnectedOHOS::Bluetooth::ClientSocket::impl153     bool IsConnected()
154     {
155         HILOGI("starts");
156         return socketStatus_ == SOCKET_CONNECTED;
157     }
158 
SetBufferSizeOHOS::Bluetooth::ClientSocket::impl159     int SetBufferSize(int bufferSize)
160     {
161         HILOGI("SetBufferSize bufferSize is %{public}d.", bufferSize);
162         if (bufferSize < MIN_BUFFER_SIZE_TO_SET || bufferSize > MAX_BUFFER_SIZE_TO_SET) {
163             HILOGE("SetBufferSize param is invalid.");
164             return RET_BAD_PARAM;
165         }
166 
167         if (fd_ <= 0) {
168             HILOGE("SetBufferSize socket fd invalid.");
169             return RET_BAD_STATUS;
170         }
171 
172         const std::pair<const char*, int> sockOpts[] = {
173             {"recvBuffer", SO_RCVBUF},
174             {"sendBuffer", SO_SNDBUF},
175         };
176         for (auto opt : sockOpts) {
177             int curSize = 0;
178             socklen_t optlen = sizeof(curSize);
179             if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) {
180                 HILOGE("SetBufferSize getsockopt %{public}s failed.", opt.first);
181                 return RET_BAD_STATUS;
182             }
183             HILOGI("SetBufferSize %{public}s before set size is %{public}d.", opt.first, curSize);
184 
185             if (curSize != bufferSize) {
186                 int setSize = bufferSize / 2;
187                 if (setsockopt(fd_, SOL_SOCKET, opt.second, &setSize, sizeof(setSize)) != 0) {
188                     HILOGE("SetBufferSize setsockopt  %{public}s failed.", opt.first);
189                     return RET_BAD_STATUS;
190                 }
191 
192                 curSize = 0;
193                 if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) {
194                     HILOGE("SetBufferSize after getsockopt %{public}s failed.", opt.first);
195                     return RET_BAD_STATUS;
196                 }
197                 HILOGI("SetBufferSize %{public}s after set size is %{public}d.", opt.first, curSize);
198             }
199         }
200 
201         return RET_NO_ERROR;
202     }
203 
204     class BluetoothClientSocketDeathRecipient;
205     sptr<BluetoothClientSocketDeathRecipient> deathRecipient_;
206 
207     sptr<IBluetoothSocket> proxy_;
208     std::unique_ptr<InputStream> inputStream_ {
209         nullptr
210     };
211     std::unique_ptr<OutputStream> outputStream_ {
212         nullptr
213     };
214     BluetoothRemoteDevice remoteDevice_;
215     UUID uuid_;
216     BtSocketType type_;
217     std::string address_;
218     int fd_;
219     bool auth_;
220     int socketStatus_;
221 };
222 
223 class ClientSocket::impl::BluetoothClientSocketDeathRecipient final : public IRemoteObject::DeathRecipient {
224 public:
BluetoothClientSocketDeathRecipient(ClientSocket::impl & host)225     explicit BluetoothClientSocketDeathRecipient(ClientSocket::impl &host) : host_(host) {};
226     ~BluetoothClientSocketDeathRecipient() final = default;
227     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothClientSocketDeathRecipient);
228 
OnRemoteDied(const wptr<IRemoteObject> & remote)229     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
230     {
231         HILOGI("starts");
232         host_.proxy_->AsObject()->RemoveDeathRecipient(host_.deathRecipient_);
233         host_.proxy_ = nullptr;
234     }
235 
236 private:
237     ClientSocket::impl &host_;
238 };
239 
impl(const BluetoothRemoteDevice & addr,UUID uuid,BtSocketType type,bool auth)240 ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth)
241     : inputStream_(nullptr),
242       outputStream_(nullptr),
243       remoteDevice_(addr),
244       uuid_(uuid),
245       type_(type),
246       fd_(-1),
247       auth_(auth),
248       socketStatus_(SOCKET_INIT)
249 {
250     HILOGI("starts");
251     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
252     sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
253 
254     if (!hostRemote) {
255         HILOGI("failed: no hostRemote");
256         return;
257     }
258 
259     sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
260     sptr<IRemoteObject> remote = hostProxy->GetProfile(PROFILE_SOCKET);
261 
262     if (!remote) {
263         HILOGI("failed: no remote");
264         return;
265     }
266     HILOGI("remote obtained");
267 
268     proxy_ = iface_cast<IBluetoothSocket>(remote);
269 
270     deathRecipient_ = new BluetoothClientSocketDeathRecipient(*this);
271 
272     if (!proxy_) {
273         HILOGE("proxy_ is nullptr");
274         return;
275     }
276 
277     proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
278 }
279 
impl(int fd,std::string address,BtSocketType type)280 ClientSocket::impl::impl(int fd, std::string address, BtSocketType type)
281     : inputStream_(std::make_unique<InputStream>(fd)),
282       outputStream_(std::make_unique<OutputStream>(fd)),
283       remoteDevice_(BluetoothRemoteDevice(address, 0)),
284       type_(type),
285       address_(address),
286       fd_(fd),
287       auth_(false),
288       socketStatus_(SOCKET_CONNECTED)
289 {
290     HILOGI("starts");
291     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
292     sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
293 
294     if (!hostRemote) {
295         HILOGI("failed: no hostRemote");
296         return;
297     }
298 
299     sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
300     sptr<IRemoteObject> remote = hostProxy->GetProfile(PROFILE_SOCKET);
301 
302     if (!remote) {
303         HILOGI("failed: no remote");
304         return;
305     }
306     HILOGI("remote obtained");
307 
308     proxy_ = iface_cast<IBluetoothSocket>(remote);
309 
310     deathRecipient_ = new BluetoothClientSocketDeathRecipient(*this);
311 
312     if (!proxy_) {
313         HILOGE("proxy_ is nullptr");
314         return;
315     }
316 
317     proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
318 }
319 
ClientSocket(const BluetoothRemoteDevice & bda,UUID uuid,BtSocketType type,bool auth)320 ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth)
321     : pimpl(new ClientSocket::impl(bda, uuid, type, auth))
322 {}
323 
ClientSocket(int fd,std::string address,BtSocketType type)324 ClientSocket::ClientSocket(int fd, std::string address, BtSocketType type)
325     : pimpl(new ClientSocket::impl(fd, address, type))
326 {}
327 
~ClientSocket()328 ClientSocket::~ClientSocket()
329 {}
330 
Connect(int psm)331 int ClientSocket::Connect(int psm)
332 {
333     HILOGI("starts");
334     if (!IS_BT_ENABLED()) {
335         HILOGI("BR is not TURN_ON");
336         return BT_ERR_INVALID_STATE;
337     }
338 
339     pimpl->address_ = pimpl->remoteDevice_.GetDeviceAddr();
340 
341     std::string tempAddress = pimpl->address_;
342     if (!tempAddress.size()) {
343         return BtStatus::BT_FAILURE;
344     }
345     if (pimpl->socketStatus_ == SOCKET_CLOSED) {
346         HILOGE("socket closed");
347         return BT_ERR_INVALID_STATE;
348     }
349 
350     if (!pimpl->proxy_) {
351         HILOGE("proxy_ is nullptr");
352         return BT_ERR_SERVICE_DISCONNECTED;
353     }
354 
355     ConnectSocketParam param {
356         .addr = tempAddress,
357         .uuid = bluetooth::Uuid::ConvertFrom128Bits(pimpl->uuid_.ConvertTo128Bits()),
358         .securityFlag = (int32_t)pimpl->getSecurityFlags(),
359         .type = (int32_t)pimpl->type_,
360         .psm = psm
361     };
362     int ret = pimpl->proxy_->Connect(param, pimpl->fd_);
363     if (ret != BT_NO_ERROR) {
364         HILOGE("Connect error %{public}d.", ret);
365         return ret;
366     }
367 
368     HILOGI("fd_: %{public}d", pimpl->fd_);
369     if (pimpl->fd_ == -1) {
370         HILOGE("connect failed!");
371         return BtStatus::BT_FAILURE;
372     }
373 
374     bool recvret = pimpl->RecvSocketSignal();
375     HILOGI("recvret: %{public}d", recvret);
376     pimpl->inputStream_ = std::make_unique<InputStream>(pimpl->fd_);
377     pimpl->outputStream_ = std::make_unique<OutputStream>(pimpl->fd_);
378 
379     if (!recvret) {
380         HILOGE("connect failed!");
381         return BtStatus::BT_FAILURE;
382     }
383     pimpl->socketStatus_ = SOCKET_CONNECTED;
384     HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
385         HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", pimpl->fd_, "ADDRESS",
386         GetEncryptAddr(tempAddress), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
387     return BtStatus::BT_SUCCESS;
388 }
389 
Close()390 void ClientSocket::Close()
391 {
392     HILOGI("starts");
393     return pimpl->Close();
394 }
395 
GetInputStream()396 InputStream &ClientSocket::GetInputStream()
397 {
398     HILOGI("starts");
399     return pimpl->GetInputStream();
400 }
401 
GetOutputStream()402 OutputStream &ClientSocket::GetOutputStream()
403 {
404     HILOGI("starts");
405     return pimpl->GetOutputStream();
406 }
407 
GetRemoteDevice()408 BluetoothRemoteDevice &ClientSocket::GetRemoteDevice()
409 {
410     HILOGI("starts");
411     return pimpl->GetRemoteDevice();
412 }
413 
IsConnected() const414 bool ClientSocket::IsConnected() const
415 {
416     HILOGI("starts");
417     return pimpl->IsConnected();
418 }
419 
SetBufferSize(int bufferSize)420 int ClientSocket::SetBufferSize(int bufferSize)
421 {
422     HILOGI("starts");
423     return pimpl->SetBufferSize(bufferSize);
424 }
425 
426 struct ServerSocket::impl {
427     impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt);
~implOHOS::Bluetooth::ServerSocket::impl428     ~impl()
429     {
430         HILOGI("enter");
431         if (proxy_ != nullptr && proxy_->AsObject() != nullptr) {
432             proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
433         } else {
434             HILOGE("proxy_ is nullptr");
435         }
436 
437         if (fd_ > 0) {
438             shutdown(fd_, SHUT_RD);
439             shutdown(fd_, SHUT_WR);
440             close(fd_);
441             HILOGI("fd closed, fd_: %{public}d", fd_);
442             fd_ = -1;
443         }
444     }
445 
ListenOHOS::Bluetooth::ServerSocket::impl446     int Listen()
447     {
448         HILOGI("starts");
449         if (!IS_BT_ENABLED()) {
450             HILOGE("BR is not TURN_ON");
451             return BT_ERR_INVALID_STATE;
452         }
453         if (!proxy_) {
454             HILOGE("failed, proxy_ is nullptr");
455             socketStatus_ = SOCKET_CLOSED;
456             return BT_ERR_SERVICE_DISCONNECTED;
457         }
458         if (socketStatus_ == SOCKET_CLOSED) {
459             HILOGE("failed, socketStatus_ is SOCKET_CLOSED");
460             return BT_ERR_INVALID_STATE;
461         }
462 
463         ListenSocketParam param {
464             name_,
465             bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits()),
466             (int32_t)getSecurityFlags(),
467             (int32_t)type_
468         };
469         int ret = proxy_->Listen(param, fd_);
470         if (ret != BT_NO_ERROR) {
471             HILOGE("Listen error %{public}d.", ret);
472             return ret;
473         }
474         if (fd_ == BT_INVALID_SOCKET_FD) {
475             HILOGE("listen socket failed, fd_ is -1");
476             socketStatus_ = SOCKET_CLOSED;
477             return BT_ERR_INVALID_STATE;
478         }
479 
480         if (type_ == TYPE_L2CAP_LE) {
481             psm_ = RecvSocketPsm();
482             if (psm_ <= 0) {
483                 return BT_ERR_INVALID_STATE;
484             }
485         }
486 
487         if (socketStatus_ == SOCKET_INIT) {
488             socketStatus_ = SOCKET_LISTENING;
489         } else {
490             HILOGE("failed, socketStatus_: %{public}d is not SOCKET_INIT", socketStatus_);
491             close(fd_);
492             socketStatus_ = SOCKET_CLOSED;
493             return BT_ERR_INVALID_STATE;
494         }
495 
496         return BT_NO_ERROR;
497     }
498 
getSecurityFlagsOHOS::Bluetooth::ServerSocket::impl499     int getSecurityFlags()
500     {
501         int flags = 0;
502         if (encrypt_) {
503             flags |= FLAG_AUTH;
504             flags |= FLAG_ENCRYPT;
505         }
506         return flags;
507     }
508 
AcceptOHOS::Bluetooth::ServerSocket::impl509     std::shared_ptr<ClientSocket> Accept(int timeout)
510     {
511         HILOGI("starts");
512         if (socketStatus_ != SOCKET_LISTENING) {
513             HILOGE("socket is not in listen state");
514             return nullptr;
515         }
516         struct timeval time = {timeout, 0};
517         setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
518         setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
519 
520         acceptFd_ = RecvSocketFd();
521         HILOGE("RecvSocketFd acceptFd: %{public}d", acceptFd_);
522         if (acceptFd_ <= 0) {
523             return nullptr;
524         }
525         if (timeout > 0) {
526             time = {0, 0};
527             setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
528             setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
529         }
530 
531         std::shared_ptr<ClientSocket> clientSocket = std::make_shared<ClientSocket>(acceptFd_, acceptAddress_, type_);
532 
533         HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
534             HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", acceptFd_, "ADDRESS",
535             GetEncryptAddr(acceptAddress_), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
536 
537         return clientSocket;
538     }
539 
RecvSocketFdOHOS::Bluetooth::ServerSocket::impl540     int RecvSocketFd()
541     {
542         HILOGI("starts");
543         int rv = 0;
544         int cfd = -1;
545         int clientFd = -1;
546         char ccmsg[CMSG_SPACE(sizeof(cfd))];
547         char buffer[10];
548         struct iovec io = {.iov_base = buffer, .iov_len = sizeof(buffer)};
549         struct msghdr msg;
550         (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
551         msg.msg_control = ccmsg;
552         msg.msg_controllen = sizeof(ccmsg);
553         msg.msg_iov = &io;
554         msg.msg_iovlen = 1;
555 
556 #ifdef DARWIN_PLATFORM
557         rv = recvmsg(fd_, &msg, 0);
558 #else
559         rv = recvmsg(fd_, &msg, MSG_NOSIGNAL);
560 #endif
561         if (rv == -1) {
562             HILOGE("[sock] recvmsg error  %{public}d, fd: %{public}d", errno, fd_);
563             return BtStatus::BT_FAILURE;
564         }
565         struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg);
566         if ((cmptr != nullptr) && (cmptr->cmsg_len == CMSG_LEN(sizeof(int)))) {
567             if (cmptr->cmsg_level != SOL_SOCKET || cmptr->cmsg_type != SCM_RIGHTS) {
568                 HILOGE("[sock] control level: %{public}d", cmptr->cmsg_level);
569                 HILOGE("[sock] control type: %{public}d", cmptr->cmsg_type);
570                 return BtStatus::BT_FAILURE;
571             }
572             clientFd = *(reinterpret_cast<int *>(CMSG_DATA(cmptr)));
573         } else {
574             return BtStatus::BT_FAILURE;
575         }
576         uint8_t recvBuf[rv];
577         (void)memset_s(&recvBuf, sizeof(recvBuf), 0, sizeof(recvBuf));
578         if (memcpy_s(recvBuf, sizeof(recvBuf), (uint8_t *)msg.msg_iov[0].iov_base, rv) != EOK) {
579             HILOGE("[sock] RecvSocketFd, recvBuf memcpy_s fail");
580             return BtStatus::BT_FAILURE;
581         }
582 
583         uint8_t buf[6] = {0};
584         if (memcpy_s(buf, sizeof(buf), &recvBuf[1], sizeof(buf)) != EOK) {
585             HILOGE("[sock] RecvSocketFd, buf memcpy_s fail");
586             return BtStatus::BT_FAILURE;
587         }
588 
589         char token[LENGTH] = {0};
590         (void)sprintf_s(token, sizeof(token), "%02X:%02X:%02X:%02X:%02X:%02X",
591             buf[0x05], buf[0x04], buf[0x03], buf[0x02], buf[0x01], buf[0x00]);
592         BluetoothRawAddress rawAddr {token};
593         acceptAddress_ = rawAddr.GetAddress().c_str();
594         return clientFd;
595     }
596 
RecvSocketPsmOHOS::Bluetooth::ServerSocket::impl597     int RecvSocketPsm()
598     {
599         uint8_t recvBuf[PSM_BUFFER_SIZE];
600         int recvBufSize = recv(fd_, recvBuf, sizeof(recvBuf), MSG_WAITALL);
601         if (recvBufSize <= 0) {
602             HILOGE("[sock] recv error  %{public}d, fd: %{public}d", errno, fd_);
603             return BtStatus::BT_FAILURE;
604         }
605         int psm = recvBuf[0];
606         HILOGI("[sock] RecvSocketPsm psm: %{public}d", psm);
607         return psm;
608     }
609 
CloseOHOS::Bluetooth::ServerSocket::impl610     void Close()
611     {
612         HILOGI("starts");
613         if (socketStatus_ == SOCKET_CLOSED) {
614             HILOGW("The socketStatus_ is already SOCKET_CLOSED");
615             return;
616         } else {
617             socketStatus_ = SOCKET_CLOSED;
618             if (fd_ > 0) {
619                 shutdown(fd_, SHUT_RD);
620                 shutdown(fd_, SHUT_WR);
621                 close(fd_);
622                 HILOGI("fd closed, fd_: %{public}d", fd_);
623                 fd_ = -1;
624                 return;
625             } else {
626                 HILOGE("socket not created");
627                 return;
628             }
629         }
630     }
631 
GetStringTagOHOS::Bluetooth::ServerSocket::impl632     const std::string &GetStringTag()
633     {
634         HILOGI("starts");
635         if (socketStatus_ == SOCKET_CLOSED) {
636             HILOGE("socketStatus_ is SOCKET_CLOSED");
637             socketServiceType_ = "";
638         } else {
639             socketServiceType_ = "ServerSocket:";
640             socketServiceType_.append(" Type: ").append(ConvertTypeToString(type_))
641                 .append(" ServerName: ").append(name_);
642         }
643         return socketServiceType_;
644     }
645 
ConvertTypeToStringOHOS::Bluetooth::ServerSocket::impl646     static std::string ConvertTypeToString(BtSocketType type)
647     {
648         std::string retStr;
649         if (type == TYPE_RFCOMM) {
650             retStr = "TYPE_RFCOMM";
651         } else if (type == TYPE_L2CAP) {
652             retStr = "TYPE_L2CAP";
653         } else if (type == TYPE_L2CAP_LE) {
654             retStr = "TYPE_L2CAP_LE";
655         } else {
656             retStr = "TYPE_UNKNOW";
657         }
658         return retStr;
659     }
660 
661     class BluetoothServerSocketDeathRecipient;
662     sptr<BluetoothServerSocketDeathRecipient> deathRecipient_;
663 
664     sptr<IBluetoothSocket> proxy_;
665     UUID uuid_;
666     BtSocketType type_;
667     bool encrypt_;
668     int fd_;
669     int socketStatus_;
670     std::string name_ {
671         ""
672         };
673     int acceptFd_;
674     std::string acceptAddress_;
675     std::string socketServiceType_ {
676         ""
677     };
678     int psm_;
679 };
680 
681 class ServerSocket::impl::BluetoothServerSocketDeathRecipient final : public IRemoteObject::DeathRecipient {
682 public:
BluetoothServerSocketDeathRecipient(ServerSocket::impl & host)683     explicit BluetoothServerSocketDeathRecipient(ServerSocket::impl &host) : host_(host) {};
684     ~BluetoothServerSocketDeathRecipient() final = default;
685     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothServerSocketDeathRecipient);
686 
OnRemoteDied(const wptr<IRemoteObject> & remote)687     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
688     {
689         HILOGI("starts");
690         if (!host_.proxy_) {
691             return;
692         }
693         host_.proxy_->AsObject()->RemoveDeathRecipient(host_.deathRecipient_);
694         host_.proxy_ = nullptr;
695     }
696 
697 private:
698     ServerSocket::impl &host_;
699 };
700 
impl(const std::string & name,UUID uuid,BtSocketType type,bool encrypt)701 ServerSocket::impl::impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt)
702     : uuid_(uuid), type_(type), encrypt_(encrypt), fd_(-1), socketStatus_(SOCKET_INIT), name_(name), psm_(-1)
703 {
704     HILOGI("(4 parameters) starts");
705     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
706     sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
707 
708     if (!hostRemote) {
709         HILOGI("failed: no hostRemote");
710         return;
711     }
712     sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
713     sptr<IRemoteObject> remote = hostProxy->GetProfile(PROFILE_SOCKET);
714 
715     if (!remote) {
716         HILOGE("failed: no remote");
717         return;
718     }
719     HILOGI("remote obtained");
720 
721     proxy_ = iface_cast<IBluetoothSocket>(remote);
722     if (proxy_ == nullptr) {
723         return;
724     }
725     deathRecipient_ = new BluetoothServerSocketDeathRecipient(*this);
726     proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
727 }
728 
ServerSocket(const std::string & name,UUID uuid,BtSocketType type,bool encrypt)729 ServerSocket::ServerSocket(const std::string &name, UUID uuid, BtSocketType type, bool encrypt)
730     : pimpl(new ServerSocket::impl(name, uuid, type, encrypt))
731 {
732     HILOGI("(4 parameters) starts");
733 }
734 
~ServerSocket()735 ServerSocket::~ServerSocket()
736 {}
737 
Listen()738 int ServerSocket::Listen()
739 {
740     HILOGI("starts");
741     return pimpl->Listen();
742 }
743 
Accept(int timeout)744 std::shared_ptr<ClientSocket> ServerSocket::Accept(int timeout)
745 {
746     HILOGI("starts");
747     return pimpl->Accept(timeout);
748 }
749 
Close()750 void ServerSocket::Close()
751 {
752     HILOGI("starts");
753     return pimpl->Close();
754 }
755 
GetStringTag()756 const std::string &ServerSocket::GetStringTag()
757 {
758     HILOGI("starts");
759     return pimpl->GetStringTag();
760 }
761 
GetPsm()762 int ServerSocket::GetPsm()
763 {
764     return pimpl->psm_;
765 }
766 
BuildInsecureRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)767 std::shared_ptr<ClientSocket> SocketFactory::BuildInsecureRfcommDataSocketByServiceRecord(
768     const BluetoothRemoteDevice &device, const UUID &uuid)
769 {
770     HILOGI("starts");
771     if (device.IsValidBluetoothRemoteDevice()) {
772         return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, false);
773     } else {
774         HILOGE("[sock] Device is not valid.");
775         return nullptr;
776     }
777 }
778 
BuildRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)779 std::shared_ptr<ClientSocket> SocketFactory::BuildRfcommDataSocketByServiceRecord(
780     const BluetoothRemoteDevice &device, const UUID &uuid)
781 {
782     HILOGI("starts");
783     if (device.IsValidBluetoothRemoteDevice()) {
784         return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, true);
785     } else {
786         HILOGE("[sock] Device is not valid.");
787         return nullptr;
788     }
789 }
790 
DataListenInsecureRfcommByServiceRecord(const std::string & name,const UUID & uuid)791 std::shared_ptr<ServerSocket> SocketFactory::DataListenInsecureRfcommByServiceRecord(
792     const std::string &name, const UUID &uuid)
793 {
794     HILOGI("starts");
795     return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, false);
796 }
797 
DataListenRfcommByServiceRecord(const std::string & name,const UUID & uuid)798 std::shared_ptr<ServerSocket> SocketFactory::DataListenRfcommByServiceRecord(const std::string &name, const UUID &uuid)
799 {
800     HILOGI("starts");
801     return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, true);
802 }
803 }  // namespace Bluetooth
804 }  // namespace OHOS