1/* 2 * Copyright (C) 2021-2023 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 "bluetooth_socket.h" 17 18#include <sys/socket.h> 19#include <string> 20#include <unistd.h> 21#include <atomic> 22#include "bluetooth_log.h" 23#include "bluetooth_host.h" 24#include "bluetooth_host_proxy.h" 25#include "bluetooth_utils.h" 26#include "bluetooth_socket_proxy.h" 27#include "hisysevent.h" 28#include "ipc_skeleton.h" 29#include "iservice_registry.h" 30#include "securec.h" 31#include "system_ability_definition.h" 32#include "raw_address.h" 33#include "bluetooth_socket_observer_stub.h" 34#include "bluetooth_profile_manager.h" 35#ifdef RES_SCHED_SUPPORT 36#include "res_type.h" 37#include "res_sched_client.h" 38#endif 39 40namespace OHOS { 41namespace Bluetooth { 42const int LENGTH = 18; 43const int MIN_BUFFER_SIZE_TO_SET = 4 * 1024; // 4KB 44const int MAX_BUFFER_SIZE_TO_SET = 50 * 1024; // 50KB 45const int ADDR_OFFSET = 1; // state(1) 46const int TX_OFFSET = 7; // state(1)+addr(6) 47const int RX_OFFSET = 9; // state(1)+addr(6)+tx(2) 48const int SOCKET_RECV_ADDR_SIZE = 6; 49const int SOCKET_RECV_TXRX_SIZE = 2; 50const int SOCKET_RECV_CHANNEL_SIZE = 4; 51const int SOCKET_RECV_FD_SIZE = 14; 52const int SOCKET_RECV_FD_SIGNAL = 11; // state(1)+addr(6)+tx(2)+rx(2) 53 54constexpr char BLUETOOTH_UE_DOMAIN[] = "BLUETOOTH_UE"; 55std::mutex g_socketProxyMutex; 56 57#define SPTR_SOCKET_CBACK(cbSptr, func, ...) \ 58do { \ 59 if (cbSptr) { \ 60 cbSptr->func(__VA_ARGS__); \ 61 } else { \ 62 HILOGE(#cbSptr ": callback is nullptr"); \ 63 } \ 64} while (0) 65 66static void ReportDataToRss(const std::string &action, int id, const std::string &address, int pid, int uid) 67{ 68#ifdef RES_SCHED_SUPPORT 69 HILOGD("report SPP_CONNECT_STATE"); 70 std::unordered_map<std::string, std::string> payload; 71 payload["ACTION"] = action; 72 payload["ID"] = std::to_string(id); 73 payload["ADDRESS"] = address; 74 payload["PID"] = std::to_string(pid); 75 payload["UID"] = std::to_string(uid); 76 ResourceSchedule::ResSchedClient::GetInstance().ReportData( 77 OHOS::ResourceSchedule::ResType::RES_TYPE_BT_SERVICE_EVENT, 78 OHOS::ResourceSchedule::ResType::BtServiceEvent::SPP_CONNECT_STATE, 79 payload); 80#endif 81} 82 83struct ClientSocket::impl { 84 impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth); 85 impl(int fd, std::string address, BtSocketType type); 86 impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth, 87 std::shared_ptr<BluetoothConnectionObserver> observer); 88 ~impl() 89 { 90 HILOGI("ClientSocket::impl ~impl"); 91 if (fd_ > 0) { 92 shutdown(fd_, SHUT_RD); 93 shutdown(fd_, SHUT_WR); 94 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE", 95 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty", 96 "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid()); 97 HiSysEventWrite(BLUETOOTH_UE_DOMAIN, "SOCKET_DISCONN", HiviewDFX::HiSysEvent::EventType::BEHAVIOR, 98 "PNAMEID", "Bluetooth", "PVERSIONID", "1.0", "DEV_ADDRESS", GetEncryptAddr(address_), 99 "SCENE_CODE", fd_); 100 ReportDataToRss("close", fd_, "empty", IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid()); 101 HILOGI("fd closed, fd_: %{public}d", fd_); 102 close(fd_); 103 fd_ = -1; 104 } 105 } 106 107 __attribute__((no_sanitize("cfi"))) 108 void Close() 109 { 110 HILOGD("enter"); 111 if (socketStatus_ == SOCKET_CLOSED) { 112 HILOGD("The socketStatus_ is already SOCKET_CLOSED"); 113 return; 114 } else { 115 socketStatus_ = SOCKET_CLOSED; 116 if (fd_ > 0) { 117 shutdown(fd_, SHUT_RD); 118 shutdown(fd_, SHUT_WR); 119 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE", 120 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty", 121 "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid()); 122 HiSysEventWrite(BLUETOOTH_UE_DOMAIN, "SOCKET_DISCONN", HiviewDFX::HiSysEvent::EventType::BEHAVIOR, 123 "PNAMEID", "Bluetooth", "PVERSIONID", "1.0", "DEV_ADDRESS", GetEncryptAddr(address_), 124 "SCENE_CODE", fd_); 125 ReportDataToRss("close", fd_, "empty", IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid()); 126 HILOGI("fd closed, fd_: %{public}d", fd_); 127 close(fd_); 128 fd_ = -1; 129 } else { 130 HILOGE("socket not created"); 131 } 132 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET); 133 CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr"); 134 bluetooth::Uuid tempUuid = bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits()); 135 if (!observerImp_) { 136 HILOGD("observerImp_ is nullptr"); 137 return; 138 } 139 proxy->DeregisterClientObserver(BluetoothRawAddress(remoteDevice_.GetDeviceAddr()), tempUuid, 140 observerImp_); 141 } 142 } 143 144 uint16_t GetPacketSizeFromBuf(const uint8_t recvBuf[], int recvBufLen) const 145 { 146 uint16_t shortBuf; 147 CHECK_AND_RETURN_LOG_RET(recvBuf, 0, "getpacketsize fail, invalid recvBuf"); 148 CHECK_AND_RETURN_LOG_RET(recvBufLen >= SOCKET_RECV_TXRX_SIZE, 0, "getpacketsize fail, invalid recvBufLen"); 149 CHECK_AND_RETURN_LOG_RET(memcpy_s(&shortBuf, sizeof(shortBuf), &recvBuf[0], sizeof(shortBuf)) == EOK, 0, 150 "getpacketsize failed, memcpy_s fail"); 151 return shortBuf; 152 } 153 154 bool RecvSocketSignal() 155 { 156 uint8_t signalBuf[SOCKET_RECV_FD_SIGNAL] = {0}; 157#ifdef DARWIN_PLATFORM 158 int recvBufSize = recv(fd_, signalBuf, sizeof(signalBuf), 0); 159#else 160 int recvBufSize = recv(fd_, signalBuf, sizeof(signalBuf), MSG_WAITALL); 161#endif 162 CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_FD_SIGNAL, false, "recv signal error, service closed"); 163 bool state = signalBuf[0]; 164 // remote addr has been obtained, no need obtain again 165 maxTxPacketSize_ = GetPacketSizeFromBuf(signalBuf + TX_OFFSET, SOCKET_RECV_FD_SIGNAL - TX_OFFSET); 166 maxRxPacketSize_ = GetPacketSizeFromBuf(signalBuf + RX_OFFSET, SOCKET_RECV_FD_SIGNAL - RX_OFFSET); 167 168 return state; 169 } 170 171 int getSecurityFlags() 172 { 173 int flags = 0; 174 if (auth_) { 175 flags |= FLAG_AUTH; 176 flags |= FLAG_ENCRYPT; 177 } 178 return flags; 179 } 180 181 std::shared_ptr<InputStream> GetInputStream() 182 { 183 HILOGD("enter"); 184 if (inputStream_ == nullptr) { 185 HILOGE("inputStream is NULL, failed. please Connect"); 186 } 187 return inputStream_; 188 } 189 190 std::shared_ptr<OutputStream> GetOutputStream() 191 { 192 HILOGD("enter"); 193 if (outputStream_ == nullptr) { 194 HILOGE("outputStream is NULL, failed. please Connect"); 195 } 196 return outputStream_; 197 } 198 199 BluetoothRemoteDevice &GetRemoteDevice() 200 { 201 HILOGD("enter"); 202 return remoteDevice_; 203 } 204 205 bool IsConnected() 206 { 207 HILOGD("enter"); 208 return socketStatus_ == SOCKET_CONNECTED; 209 } 210 211 int SetBufferSize(int bufferSize) 212 { 213 HILOGI("SetBufferSize bufferSize is %{public}d.", bufferSize); 214 if (bufferSize < MIN_BUFFER_SIZE_TO_SET || bufferSize > MAX_BUFFER_SIZE_TO_SET) { 215 HILOGE("SetBufferSize param is invalid."); 216 return RET_BAD_PARAM; 217 } 218 219 if (fd_ <= 0) { 220 HILOGE("SetBufferSize socket fd invalid."); 221 return RET_BAD_STATUS; 222 } 223 224 const std::pair<const char*, int> sockOpts[] = { 225 {"recvBuffer", SO_RCVBUF}, 226 {"sendBuffer", SO_SNDBUF}, 227 }; 228 for (auto opt : sockOpts) { 229 int curSize = 0; 230 socklen_t optlen = sizeof(curSize); 231 if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) { 232 HILOGE("SetBufferSize getsockopt %{public}s failed.", opt.first); 233 return RET_BAD_STATUS; 234 } 235 HILOGI("SetBufferSize %{public}s before set size is %{public}d.", opt.first, curSize); 236 237 if (curSize != bufferSize) { 238 int setSize = bufferSize / 2; 239 if (setsockopt(fd_, SOL_SOCKET, opt.second, &setSize, sizeof(setSize)) != 0) { 240 HILOGE("SetBufferSize setsockopt %{public}s failed.", opt.first); 241 return RET_BAD_STATUS; 242 } 243 244 curSize = 0; 245 if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) { 246 HILOGE("SetBufferSize after getsockopt %{public}s failed.", opt.first); 247 return RET_BAD_STATUS; 248 } 249 HILOGI("SetBufferSize %{public}s after set size is %{public}d.", opt.first, curSize); 250 } 251 } 252 253 return RET_NO_ERROR; 254 } 255 256 bool RecvSocketPsmOrScn() 257 { 258 int channel = 0; 259#ifdef DARWIN_PLATFORM 260 int recvBufSize = recv(fd_, &channel, sizeof(channel), 0); 261#else 262 int recvBufSize = recv(fd_, &channel, sizeof(channel), MSG_WAITALL); 263#endif 264 CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_CHANNEL_SIZE, false, 265 "recv psm or scn error, errno:%{public}d, fd_:%{public}d", errno, fd_); 266 CHECK_AND_RETURN_LOG_RET(channel > 0, false, "recv channel error, invalid channel:%{public}d", channel); 267 HILOGI("psm or scn = %{public}d, type = %{public}d", channel, type_); 268 socketChannel_ = channel; 269 return true; 270 } 271 272 // user register observer 273 std::shared_ptr<BluetoothConnectionObserver> observer_; 274 class BluetoothSocketObserverImp; 275 276 // socket observer 277 sptr<BluetoothSocketObserverImp> observerImp_ = nullptr; 278 std::shared_ptr<InputStream> inputStream_ { 279 nullptr 280 }; 281 std::shared_ptr<OutputStream> outputStream_ { 282 nullptr 283 }; 284 bool Init(std::weak_ptr<ClientSocket> client); 285 BluetoothRemoteDevice remoteDevice_; 286 UUID uuid_; 287 BtSocketType type_; 288 std::string address_; 289 int fd_; 290 bool auth_; 291 int socketStatus_; 292 std::atomic<int> socketChannel_{ -1 }; 293 std::atomic<uint32_t> maxTxPacketSize_{ 0 }; 294 std::atomic<uint32_t> maxRxPacketSize_{ 0 }; 295}; 296 297class ClientSocket::impl::BluetoothSocketObserverImp : public BluetoothClientSocketObserverStub { 298public: 299 inline std::shared_ptr<ClientSocket> GetClientSocketSptr(void) 300 { 301 auto clientSptr = clientSocket_.lock(); 302 if (!clientSptr) { 303 HILOGE("clientSocket_ is nullptr"); 304 return nullptr; 305 } 306 return clientSptr; 307 } 308 309 explicit BluetoothSocketObserverImp(std::weak_ptr<ClientSocket> clientSocket) : clientSocket_(clientSocket) 310 { 311 HILOGD("enter"); 312 } 313 ~BluetoothSocketObserverImp() 314 { 315 HILOGD("enter"); 316 } 317 318 __attribute__((no_sanitize("cfi"))) 319 void OnConnectionStateChanged(const CallbackParam &callbackParam) override 320 { 321 HILOGD("dev: %{public}s, uuid:%{public}s, status: %{public}d, psm: %{public}d, result: %{public}d", 322 GetEncryptAddr((callbackParam.dev).GetAddress()).c_str(), callbackParam.uuid.ToString().c_str(), 323 callbackParam.status, callbackParam.psm, callbackParam.result); 324 BluetoothRemoteDevice device(callbackParam.dev.GetAddress(), BTTransport::ADAPTER_BREDR); 325 UUID btUuid = UUID::ConvertFrom128Bits(callbackParam.uuid.ConvertTo128Bits()); 326 auto clientSptr = GetClientSocketSptr(); 327 if (!clientSptr) { 328 HILOGE("clientSptr is nullptr"); 329 return; 330 } 331 if (!clientSptr->pimpl) { 332 HILOGE("impl is nullptr"); 333 return; 334 } 335 CallbackConnectParam callbackConnectParam = { 336 .addr = device, 337 .uuid = btUuid, 338 .status = callbackParam.status, 339 .result = callbackParam.result, 340 .type = callbackParam.type, 341 .psm = callbackParam.psm, 342 }; 343 SPTR_SOCKET_CBACK(clientSptr->pimpl->observer_, OnConnectionStateChanged, callbackConnectParam); 344 } 345 346private: 347 std::weak_ptr<ClientSocket> clientSocket_; 348}; 349 350bool ClientSocket::impl::Init(std::weak_ptr<ClientSocket> client) 351{ 352 if (observerImp_ != nullptr) { 353 return true; 354 } 355 observerImp_ = new(std::nothrow) BluetoothSocketObserverImp(client); 356 if (observerImp_ == nullptr) { 357 return false; 358 } 359 return true; 360} 361 362ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth) 363 : inputStream_(nullptr), 364 outputStream_(nullptr), 365 remoteDevice_(addr), 366 uuid_(uuid), 367 type_(type), 368 fd_(-1), 369 auth_(auth), 370 socketStatus_(SOCKET_INIT) 371{ 372 HILOGD("enter 4 parameters"); 373} 374 375ClientSocket::impl::impl(int fd, std::string address, BtSocketType type) 376 : inputStream_(std::make_unique<InputStream>(fd)), 377 outputStream_(std::make_unique<OutputStream>(fd)), 378 remoteDevice_(BluetoothRemoteDevice(address, 0)), 379 type_(type), 380 address_(address), 381 fd_(fd), 382 auth_(false), 383 socketStatus_(SOCKET_CONNECTED) 384{ 385 HILOGD("enter 3 parameters"); 386} 387 388ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth, 389 std::shared_ptr<BluetoothConnectionObserver> observer) 390 : observer_(observer), 391 inputStream_(nullptr), 392 outputStream_(nullptr), 393 remoteDevice_(addr), 394 uuid_(uuid), 395 type_(type), 396 fd_(-1), 397 auth_(auth), 398 socketStatus_(SOCKET_INIT) 399{ 400 HILOGD("enter 5 parameters"); 401} 402 403ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth) 404 : pimpl(new ClientSocket::impl(bda, uuid, type, auth)) 405{} 406 407ClientSocket::ClientSocket(int fd, std::string address, BtSocketType type) 408 : pimpl(new ClientSocket::impl(fd, address, type)) 409{} 410 411ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth, 412 std::shared_ptr<BluetoothConnectionObserver> observer) 413 : pimpl(new ClientSocket::impl(bda, uuid, type, auth, observer)) 414{} 415 416ClientSocket::~ClientSocket() 417{} 418 419bool ClientSocket::Init() 420{ 421 HILOGI("ClientSocket Init"); 422 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, false, "pimpl is nullptr!"); 423 return pimpl->Init(weak_from_this()); 424} 425 426int ClientSocket::Connect(int psm) 427{ 428 HILOGD("enter"); 429 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 430 if (pimpl->type_ == TYPE_L2CAP_LE) { 431 CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "BLE is not TURN_ON"); 432 } else { 433 CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "BR is not TURN_ON"); 434 } 435 436 if (!pimpl->Init(weak_from_this())) { 437 HILOGE("clientSocket proxy is nullptr"); 438 return BT_ERR_INTERNAL_ERROR; 439 } 440 441 pimpl->address_ = pimpl->remoteDevice_.GetDeviceAddr(); 442 std::string tempAddress = pimpl->address_; 443 CHECK_AND_RETURN_LOG_RET(tempAddress.size(), BtStatus::BT_FAILURE, "address size error"); 444 CHECK_AND_RETURN_LOG_RET(pimpl->socketStatus_ != SOCKET_CLOSED, BT_ERR_INVALID_STATE, "socket closed"); 445 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET); 446 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "proxy is nullptr"); 447 448 bluetooth::Uuid tempUuid = bluetooth::Uuid::ConvertFrom128Bits(pimpl->uuid_.ConvertTo128Bits()); 449 int ret = proxy->RegisterClientObserver(BluetoothRawAddress(pimpl->address_), tempUuid, 450 pimpl->observerImp_); 451 CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, ret, "regitser observer fail, ret = %d", ret); 452 453 ConnectSocketParam param { 454 .addr = tempAddress, 455 .uuid = tempUuid, 456 .securityFlag = (int32_t)pimpl->getSecurityFlags(), 457 .type = (int32_t)pimpl->type_, 458 .psm = psm 459 }; 460 ret = proxy->Connect(param, pimpl->fd_); 461 CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, ret, "Connect error %{public}d", ret); 462 463 HILOGI("fd_: %{public}d", pimpl->fd_); 464 CHECK_AND_RETURN_LOG_RET(pimpl->fd_ != -1, BtStatus::BT_FAILURE, "connect failed!"); 465 CHECK_AND_RETURN_LOG_RET(pimpl->RecvSocketPsmOrScn(), BT_ERR_INVALID_STATE, "recv psm or scn failed"); 466 467 bool recvret = pimpl->RecvSocketSignal(); 468 HILOGI("recvret: %{public}d", recvret); 469 pimpl->inputStream_ = std::make_unique<InputStream>(pimpl->fd_); 470 pimpl->outputStream_ = std::make_unique<OutputStream>(pimpl->fd_); 471 CHECK_AND_RETURN_LOG_RET(recvret, BtStatus::BT_FAILURE, "recvSocketSignal connect failed!"); 472 pimpl->socketStatus_ = SOCKET_CONNECTED; 473 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE", 474 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", pimpl->fd_, "ADDRESS", 475 GetEncryptAddr(tempAddress), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid()); 476 ReportDataToRss("connect", pimpl->fd_, GetEncryptAddr(tempAddress), IPCSkeleton::GetCallingPid(), 477 IPCSkeleton::GetCallingUid()); 478 return BtStatus::BT_SUCCESS; 479} 480 481void ClientSocket::Close() 482{ 483 HILOGD("enter"); 484 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is nullptr!"); 485 return pimpl->Close(); 486} 487 488std::shared_ptr<InputStream> ClientSocket::GetInputStream() 489{ 490 HILOGD("enter"); 491 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, nullptr, "pimpl is nullptr!"); 492 return pimpl->GetInputStream(); 493} 494 495std::shared_ptr<OutputStream> ClientSocket::GetOutputStream() 496{ 497 HILOGD("enter"); 498 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, nullptr, "pimpl is nullptr!"); 499 return pimpl->GetOutputStream(); 500} 501 502BluetoothRemoteDevice &ClientSocket::GetRemoteDevice() 503{ 504 HILOGD("enter"); 505 return pimpl->GetRemoteDevice(); 506} 507 508bool ClientSocket::IsConnected() const 509{ 510 HILOGD("enter"); 511 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, false, "pimpl is nullptr!"); 512 return pimpl->IsConnected(); 513} 514 515int ClientSocket::SetBufferSize(int bufferSize) 516{ 517 HILOGD("enter"); 518 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, false, "pimpl is nullptr!"); 519 return pimpl->SetBufferSize(bufferSize); 520} 521 522int ClientSocket::GetSocketFd() 523{ 524 HILOGD("enter"); 525 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 526 return pimpl->fd_; 527} 528 529int ClientSocket::GetL2capPsm() 530{ 531 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 532 HILOGI("psm:%{public}d", pimpl->socketChannel_.load()); 533 return pimpl->socketChannel_; 534} 535 536int ClientSocket::GetRfcommScn() 537{ 538 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 539 HILOGI("scn:%{public}d", pimpl->socketChannel_.load()); 540 return pimpl->socketChannel_; 541} 542 543uint32_t ClientSocket::GetMaxTransmitPacketSize() 544{ 545 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 546 HILOGI("MaxTransmitPacketSize:%{public}d", pimpl->maxTxPacketSize_.load()); 547 return pimpl->maxTxPacketSize_; 548} 549 550uint32_t ClientSocket::GetMaxReceivePacketSize() 551{ 552 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 553 HILOGI("MaxReceivePacketSize:%{public}d", pimpl->maxRxPacketSize_.load()); 554 return pimpl->maxRxPacketSize_; 555} 556 557struct ServerSocket::impl { 558 impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt); 559 ~impl() 560 { 561 if (fd_ > 0) { 562 shutdown(fd_, SHUT_RD); 563 shutdown(fd_, SHUT_WR); 564 close(fd_); 565 HILOGI("fd closed, fd_: %{public}d", fd_); 566 fd_ = -1; 567 } 568 } 569 570 int Listen() 571 { 572 HILOGD("enter"); 573 if (type_ == TYPE_L2CAP_LE) { 574 CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "BLE is not TURN_ON"); 575 } else { 576 CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "BR is not TURN_ON"); 577 } 578 579 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET); 580 if (!proxy) { 581 HILOGE("failed, proxy is nullptr"); 582 socketStatus_ = SOCKET_CLOSED; 583 return BT_ERR_SERVICE_DISCONNECTED; 584 } 585 CHECK_AND_RETURN_LOG_RET(socketStatus_ != SOCKET_CLOSED, BT_ERR_INVALID_STATE, 586 "failed, socketStatus_ is SOCKET_CLOSED"); 587 588 ListenSocketParam param { 589 .name = name_, 590 .uuid = bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits()), 591 .securityFlag = (int32_t)getSecurityFlags(), 592 .type = (int32_t)type_, 593 .observer = observer_ 594 }; 595 int ret = proxy->Listen(param, fd_); 596 if (ret != BT_NO_ERROR) { 597 HILOGE("Listen error %{public}d.", ret); 598 socketStatus_ = SOCKET_CLOSED; 599 return ret; 600 } 601 602 if (fd_ == BT_INVALID_SOCKET_FD) { 603 HILOGE("listen socket failed"); 604 socketStatus_ = SOCKET_CLOSED; 605 return BT_ERR_INVALID_STATE; 606 } 607 608 CHECK_AND_RETURN_LOG_RET(RecvSocketPsmOrScn(), BT_ERR_INVALID_STATE, "recv psm or scn failed"); 609 610 if (socketStatus_ == SOCKET_INIT) { 611 socketStatus_ = SOCKET_LISTENING; 612 } else { 613 HILOGE("failed, socketStatus_: %{public}d is not SOCKET_INIT", socketStatus_); 614 close(fd_); 615 socketStatus_ = SOCKET_CLOSED; 616 return BT_ERR_INVALID_STATE; 617 } 618 619 return BT_NO_ERROR; 620 } 621 622 int getSecurityFlags() 623 { 624 int flags = 0; 625 if (encrypt_) { 626 flags |= FLAG_AUTH; 627 flags |= FLAG_ENCRYPT; 628 } 629 return flags; 630 } 631 632 std::shared_ptr<ClientSocket> Accept(int timeout) 633 { 634 HILOGD("enter"); 635 if (socketStatus_ != SOCKET_LISTENING) { 636 HILOGE("socket is not in listen state"); 637 return nullptr; 638 } 639 struct timeval time = {timeout, 0}; 640 setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time)); 641 setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time)); 642 643 acceptFd_ = RecvSocketFd(); 644 HILOGI("RecvSocketFd acceptFd: %{public}d", acceptFd_); 645 if (acceptFd_ <= 0) { 646 return nullptr; 647 } 648 if (timeout > 0) { 649 time = {0, 0}; 650 setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time)); 651 setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time)); 652 } 653 654 std::shared_ptr<ClientSocket> clientSocket = std::make_shared<ClientSocket>(acceptFd_, acceptAddress_, type_); 655 656 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE", 657 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", acceptFd_, "ADDRESS", 658 GetEncryptAddr(acceptAddress_), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid()); 659 ReportDataToRss("connect", acceptFd_, GetEncryptAddr(acceptAddress_), IPCSkeleton::GetCallingPid(), 660 IPCSkeleton::GetCallingUid()); 661 return clientSocket; 662 } 663 664 int RecvSocketFd() 665 { 666 HILOGD("enter"); 667 char ccmsg[CMSG_SPACE(sizeof(int))]; 668 char buffer[SOCKET_RECV_FD_SIZE]; 669 struct iovec io = {.iov_base = buffer, .iov_len = sizeof(buffer)}; 670 struct msghdr msg; 671 (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg)); 672 msg.msg_control = ccmsg; 673 msg.msg_controllen = sizeof(ccmsg); 674 msg.msg_iov = &io; 675 msg.msg_iovlen = 1; 676 677#ifdef DARWIN_PLATFORM 678 int rv = recvmsg(fd_, &msg, 0); 679#else 680 int rv = recvmsg(fd_, &msg, MSG_NOSIGNAL); 681#endif 682 if (rv == -1) { 683 HILOGE("[sock] recvmsg error %{public}d, fd: %{public}d", errno, fd_); 684 return BtStatus::BT_FAILURE; 685 } 686 struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg); 687 CHECK_AND_RETURN_LOG_RET(cmptr != nullptr, BtStatus::BT_FAILURE, "cmptr error"); 688 CHECK_AND_RETURN_LOG_RET(cmptr->cmsg_len == CMSG_LEN(sizeof(int)) && cmptr->cmsg_level == SOL_SOCKET 689 && cmptr->cmsg_type == SCM_RIGHTS, BtStatus::BT_FAILURE, 690 "recvmsg error, len:%{public}d level:%{public}d type:%{public}d", 691 cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type); 692 int clientFd = *(reinterpret_cast<int *>(CMSG_DATA(cmptr))); 693 694 uint8_t recvBuf[rv]; 695 (void)memset_s(&recvBuf, sizeof(recvBuf), 0, sizeof(recvBuf)); 696 CHECK_AND_RETURN_LOG_RET(memcpy_s(recvBuf, sizeof(recvBuf), (uint8_t *)msg.msg_iov[0].iov_base, rv) == EOK, 697 BtStatus::BT_FAILURE, "RecvSocketFd, recvBuf memcpy_s fail"); 698 699 uint8_t buf[SOCKET_RECV_ADDR_SIZE] = {0}; 700 CHECK_AND_RETURN_LOG_RET(memcpy_s(buf, sizeof(buf), &recvBuf[ADDR_OFFSET], sizeof(buf)) == EOK, 701 BtStatus::BT_FAILURE, "RecvSocketFd, buf memcpy_s fail"); 702 703 char token[LENGTH] = {0}; 704 (void)sprintf_s(token, sizeof(token), "%02X:%02X:%02X:%02X:%02X:%02X", 705 buf[0x05], buf[0x04], buf[0x03], buf[0x02], buf[0x01], buf[0x00]); 706 BluetoothRawAddress rawAddr {token}; 707 acceptAddress_ = rawAddr.GetAddress().c_str(); 708 709 maxTxPacketSize_ = GetPacketSizeFromBuf(recvBuf + TX_OFFSET, rv - TX_OFFSET); 710 maxRxPacketSize_ = GetPacketSizeFromBuf(recvBuf + RX_OFFSET, rv - RX_OFFSET); 711 return clientFd; 712 } 713 714 uint16_t GetPacketSizeFromBuf(uint8_t recvBuf[], int recvBufLen) 715 { 716 uint16_t shortBuf; 717 CHECK_AND_RETURN_LOG_RET(recvBuf, 0, "getpacketsize fail, invalid recvBuf"); 718 CHECK_AND_RETURN_LOG_RET(recvBufLen >= SOCKET_RECV_TXRX_SIZE, 0, "getpacketsize fail, invalid recvBufLen"); 719 CHECK_AND_RETURN_LOG_RET(memcpy_s(&shortBuf, sizeof(shortBuf), &recvBuf[0], sizeof(shortBuf)) == EOK, 0, 720 "getpacketsize failed, memcpy_s fail"); 721 return shortBuf; 722 } 723 724 bool RecvSocketPsmOrScn() 725 { 726 int channel = 0; 727#ifdef DARWIN_PLATFORM 728 int recvBufSize = recv(fd_, &channel, sizeof(channel), 0); 729#else 730 int recvBufSize = recv(fd_, &channel, sizeof(channel), MSG_WAITALL); 731#endif 732 CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_CHANNEL_SIZE, false, 733 "recv psm or scn error, errno:%{public}d, fd_:%{public}d", errno, fd_); 734 CHECK_AND_RETURN_LOG_RET(channel > 0, false, 735 "recv channel error, errno:%{public}d, fd_:%{public}d", errno, fd_); 736 HILOGI("psm or scn = %{public}d, type = %{public}d", channel, type_); 737 socketChannel_ = channel; 738 return true; 739 } 740 741 void Close() 742 { 743 HILOGD("enter"); 744 if (socketStatus_ == SOCKET_CLOSED) { 745 HILOGD("The socketStatus_ is already SOCKET_CLOSED"); 746 return; 747 } else { 748 socketStatus_ = SOCKET_CLOSED; 749 if (fd_ > 0) { 750 shutdown(fd_, SHUT_RD); 751 shutdown(fd_, SHUT_WR); 752 HILOGI("fd closed, fd_: %{public}d", fd_); 753 close(fd_); 754 fd_ = -1; 755 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET); 756 CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr"); 757 proxy->DeregisterServerObserver(observer_); 758 return; 759 } else { 760 HILOGE("socket not created"); 761 return; 762 } 763 } 764 } 765 766 const std::string &GetStringTag() 767 { 768 HILOGD("enter"); 769 if (socketStatus_ == SOCKET_CLOSED) { 770 HILOGE("socketStatus_ is SOCKET_CLOSED"); 771 socketServiceType_ = ""; 772 } else { 773 socketServiceType_ = "ServerSocket:"; 774 socketServiceType_.append(" Type: ").append(ConvertTypeToString(type_)) 775 .append(" ServerName: ").append(name_); 776 } 777 return socketServiceType_; 778 } 779 780 static std::string ConvertTypeToString(BtSocketType type) 781 { 782 std::string retStr; 783 if (type == TYPE_RFCOMM) { 784 retStr = "TYPE_RFCOMM"; 785 } else if (type == TYPE_L2CAP) { 786 retStr = "TYPE_L2CAP"; 787 } else if (type == TYPE_L2CAP_LE) { 788 retStr = "TYPE_L2CAP_LE"; 789 } else { 790 retStr = "TYPE_UNKNOW"; 791 } 792 return retStr; 793 } 794 795 sptr<BluetoothServerSocketObserverStub> observer_ = nullptr; 796 797 sptr<IBluetoothSocket> proxy; 798 UUID uuid_; 799 BtSocketType type_; 800 bool encrypt_; 801 int fd_; 802 int socketStatus_; 803 std::string name_ { 804 "" 805 }; 806 int acceptFd_ = 0; 807 std::string acceptAddress_; 808 std::string socketServiceType_ { 809 "" 810 }; 811 std::atomic<int> socketChannel_{ -1 }; 812 std::atomic<uint32_t> maxTxPacketSize_{ 0 }; 813 std::atomic<uint32_t> maxRxPacketSize_{ 0 }; 814}; 815 816ServerSocket::impl::impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt) 817 : uuid_(uuid), type_(type), encrypt_(encrypt), fd_(-1), socketStatus_(SOCKET_INIT), name_(name) 818{ 819 HILOGD("(4 parameters) starts"); 820 observer_ = new BluetoothServerSocketObserverStub(); 821} 822 823ServerSocket::ServerSocket(const std::string &name, UUID uuid, BtSocketType type, bool encrypt) 824 : pimpl(new ServerSocket::impl(name, uuid, type, encrypt)) 825{ 826 HILOGD("type:%{public}d encrypt:%{public}d", type, encrypt); 827} 828 829ServerSocket::~ServerSocket() 830{} 831 832int ServerSocket::Listen() 833{ 834 HILOGD("enter"); 835 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 836 return pimpl->Listen(); 837} 838 839std::shared_ptr<ClientSocket> ServerSocket::Accept(int timeout) 840{ 841 HILOGD("enter"); 842 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, nullptr, "pimpl is nullptr!"); 843 return pimpl->Accept(timeout); 844} 845 846void ServerSocket::Close() 847{ 848 HILOGD("enter"); 849 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is nullptr!"); 850 return pimpl->Close(); 851} 852 853const std::string &ServerSocket::GetStringTag() 854{ 855 HILOGD("enter"); 856 return pimpl->GetStringTag(); 857} 858 859int ServerSocket::GetL2capPsm() 860{ 861 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 862 HILOGI("psm:%{public}d", pimpl->socketChannel_.load()); 863 return pimpl->socketChannel_; 864} 865 866int ServerSocket::GetRfcommScn() 867{ 868 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 869 HILOGI("scn:%{public}d", pimpl->socketChannel_.load()); 870 return pimpl->socketChannel_; 871} 872 873uint32_t ServerSocket::GetMaxTransmitPacketSize() 874{ 875 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 876 HILOGI("MaxTransmitPacketSize:%{public}d", pimpl->maxTxPacketSize_.load()); 877 return pimpl->maxTxPacketSize_; 878} 879 880uint32_t ServerSocket::GetMaxReceivePacketSize() 881{ 882 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 883 HILOGI("MaxReceivePacketSize:%{public}d", pimpl->maxRxPacketSize_.load()); 884 return pimpl->maxRxPacketSize_; 885} 886 887int ServerSocket::GetSocketFd() 888{ 889 CHECK_AND_RETURN_LOG_RET(pimpl != nullptr, BT_ERR_DEVICE_DISCONNECTED, "pimpl is nullptr!"); 890 return pimpl->fd_; 891} 892 893std::shared_ptr<ClientSocket> SocketFactory::BuildInsecureRfcommDataSocketByServiceRecord( 894 const BluetoothRemoteDevice &device, const UUID &uuid) 895{ 896 HILOGD("enter"); 897 if (device.IsValidBluetoothRemoteDevice()) { 898 return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, false); 899 } else { 900 HILOGE("[sock] Device is not valid."); 901 return nullptr; 902 } 903} 904 905std::shared_ptr<ClientSocket> SocketFactory::BuildRfcommDataSocketByServiceRecord( 906 const BluetoothRemoteDevice &device, const UUID &uuid) 907{ 908 HILOGD("enter"); 909 if (device.IsValidBluetoothRemoteDevice()) { 910 return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, true); 911 } else { 912 HILOGE("[sock] Device is not valid."); 913 return nullptr; 914 } 915} 916 917std::shared_ptr<ServerSocket> SocketFactory::DataListenInsecureRfcommByServiceRecord( 918 const std::string &name, const UUID &uuid) 919{ 920 HILOGD("enter"); 921 return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, false); 922} 923 924std::shared_ptr<ServerSocket> SocketFactory::DataListenRfcommByServiceRecord(const std::string &name, const UUID &uuid) 925{ 926 HILOGD("enter"); 927 return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, true); 928} 929 930int ClientSocket::UpdateCocConnectionParams(CocUpdateSocketParam ¶m) 931{ 932 HILOGI("UpdateCocConnectionParams enter"); 933 BluetoothSocketCocInfo info; 934 935 info.addr = param.addr; 936 info.minInterval = param.minInterval; 937 info.maxInterval = param.maxInterval; 938 info.peripheralLatency = param.peripheralLatency; 939 info.supervisionTimeout = param.supervisionTimeout; 940 info.minConnEventLen = param.minConnEventLen; 941 info.maxConnEventLen = param.maxConnEventLen; 942 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET); 943 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "proxy is null"); 944 return proxy->UpdateCocConnectionParams(info); 945} 946} // namespace Bluetooth 947} // namespace OHOS