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