• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
40 namespace OHOS {
41 namespace Bluetooth {
42 const int LENGTH = 18;
43 const int MIN_BUFFER_SIZE_TO_SET = 4 * 1024; // 4KB
44 const int MAX_BUFFER_SIZE_TO_SET = 50 * 1024; // 50KB
45 const int ADDR_OFFSET = 1; // state(1)
46 const int TX_OFFSET = 7; // state(1)+addr(6)
47 const int RX_OFFSET = 9; // state(1)+addr(6)+tx(2)
48 const int SOCKET_RECV_ADDR_SIZE = 6;
49 const int SOCKET_RECV_TXRX_SIZE = 2;
50 const int SOCKET_RECV_CHANNEL_SIZE = 4;
51 const int SOCKET_RECV_FD_SIZE = 14;
52 const int SOCKET_RECV_FD_SIGNAL = 11; // state(1)+addr(6)+tx(2)+rx(2)
53 
54 constexpr char BLUETOOTH_UE_DOMAIN[] = "BLUETOOTH_UE";
55 std::mutex g_socketProxyMutex;
56 
57 #define WPTR_SOCKET_CBACK(cbWptr, func, ...)      \
58 do {                                            \
59     auto cbSptr = (cbWptr).lock();               \
60     if (cbSptr) {                                \
61         cbSptr->func(__VA_ARGS__);               \
62     } else {                                     \
63         HILOGE(#cbWptr ": callback is nullptr"); \
64     }                                            \
65 } while (0)
66 
ReportDataToRss(const std::string & action,int id,const std::string & address,int pid,int uid)67 static void ReportDataToRss(const std::string &action, int id, const std::string &address, int pid, int uid)
68 {
69 #ifdef RES_SCHED_SUPPORT
70     HILOGD("report SPP_CONNECT_STATE");
71     std::unordered_map<std::string, std::string> payload;
72     payload["ACTION"] = action;
73     payload["ID"] = std::to_string(id);
74     payload["ADDRESS"] = address;
75     payload["PID"] = std::to_string(pid);
76     payload["UID"] = std::to_string(uid);
77     ResourceSchedule::ResSchedClient::GetInstance().ReportData(
78         OHOS::ResourceSchedule::ResType::RES_TYPE_BT_SERVICE_EVENT,
79         OHOS::ResourceSchedule::ResType::BtServiceEvent::SPP_CONNECT_STATE,
80         payload);
81 #endif
82 }
83 
84 struct ClientSocket::impl {
85     impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth);
86     impl(int fd, std::string address, BtSocketType type);
87     impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth,
88         std::weak_ptr<BluetoothConnectionObserver> observer);
~implOHOS::Bluetooth::ClientSocket::impl89     ~impl()
90     {
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")))
CloseOHOS::Bluetooth::ClientSocket::impl108     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 
GetPacketSizeFromBufOHOS::Bluetooth::ClientSocket::impl144     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 
RecvSocketSignalOHOS::Bluetooth::ClientSocket::impl154     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 
getSecurityFlagsOHOS::Bluetooth::ClientSocket::impl171     int getSecurityFlags()
172     {
173         int flags = 0;
174         if (auth_) {
175             flags |= FLAG_AUTH;
176             flags |= FLAG_ENCRYPT;
177         }
178         return flags;
179     }
180 
GetInputStreamOHOS::Bluetooth::ClientSocket::impl181     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 
GetOutputStreamOHOS::Bluetooth::ClientSocket::impl190     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 
GetRemoteDeviceOHOS::Bluetooth::ClientSocket::impl199     BluetoothRemoteDevice &GetRemoteDevice()
200     {
201         HILOGD("enter");
202         return remoteDevice_;
203     }
204 
IsConnectedOHOS::Bluetooth::ClientSocket::impl205     bool IsConnected()
206     {
207         HILOGD("enter");
208         return socketStatus_ == SOCKET_CONNECTED;
209     }
210 
SetBufferSizeOHOS::Bluetooth::ClientSocket::impl211     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 
RecvSocketPsmOrScnOHOS::Bluetooth::ClientSocket::impl256     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::weak_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 
297 class ClientSocket::impl::BluetoothSocketObserverImp : public BluetoothClientSocketObserverStub {
298 public:
GetClientSocketSptr(void)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 
BluetoothSocketObserverImp(std::weak_ptr<ClientSocket> clientSocket)309     explicit BluetoothSocketObserverImp(std::weak_ptr<ClientSocket> clientSocket) : clientSocket_(clientSocket)
310     {
311         HILOGD("enter");
312     }
~BluetoothSocketObserverImp()313     ~BluetoothSocketObserverImp()
314     {
315         HILOGD("enter");
316     }
317 
318     __attribute__((no_sanitize("cfi")))
OnConnectionStateChanged(const CallbackParam & callbackParam)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             return;
329         }
330         if (!clientSptr->pimpl) {
331             HILOGE("impl is nullptr");
332             return;
333         }
334         CallbackConnectParam callbackConnectParam = {
335             .addr = device,
336             .uuid = btUuid,
337             .status = callbackParam.status,
338             .result = callbackParam.result,
339             .type = callbackParam.type,
340             .psm = callbackParam.psm,
341         };
342         WPTR_SOCKET_CBACK(clientSptr->pimpl->observer_, OnConnectionStateChanged, callbackConnectParam);
343     }
344 
345 private:
346     std::weak_ptr<ClientSocket> clientSocket_;
347 };
348 
Init(std::weak_ptr<ClientSocket> client)349 bool ClientSocket::impl::Init(std::weak_ptr<ClientSocket> client)
350 {
351     if (observerImp_ != nullptr) {
352         return true;
353     }
354     observerImp_ = new(std::nothrow) BluetoothSocketObserverImp(client);
355     if (observerImp_ == nullptr) {
356         return false;
357     }
358     return true;
359 }
360 
impl(const BluetoothRemoteDevice & addr,UUID uuid,BtSocketType type,bool auth)361 ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth)
362     : inputStream_(nullptr),
363       outputStream_(nullptr),
364       remoteDevice_(addr),
365       uuid_(uuid),
366       type_(type),
367       fd_(-1),
368       auth_(auth),
369       socketStatus_(SOCKET_INIT)
370 {
371     HILOGD("enter 4 parameters");
372 }
373 
impl(int fd,std::string address,BtSocketType type)374 ClientSocket::impl::impl(int fd, std::string address, BtSocketType type)
375     : inputStream_(std::make_unique<InputStream>(fd)),
376       outputStream_(std::make_unique<OutputStream>(fd)),
377       remoteDevice_(BluetoothRemoteDevice(address, 0)),
378       type_(type),
379       address_(address),
380       fd_(fd),
381       auth_(false),
382       socketStatus_(SOCKET_CONNECTED)
383 {
384     HILOGD("enter 3 parameters");
385 }
386 
impl(const BluetoothRemoteDevice & addr,UUID uuid,BtSocketType type,bool auth,std::weak_ptr<BluetoothConnectionObserver> observer)387 ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth,
388     std::weak_ptr<BluetoothConnectionObserver> observer)
389     : observer_(observer),
390       inputStream_(nullptr),
391       outputStream_(nullptr),
392       remoteDevice_(addr),
393       uuid_(uuid),
394       type_(type),
395       fd_(-1),
396       auth_(auth),
397       socketStatus_(SOCKET_INIT)
398 {
399     HILOGD("enter 5 parameters");
400 }
401 
ClientSocket(const BluetoothRemoteDevice & bda,UUID uuid,BtSocketType type,bool auth)402 ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth)
403     : pimpl(new ClientSocket::impl(bda, uuid, type, auth))
404 {}
405 
ClientSocket(int fd,std::string address,BtSocketType type)406 ClientSocket::ClientSocket(int fd, std::string address, BtSocketType type)
407     : pimpl(new ClientSocket::impl(fd, address, type))
408 {}
409 
ClientSocket(const BluetoothRemoteDevice & bda,UUID uuid,BtSocketType type,bool auth,std::weak_ptr<BluetoothConnectionObserver> observer)410 ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth,
411     std::weak_ptr<BluetoothConnectionObserver> observer)
412     : pimpl(new ClientSocket::impl(bda, uuid, type, auth, observer))
413 {}
414 
~ClientSocket()415 ClientSocket::~ClientSocket()
416 {}
417 
Init()418 bool ClientSocket::Init()
419 {
420     HILOGI("ClientSocket Init");
421     return pimpl->Init(weak_from_this());
422 }
423 
Connect(int psm)424 int ClientSocket::Connect(int psm)
425 {
426     HILOGD("enter");
427     if (pimpl->type_ == TYPE_L2CAP_LE) {
428         CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "BLE is not TURN_ON");
429     } else {
430         CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "BR is not TURN_ON");
431     }
432 
433     if (!pimpl->Init(weak_from_this())) {
434         HILOGE("clientSocket proxy is nullptr");
435         return BT_ERR_INTERNAL_ERROR;
436     }
437 
438     pimpl->address_ = pimpl->remoteDevice_.GetDeviceAddr();
439     std::string tempAddress = pimpl->address_;
440     CHECK_AND_RETURN_LOG_RET(tempAddress.size(), BtStatus::BT_FAILURE, "address size error");
441     CHECK_AND_RETURN_LOG_RET(pimpl->socketStatus_ != SOCKET_CLOSED, BT_ERR_INVALID_STATE, "socket closed");
442     sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
443     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "proxy is nullptr");
444 
445     bluetooth::Uuid tempUuid = bluetooth::Uuid::ConvertFrom128Bits(pimpl->uuid_.ConvertTo128Bits());
446     int ret = proxy->RegisterClientObserver(BluetoothRawAddress(pimpl->address_), tempUuid,
447         pimpl->observerImp_);
448     CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, ret, "regitser observer fail, ret = %d", ret);
449 
450     ConnectSocketParam param {
451         .addr = tempAddress,
452         .uuid = tempUuid,
453         .securityFlag = (int32_t)pimpl->getSecurityFlags(),
454         .type = (int32_t)pimpl->type_,
455         .psm = psm
456     };
457     ret = proxy->Connect(param, pimpl->fd_);
458     CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, ret, "Connect error %{public}d", ret);
459 
460     HILOGI("fd_: %{public}d", pimpl->fd_);
461     CHECK_AND_RETURN_LOG_RET(pimpl->fd_ != -1, BtStatus::BT_FAILURE, "connect failed!");
462     CHECK_AND_RETURN_LOG_RET(pimpl->RecvSocketPsmOrScn(), BT_ERR_INVALID_STATE, "recv psm or scn failed");
463 
464     bool recvret = pimpl->RecvSocketSignal();
465     HILOGI("recvret: %{public}d", recvret);
466     pimpl->inputStream_ = std::make_unique<InputStream>(pimpl->fd_);
467     pimpl->outputStream_ = std::make_unique<OutputStream>(pimpl->fd_);
468     CHECK_AND_RETURN_LOG_RET(recvret, BtStatus::BT_FAILURE, "recvSocketSignal connect failed!");
469     pimpl->socketStatus_ = SOCKET_CONNECTED;
470     HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
471         HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", pimpl->fd_, "ADDRESS",
472         GetEncryptAddr(tempAddress), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
473     ReportDataToRss("connect", pimpl->fd_, GetEncryptAddr(tempAddress), IPCSkeleton::GetCallingPid(),
474         IPCSkeleton::GetCallingUid());
475     return BtStatus::BT_SUCCESS;
476 }
477 
Close()478 void ClientSocket::Close()
479 {
480     HILOGD("enter");
481     return pimpl->Close();
482 }
483 
GetInputStream()484 std::shared_ptr<InputStream> ClientSocket::GetInputStream()
485 {
486     HILOGD("enter");
487     return pimpl->GetInputStream();
488 }
489 
GetOutputStream()490 std::shared_ptr<OutputStream> ClientSocket::GetOutputStream()
491 {
492     HILOGD("enter");
493     return pimpl->GetOutputStream();
494 }
495 
GetRemoteDevice()496 BluetoothRemoteDevice &ClientSocket::GetRemoteDevice()
497 {
498     HILOGD("enter");
499     return pimpl->GetRemoteDevice();
500 }
501 
IsConnected() const502 bool ClientSocket::IsConnected() const
503 {
504     HILOGD("enter");
505     return pimpl->IsConnected();
506 }
507 
SetBufferSize(int bufferSize)508 int ClientSocket::SetBufferSize(int bufferSize)
509 {
510     HILOGD("enter");
511     return pimpl->SetBufferSize(bufferSize);
512 }
513 
GetSocketFd()514 int ClientSocket::GetSocketFd()
515 {
516     HILOGD("enter");
517     return pimpl->fd_;
518 }
519 
GetL2capPsm()520 int ClientSocket::GetL2capPsm()
521 {
522     HILOGI("psm:%{public}d", pimpl->socketChannel_.load());
523     return pimpl->socketChannel_;
524 }
525 
GetRfcommScn()526 int ClientSocket::GetRfcommScn()
527 {
528     HILOGI("scn:%{public}d", pimpl->socketChannel_.load());
529     return pimpl->socketChannel_;
530 }
531 
GetMaxTransmitPacketSize()532 uint32_t ClientSocket::GetMaxTransmitPacketSize()
533 {
534     HILOGI("MaxTransmitPacketSize:%{public}d", pimpl->maxTxPacketSize_.load());
535     return pimpl->maxTxPacketSize_;
536 }
537 
GetMaxReceivePacketSize()538 uint32_t ClientSocket::GetMaxReceivePacketSize()
539 {
540     HILOGI("MaxReceivePacketSize:%{public}d", pimpl->maxRxPacketSize_.load());
541     return pimpl->maxRxPacketSize_;
542 }
543 
544 struct ServerSocket::impl {
545     impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt);
~implOHOS::Bluetooth::ServerSocket::impl546     ~impl()
547     {
548         if (fd_ > 0) {
549             shutdown(fd_, SHUT_RD);
550             shutdown(fd_, SHUT_WR);
551             close(fd_);
552             HILOGI("fd closed, fd_: %{public}d", fd_);
553             fd_ = -1;
554         }
555     }
556 
ListenOHOS::Bluetooth::ServerSocket::impl557     int Listen()
558     {
559         HILOGD("enter");
560         if (type_ == TYPE_L2CAP_LE) {
561             CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "BLE is not TURN_ON");
562         } else {
563             CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "BR is not TURN_ON");
564         }
565 
566         sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
567         if (!proxy) {
568             HILOGE("failed, proxy is nullptr");
569             socketStatus_ = SOCKET_CLOSED;
570             return BT_ERR_SERVICE_DISCONNECTED;
571         }
572         CHECK_AND_RETURN_LOG_RET(socketStatus_ != SOCKET_CLOSED, BT_ERR_INVALID_STATE,
573             "failed, socketStatus_ is SOCKET_CLOSED");
574 
575         ListenSocketParam param {
576             .name = name_,
577             .uuid = bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits()),
578             .securityFlag = (int32_t)getSecurityFlags(),
579             .type = (int32_t)type_,
580             .observer = observer_
581         };
582         int ret = proxy->Listen(param, fd_);
583         if (ret != BT_NO_ERROR) {
584             HILOGE("Listen error %{public}d.", ret);
585             socketStatus_ = SOCKET_CLOSED;
586             return ret;
587         }
588 
589         if (fd_ == BT_INVALID_SOCKET_FD) {
590             HILOGE("listen socket failed");
591             socketStatus_ = SOCKET_CLOSED;
592             return BT_ERR_INVALID_STATE;
593         }
594 
595         CHECK_AND_RETURN_LOG_RET(RecvSocketPsmOrScn(), BT_ERR_INVALID_STATE, "recv psm or scn failed");
596 
597         if (socketStatus_ == SOCKET_INIT) {
598             socketStatus_ = SOCKET_LISTENING;
599         } else {
600             HILOGE("failed, socketStatus_: %{public}d is not SOCKET_INIT", socketStatus_);
601             close(fd_);
602             socketStatus_ = SOCKET_CLOSED;
603             return BT_ERR_INVALID_STATE;
604         }
605 
606         return BT_NO_ERROR;
607     }
608 
getSecurityFlagsOHOS::Bluetooth::ServerSocket::impl609     int getSecurityFlags()
610     {
611         int flags = 0;
612         if (encrypt_) {
613             flags |= FLAG_AUTH;
614             flags |= FLAG_ENCRYPT;
615         }
616         return flags;
617     }
618 
AcceptOHOS::Bluetooth::ServerSocket::impl619     std::shared_ptr<ClientSocket> Accept(int timeout)
620     {
621         HILOGD("enter");
622         if (socketStatus_ != SOCKET_LISTENING) {
623             HILOGE("socket is not in listen state");
624             return nullptr;
625         }
626         struct timeval time = {timeout, 0};
627         setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
628         setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
629 
630         acceptFd_ = RecvSocketFd();
631         HILOGI("RecvSocketFd acceptFd: %{public}d", acceptFd_);
632         if (acceptFd_ <= 0) {
633             return nullptr;
634         }
635         if (timeout > 0) {
636             time = {0, 0};
637             setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
638             setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
639         }
640 
641         std::shared_ptr<ClientSocket> clientSocket = std::make_shared<ClientSocket>(acceptFd_, acceptAddress_, type_);
642 
643         HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
644             HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", acceptFd_, "ADDRESS",
645             GetEncryptAddr(acceptAddress_), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
646         ReportDataToRss("connect", acceptFd_, GetEncryptAddr(acceptAddress_), IPCSkeleton::GetCallingPid(),
647             IPCSkeleton::GetCallingUid());
648         return clientSocket;
649     }
650 
RecvSocketFdOHOS::Bluetooth::ServerSocket::impl651     int RecvSocketFd()
652     {
653         HILOGD("enter");
654         char ccmsg[CMSG_SPACE(sizeof(int))];
655         char buffer[SOCKET_RECV_FD_SIZE];
656         struct iovec io = {.iov_base = buffer, .iov_len = sizeof(buffer)};
657         struct msghdr msg;
658         (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
659         msg.msg_control = ccmsg;
660         msg.msg_controllen = sizeof(ccmsg);
661         msg.msg_iov = &io;
662         msg.msg_iovlen = 1;
663 
664 #ifdef DARWIN_PLATFORM
665         int rv = recvmsg(fd_, &msg, 0);
666 #else
667         int rv = recvmsg(fd_, &msg, MSG_NOSIGNAL);
668 #endif
669         if (rv == -1) {
670             HILOGE("[sock] recvmsg error  %{public}d, fd: %{public}d", errno, fd_);
671             return BtStatus::BT_FAILURE;
672         }
673         struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg);
674         CHECK_AND_RETURN_LOG_RET(cmptr != nullptr, BtStatus::BT_FAILURE, "cmptr error");
675         CHECK_AND_RETURN_LOG_RET(cmptr->cmsg_len == CMSG_LEN(sizeof(int)) && cmptr->cmsg_level == SOL_SOCKET
676             && cmptr->cmsg_type == SCM_RIGHTS, BtStatus::BT_FAILURE,
677             "recvmsg error, len:%{public}d level:%{public}d type:%{public}d",
678             cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);
679         int clientFd = *(reinterpret_cast<int *>(CMSG_DATA(cmptr)));
680 
681         uint8_t recvBuf[rv];
682         (void)memset_s(&recvBuf, sizeof(recvBuf), 0, sizeof(recvBuf));
683         CHECK_AND_RETURN_LOG_RET(memcpy_s(recvBuf, sizeof(recvBuf), (uint8_t *)msg.msg_iov[0].iov_base, rv) == EOK,
684             BtStatus::BT_FAILURE, "RecvSocketFd, recvBuf memcpy_s fail");
685 
686         uint8_t buf[SOCKET_RECV_ADDR_SIZE] = {0};
687         CHECK_AND_RETURN_LOG_RET(memcpy_s(buf, sizeof(buf), &recvBuf[ADDR_OFFSET], sizeof(buf)) == EOK,
688             BtStatus::BT_FAILURE, "RecvSocketFd, buf memcpy_s fail");
689 
690         char token[LENGTH] = {0};
691         (void)sprintf_s(token, sizeof(token), "%02X:%02X:%02X:%02X:%02X:%02X",
692             buf[0x05], buf[0x04], buf[0x03], buf[0x02], buf[0x01], buf[0x00]);
693         BluetoothRawAddress rawAddr {token};
694         acceptAddress_ = rawAddr.GetAddress().c_str();
695 
696         maxTxPacketSize_ = GetPacketSizeFromBuf(recvBuf + TX_OFFSET, rv - TX_OFFSET);
697         maxRxPacketSize_ = GetPacketSizeFromBuf(recvBuf + RX_OFFSET, rv - RX_OFFSET);
698         return clientFd;
699     }
700 
GetPacketSizeFromBufOHOS::Bluetooth::ServerSocket::impl701     uint16_t GetPacketSizeFromBuf(uint8_t recvBuf[], int recvBufLen)
702     {
703         uint16_t shortBuf;
704         CHECK_AND_RETURN_LOG_RET(recvBuf, 0, "getpacketsize fail, invalid recvBuf");
705         CHECK_AND_RETURN_LOG_RET(recvBufLen >= SOCKET_RECV_TXRX_SIZE, 0, "getpacketsize fail, invalid recvBufLen");
706         CHECK_AND_RETURN_LOG_RET(memcpy_s(&shortBuf, sizeof(shortBuf), &recvBuf[0], sizeof(shortBuf)) == EOK, 0,
707             "getpacketsize failed, memcpy_s fail");
708         return shortBuf;
709     }
710 
RecvSocketPsmOrScnOHOS::Bluetooth::ServerSocket::impl711     bool RecvSocketPsmOrScn()
712     {
713         int channel = 0;
714 #ifdef DARWIN_PLATFORM
715         int recvBufSize = recv(fd_, &channel, sizeof(channel), 0);
716 #else
717         int recvBufSize = recv(fd_, &channel, sizeof(channel), MSG_WAITALL);
718 #endif
719         CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_CHANNEL_SIZE, false,
720             "recv psm or scn error, errno:%{public}d, fd_:%{public}d", errno, fd_);
721         CHECK_AND_RETURN_LOG_RET(channel > 0, false,
722             "recv channel error, errno:%{public}d, fd_:%{public}d", errno, fd_);
723         HILOGI("psm or scn = %{public}d, type = %{public}d", channel, type_);
724         socketChannel_ = channel;
725         return true;
726     }
727 
CloseOHOS::Bluetooth::ServerSocket::impl728     void Close()
729     {
730         HILOGD("enter");
731         if (socketStatus_ == SOCKET_CLOSED) {
732             HILOGD("The socketStatus_ is already SOCKET_CLOSED");
733             return;
734         } else {
735             socketStatus_ = SOCKET_CLOSED;
736             if (fd_ > 0) {
737                 shutdown(fd_, SHUT_RD);
738                 shutdown(fd_, SHUT_WR);
739                 HILOGI("fd closed, fd_: %{public}d", fd_);
740                 close(fd_);
741                 fd_ = -1;
742                 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
743                 CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
744                 proxy->DeregisterServerObserver(observer_);
745                 return;
746             } else {
747                 HILOGE("socket not created");
748                 return;
749             }
750         }
751     }
752 
GetStringTagOHOS::Bluetooth::ServerSocket::impl753     const std::string &GetStringTag()
754     {
755         HILOGD("enter");
756         if (socketStatus_ == SOCKET_CLOSED) {
757             HILOGE("socketStatus_ is SOCKET_CLOSED");
758             socketServiceType_ = "";
759         } else {
760             socketServiceType_ = "ServerSocket:";
761             socketServiceType_.append(" Type: ").append(ConvertTypeToString(type_))
762                 .append(" ServerName: ").append(name_);
763         }
764         return socketServiceType_;
765     }
766 
ConvertTypeToStringOHOS::Bluetooth::ServerSocket::impl767     static std::string ConvertTypeToString(BtSocketType type)
768     {
769         std::string retStr;
770         if (type == TYPE_RFCOMM) {
771             retStr = "TYPE_RFCOMM";
772         } else if (type == TYPE_L2CAP) {
773             retStr = "TYPE_L2CAP";
774         } else if (type == TYPE_L2CAP_LE) {
775             retStr = "TYPE_L2CAP_LE";
776         } else {
777             retStr = "TYPE_UNKNOW";
778         }
779         return retStr;
780     }
781 
782     sptr<BluetoothServerSocketObserverStub> observer_ = nullptr;
783 
784     sptr<IBluetoothSocket> proxy;
785     UUID uuid_;
786     BtSocketType type_;
787     bool encrypt_;
788     int fd_;
789     int socketStatus_;
790     std::string name_ {
791         ""
792         };
793     int acceptFd_ = 0;
794     std::string acceptAddress_;
795     std::string socketServiceType_ {
796         ""
797     };
798     std::atomic<int> socketChannel_{ -1 };
799     std::atomic<uint32_t> maxTxPacketSize_{ 0 };
800     std::atomic<uint32_t> maxRxPacketSize_{ 0 };
801 };
802 
impl(const std::string & name,UUID uuid,BtSocketType type,bool encrypt)803 ServerSocket::impl::impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt)
804     : uuid_(uuid), type_(type), encrypt_(encrypt), fd_(-1), socketStatus_(SOCKET_INIT), name_(name)
805 {
806     HILOGD("(4 parameters) starts");
807     observer_ = new BluetoothServerSocketObserverStub();
808 }
809 
ServerSocket(const std::string & name,UUID uuid,BtSocketType type,bool encrypt)810 ServerSocket::ServerSocket(const std::string &name, UUID uuid, BtSocketType type, bool encrypt)
811     : pimpl(new ServerSocket::impl(name, uuid, type, encrypt))
812 {
813     HILOGD("type:%{public}d encrypt:%{public}d", type, encrypt);
814 }
815 
~ServerSocket()816 ServerSocket::~ServerSocket()
817 {}
818 
Listen()819 int ServerSocket::Listen()
820 {
821     HILOGD("enter");
822     return pimpl->Listen();
823 }
824 
Accept(int timeout)825 std::shared_ptr<ClientSocket> ServerSocket::Accept(int timeout)
826 {
827     HILOGD("enter");
828     return pimpl->Accept(timeout);
829 }
830 
Close()831 void ServerSocket::Close()
832 {
833     HILOGD("enter");
834     return pimpl->Close();
835 }
836 
GetStringTag()837 const std::string &ServerSocket::GetStringTag()
838 {
839     HILOGD("enter");
840     return pimpl->GetStringTag();
841 }
842 
GetL2capPsm()843 int ServerSocket::GetL2capPsm()
844 {
845     HILOGI("psm:%{public}d", pimpl->socketChannel_.load());
846     return pimpl->socketChannel_;
847 }
848 
GetRfcommScn()849 int ServerSocket::GetRfcommScn()
850 {
851     HILOGI("scn:%{public}d", pimpl->socketChannel_.load());
852     return pimpl->socketChannel_;
853 }
854 
GetMaxTransmitPacketSize()855 uint32_t ServerSocket::GetMaxTransmitPacketSize()
856 {
857     HILOGI("MaxTransmitPacketSize:%{public}d", pimpl->maxTxPacketSize_.load());
858     return pimpl->maxTxPacketSize_;
859 }
860 
GetMaxReceivePacketSize()861 uint32_t ServerSocket::GetMaxReceivePacketSize()
862 {
863     HILOGI("MaxReceivePacketSize:%{public}d", pimpl->maxRxPacketSize_.load());
864     return pimpl->maxRxPacketSize_;
865 }
866 
GetSocketFd()867 int ServerSocket::GetSocketFd()
868 {
869     return pimpl->fd_;
870 }
871 
BuildInsecureRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)872 std::shared_ptr<ClientSocket> SocketFactory::BuildInsecureRfcommDataSocketByServiceRecord(
873     const BluetoothRemoteDevice &device, const UUID &uuid)
874 {
875     HILOGD("enter");
876     if (device.IsValidBluetoothRemoteDevice()) {
877         return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, false);
878     } else {
879         HILOGE("[sock] Device is not valid.");
880         return nullptr;
881     }
882 }
883 
BuildRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)884 std::shared_ptr<ClientSocket> SocketFactory::BuildRfcommDataSocketByServiceRecord(
885     const BluetoothRemoteDevice &device, const UUID &uuid)
886 {
887     HILOGD("enter");
888     if (device.IsValidBluetoothRemoteDevice()) {
889         return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, true);
890     } else {
891         HILOGE("[sock] Device is not valid.");
892         return nullptr;
893     }
894 }
895 
DataListenInsecureRfcommByServiceRecord(const std::string & name,const UUID & uuid)896 std::shared_ptr<ServerSocket> SocketFactory::DataListenInsecureRfcommByServiceRecord(
897     const std::string &name, const UUID &uuid)
898 {
899     HILOGD("enter");
900     return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, false);
901 }
902 
DataListenRfcommByServiceRecord(const std::string & name,const UUID & uuid)903 std::shared_ptr<ServerSocket> SocketFactory::DataListenRfcommByServiceRecord(const std::string &name, const UUID &uuid)
904 {
905     HILOGD("enter");
906     return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, true);
907 }
908 
UpdateCocConnectionParams(CocUpdateSocketParam & param)909 int ClientSocket::UpdateCocConnectionParams(CocUpdateSocketParam &param)
910 {
911     HILOGI("UpdateCocConnectionParams enter");
912     BluetoothSocketCocInfo info;
913 
914     info.addr = param.addr;
915     info.minInterval = param.minInterval;
916     info.maxInterval = param.maxInterval;
917     info.peripheralLatency = param.peripheralLatency;
918     info.supervisionTimeout = param.supervisionTimeout;
919     info.minConnEventLen = param.minConnEventLen;
920     info.maxConnEventLen = param.maxConnEventLen;
921     sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
922     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "proxy is null");
923     return proxy->UpdateCocConnectionParams(info);
924 }
925 }  // namespace Bluetooth
926 }  // namespace OHOS