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