• 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 #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 SPTR_SOCKET_CBACK(cbSptr, func, ...)      \
61 do {                                            \
62     if (cbSptr) {                                \
63         cbSptr->func(__VA_ARGS__);               \
64     } else {                                     \
65         HILOGE(#cbSptr ": callback is nullptr"); \
66     }                                            \
67 } while (0)
68 
ReportDataToRss(const std::string & action,int id,const std::string & address,int pid,int uid)69 static void ReportDataToRss(const std::string &action, int id, const std::string &address, int pid, int uid)
70 {
71 #ifdef RES_SCHED_SUPPORT
72     HILOGD("report SPP_CONNECT_STATE");
73     std::unordered_map<std::string, std::string> payload;
74     payload["ACTION"] = action;
75     payload["ID"] = std::to_string(id);
76     payload["ADDRESS"] = address;
77     payload["PID"] = std::to_string(pid);
78     payload["UID"] = std::to_string(uid);
79     ResourceSchedule::ResSchedClient::GetInstance().ReportData(
80         OHOS::ResourceSchedule::ResType::RES_TYPE_BT_SERVICE_EVENT,
81         OHOS::ResourceSchedule::ResType::BtServiceEvent::SPP_CONNECT_STATE,
82         payload);
83 #endif
84 }
85 
86 struct ClientSocket::impl {
87     impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth);
88     impl(int fd, std::string address, BtSocketType type);
89     impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth,
90         std::shared_ptr<BluetoothConnectionObserver> observer);
~implOHOS::Bluetooth::ClientSocket::impl91     ~impl()
92     {
93         if (fd_ > 0) {
94             shutdown(fd_, SHUT_RD);
95             shutdown(fd_, SHUT_WR);
96             HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
97                 HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty",
98                 "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
99             HiSysEventWrite(BLUETOOTH_UE_DOMAIN, "SOCKET_DISCONN", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
100                 "PNAMEID", "Bluetooth", "PVERSIONID", "1.0", "DEV_ADDRESS", GetEncryptAddr(address_),
101                 "SCENE_CODE", fd_);
102             ReportDataToRss("close", fd_, "empty", IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
103             HILOGI("fd closed, fd_: %{public}d", fd_);
104             close(fd_);
105             fd_ = -1;
106         }
107     }
108 
109     __attribute__((no_sanitize("cfi")))
CloseOHOS::Bluetooth::ClientSocket::impl110     void Close()
111     {
112         HILOGD("enter");
113         if (socketStatus_ == SOCKET_CLOSED) {
114             HILOGD("The socketStatus_ is already SOCKET_CLOSED");
115             return;
116         } else {
117             socketStatus_ = SOCKET_CLOSED;
118             if (fd_ > 0) {
119                 shutdown(fd_, SHUT_RD);
120                 shutdown(fd_, SHUT_WR);
121                 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
122                     HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "close", "ID", fd_, "ADDRESS", "empty",
123                     "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
124                 HiSysEventWrite(BLUETOOTH_UE_DOMAIN, "SOCKET_DISCONN", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
125                     "PNAMEID", "Bluetooth", "PVERSIONID", "1.0", "DEV_ADDRESS", GetEncryptAddr(address_),
126                     "SCENE_CODE", fd_);
127                 ReportDataToRss("close", fd_, "empty", IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
128                 HILOGI("fd closed, fd_: %{public}d", fd_);
129                 close(fd_);
130                 fd_ = -1;
131             } else {
132                 HILOGE("socket not created");
133             }
134             sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
135             CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
136             bluetooth::Uuid tempUuid = bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits());
137             if (!observerImp_) {
138                 HILOGD("observerImp_ is nullptr");
139                 return;
140             }
141             proxy->DeregisterClientObserver(BluetoothRawAddress(remoteDevice_.GetDeviceAddr()), tempUuid,
142                 observerImp_);
143         }
144     }
145 
GetPacketSizeFromBufOHOS::Bluetooth::ClientSocket::impl146     uint16_t GetPacketSizeFromBuf(const uint8_t recvBuf[], int recvBufLen) const
147     {
148         uint16_t shortBuf;
149         CHECK_AND_RETURN_LOG_RET(recvBuf, 0, "getpacketsize fail, invalid recvBuf");
150         CHECK_AND_RETURN_LOG_RET(recvBufLen >= SOCKET_RECV_TXRX_SIZE, 0, "getpacketsize fail, invalid recvBufLen");
151         CHECK_AND_RETURN_LOG_RET(memcpy_s(&shortBuf, sizeof(shortBuf), &recvBuf[0], sizeof(shortBuf)) == EOK, 0,
152             "getpacketsize failed, memcpy_s fail");
153         return shortBuf;
154     }
155 
RecvSocketSignalOHOS::Bluetooth::ClientSocket::impl156     bool RecvSocketSignal()
157     {
158         uint8_t signalBuf[SOCKET_RECV_FD_SIGNAL] = {0};
159 #ifdef DARWIN_PLATFORM
160         int recvBufSize = recv(fd_, signalBuf, sizeof(signalBuf), 0);
161 #else
162         int recvBufSize = recv(fd_, signalBuf, sizeof(signalBuf), MSG_WAITALL);
163 #endif
164         CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_FD_SIGNAL, false, "recv signal error, service closed");
165         bool state = signalBuf[0];
166         // remote addr has been obtained, no need obtain again
167         maxTxPacketSize_ = GetPacketSizeFromBuf(signalBuf + TX_OFFSET, SOCKET_RECV_FD_SIGNAL - TX_OFFSET);
168         maxRxPacketSize_ = GetPacketSizeFromBuf(signalBuf + RX_OFFSET, SOCKET_RECV_FD_SIGNAL - RX_OFFSET);
169 
170         return state;
171     }
172 
getSecurityFlagsOHOS::Bluetooth::ClientSocket::impl173     int getSecurityFlags()
174     {
175         int flags = 0;
176         if (auth_) {
177             flags |= FLAG_AUTH;
178             flags |= FLAG_ENCRYPT;
179         }
180         return flags;
181     }
182 
GetInputStreamOHOS::Bluetooth::ClientSocket::impl183     std::shared_ptr<InputStream> GetInputStream()
184     {
185         HILOGD("enter");
186         if (inputStream_ == nullptr) {
187             HILOGE("inputStream is NULL, failed. please Connect");
188         }
189         return inputStream_;
190     }
191 
GetOutputStreamOHOS::Bluetooth::ClientSocket::impl192     std::shared_ptr<OutputStream> GetOutputStream()
193     {
194         HILOGD("enter");
195         if (outputStream_ == nullptr) {
196             HILOGE("outputStream is NULL, failed. please Connect");
197         }
198         return outputStream_;
199     }
200 
GetRemoteDeviceOHOS::Bluetooth::ClientSocket::impl201     BluetoothRemoteDevice &GetRemoteDevice()
202     {
203         HILOGD("enter");
204         return remoteDevice_;
205     }
206 
IsConnectedOHOS::Bluetooth::ClientSocket::impl207     bool IsConnected()
208     {
209         HILOGD("enter");
210         return socketStatus_ == SOCKET_CONNECTED;
211     }
212 
SetBufferSizeOHOS::Bluetooth::ClientSocket::impl213     int SetBufferSize(int bufferSize)
214     {
215         HILOGI("SetBufferSize bufferSize is %{public}d.", bufferSize);
216         if (bufferSize < MIN_BUFFER_SIZE_TO_SET || bufferSize > MAX_BUFFER_SIZE_TO_SET) {
217             HILOGE("SetBufferSize param is invalid.");
218             return RET_BAD_PARAM;
219         }
220 
221         if (fd_ <= 0) {
222             HILOGE("SetBufferSize socket fd invalid.");
223             return RET_BAD_STATUS;
224         }
225 
226         const std::pair<const char*, int> sockOpts[] = {
227             {"recvBuffer", SO_RCVBUF},
228             {"sendBuffer", SO_SNDBUF},
229         };
230         for (auto opt : sockOpts) {
231             int curSize = 0;
232             socklen_t optlen = sizeof(curSize);
233             if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) {
234                 HILOGE("SetBufferSize getsockopt %{public}s failed.", opt.first);
235                 return RET_BAD_STATUS;
236             }
237             HILOGI("SetBufferSize %{public}s before set size is %{public}d.", opt.first, curSize);
238 
239             if (curSize != bufferSize) {
240                 int setSize = bufferSize / 2;
241                 if (setsockopt(fd_, SOL_SOCKET, opt.second, &setSize, sizeof(setSize)) != 0) {
242                     HILOGE("SetBufferSize setsockopt  %{public}s failed.", opt.first);
243                     return RET_BAD_STATUS;
244                 }
245 
246                 curSize = 0;
247                 if (getsockopt(fd_, SOL_SOCKET, opt.second, &curSize, &optlen) != 0) {
248                     HILOGE("SetBufferSize after getsockopt %{public}s failed.", opt.first);
249                     return RET_BAD_STATUS;
250                 }
251                 HILOGI("SetBufferSize %{public}s after set size is %{public}d.", opt.first, curSize);
252             }
253         }
254 
255         return RET_NO_ERROR;
256     }
257 
RecvSocketPsmOrScnOHOS::Bluetooth::ClientSocket::impl258     bool RecvSocketPsmOrScn()
259     {
260         int channel = 0;
261 #ifdef DARWIN_PLATFORM
262         int recvBufSize = recv(fd_, &channel, sizeof(channel), 0);
263 #else
264         int recvBufSize = recv(fd_, &channel, sizeof(channel), MSG_WAITALL);
265 #endif
266         CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_CHANNEL_SIZE, false,
267             "recv psm or scn error, errno:%{public}d, fd_:%{public}d", errno, fd_);
268         CHECK_AND_RETURN_LOG_RET(channel > 0, false, "recv channel error, invalid channel:%{public}d", channel);
269         HILOGI("psm or scn = %{public}d, type = %{public}d", channel, type_);
270         socketChannel_ = channel;
271         return true;
272     }
273 
274     // user register observer
275     std::shared_ptr<BluetoothConnectionObserver> observer_;
276     class BluetoothSocketObserverImp;
277 
278     // socket observer
279     sptr<BluetoothSocketObserverImp> observerImp_ = nullptr;
280     std::shared_ptr<InputStream> inputStream_ {
281         nullptr
282     };
283     std::shared_ptr<OutputStream> outputStream_ {
284         nullptr
285     };
286     bool Init(std::weak_ptr<ClientSocket> client);
287     BluetoothRemoteDevice remoteDevice_;
288     UUID uuid_;
289     BtSocketType type_;
290     std::string address_;
291     int fd_;
292     bool auth_;
293     int socketStatus_;
294     std::atomic<int> socketChannel_{ -1 };
295     std::atomic<uint32_t> maxTxPacketSize_{ 0 };
296     std::atomic<uint32_t> maxRxPacketSize_{ 0 };
297 };
298 
299 class ClientSocket::impl::BluetoothSocketObserverImp : public BluetoothClientSocketObserverStub {
300 public:
GetClientSocketSptr(void)301     inline std::shared_ptr<ClientSocket> GetClientSocketSptr(void)
302     {
303         auto clientSptr = clientSocket_.lock();
304         if (!clientSptr) {
305             HILOGE("clientSocket_ is nullptr");
306             return nullptr;
307         }
308         return clientSptr;
309     }
310 
BluetoothSocketObserverImp(std::weak_ptr<ClientSocket> clientSocket)311     explicit BluetoothSocketObserverImp(std::weak_ptr<ClientSocket> clientSocket) : clientSocket_(clientSocket)
312     {
313         HILOGD("enter");
314     }
~BluetoothSocketObserverImp()315     ~BluetoothSocketObserverImp()
316     {
317         HILOGD("enter");
318     }
319 
320     __attribute__((no_sanitize("cfi")))
OnConnectionStateChanged(const CallbackParam & callbackParam)321     void OnConnectionStateChanged(const CallbackParam &callbackParam) override
322     {
323         HILOGD("dev: %{public}s, uuid:%{public}s, status: %{public}d, psm: %{public}d, result: %{public}d",
324             GetEncryptAddr((callbackParam.dev).GetAddress()).c_str(), callbackParam.uuid.ToString().c_str(),
325             callbackParam.status, callbackParam.psm, callbackParam.result);
326         BluetoothRemoteDevice device(callbackParam.dev.GetAddress(), BTTransport::ADAPTER_BREDR);
327         UUID btUuid = UUID::ConvertFrom128Bits(callbackParam.uuid.ConvertTo128Bits());
328         auto clientSptr = GetClientSocketSptr();
329         if (!clientSptr) {
330             HILOGE("clientSptr is nullptr");
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         SPTR_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::shared_ptr<BluetoothConnectionObserver> observer)390 ClientSocket::impl::impl(const BluetoothRemoteDevice &addr, UUID uuid, BtSocketType type, bool auth,
391     std::shared_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::shared_ptr<BluetoothConnectionObserver> observer)413 ClientSocket::ClientSocket(const BluetoothRemoteDevice &bda, UUID uuid, BtSocketType type, bool auth,
414     std::shared_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_SPP_CONNECT_FAILED, "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 
IsAllowSocketConnect(int socketType)547 bool ClientSocket::IsAllowSocketConnect(int socketType)
548 {
549     HILOGI("socketType: %{public}d", socketType);
550     sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
551     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, true, "proxy is nullptr");
552     bool isAllowed = true;
553     int ret = proxy->IsAllowSocketConnect(socketType, pimpl->remoteDevice_.GetDeviceAddr(), isAllowed);
554     CHECK_AND_RETURN_LOG_RET(ret == BT_NO_ERROR, true, "check if socket allowed failed, error: %{public}d", ret);
555     return isAllowed;
556 }
557 
558 struct ServerSocket::impl {
559     impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt, int psm);
~implOHOS::Bluetooth::ServerSocket::impl560     ~impl()
561     {
562         if (fd_ > 0) {
563             shutdown(fd_, SHUT_RD);
564             shutdown(fd_, SHUT_WR);
565             close(fd_);
566             HILOGI("fd closed, fd_: %{public}d", fd_);
567             fd_ = -1;
568         }
569     }
570 
ListenOHOS::Bluetooth::ServerSocket::impl571     int Listen()
572     {
573         HILOGD("enter");
574         if (type_ == TYPE_L2CAP_LE) {
575             CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "BLE is not TURN_ON");
576         } else {
577             CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "BR is not TURN_ON");
578         }
579 
580         sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
581         if (!proxy) {
582             HILOGE("failed, proxy is nullptr");
583             socketStatus_ = SOCKET_CLOSED;
584             return BT_ERR_SERVICE_DISCONNECTED;
585         }
586         CHECK_AND_RETURN_LOG_RET(socketStatus_ != SOCKET_CLOSED, BT_ERR_INVALID_STATE,
587             "failed, socketStatus_ is SOCKET_CLOSED");
588 
589         ListenSocketParam param {
590             .name = name_,
591             .uuid = bluetooth::Uuid::ConvertFrom128Bits(uuid_.ConvertTo128Bits()),
592             .securityFlag = (int32_t)getSecurityFlags(),
593             .type = (int32_t)type_,
594             .observer = observer_,
595             .psm = psm_
596         };
597         int ret = proxy->Listen(param, fd_);
598         if (ret != BT_NO_ERROR) {
599             HILOGE("Listen error %{public}d.", ret);
600             socketStatus_ = SOCKET_CLOSED;
601             return ret;
602         }
603 
604         if (fd_ == BT_INVALID_SOCKET_FD) {
605             HILOGE("listen socket failed");
606             socketStatus_ = SOCKET_CLOSED;
607             return BT_ERR_INVALID_STATE;
608         }
609 
610         CHECK_AND_RETURN_LOG_RET(RecvSocketPsmOrScn(), BT_ERR_INVALID_STATE, "recv psm or scn failed");
611 
612         if (socketStatus_ == SOCKET_INIT) {
613             socketStatus_ = SOCKET_LISTENING;
614         } else {
615             HILOGE("failed, socketStatus_: %{public}d is not SOCKET_INIT", socketStatus_);
616             close(fd_);
617             socketStatus_ = SOCKET_CLOSED;
618             return BT_ERR_INVALID_STATE;
619         }
620 
621         return BT_NO_ERROR;
622     }
623 
getSecurityFlagsOHOS::Bluetooth::ServerSocket::impl624     int getSecurityFlags()
625     {
626         int flags = 0;
627         if (encrypt_) {
628             flags |= FLAG_AUTH;
629             flags |= FLAG_ENCRYPT;
630         }
631         return flags;
632     }
633 
AcceptOHOS::Bluetooth::ServerSocket::impl634     std::shared_ptr<ClientSocket> Accept(int timeout)
635     {
636         HILOGD("enter");
637         if (socketStatus_ != SOCKET_LISTENING) {
638             HILOGE("socket is not in listen state");
639             return nullptr;
640         }
641         // If timeout < 0, keeps waiting in blocking mode
642         if (timeout > 0) {
643             struct timeval time = {timeout, 0};
644             setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
645             setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
646         }
647 
648         acceptFd_ = RecvSocketFd();
649         HILOGI("RecvSocketFd acceptFd: %{public}d", acceptFd_);
650         if (acceptFd_ <= 0) {
651             return nullptr;
652         }
653         if (timeout > 0) {
654             struct timeval time = {0, 0};
655             setsockopt(fd_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&time, sizeof(time));
656             setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&time, sizeof(time));
657         }
658 
659         std::shared_ptr<ClientSocket> clientSocket = std::make_shared<ClientSocket>(acceptFd_, acceptAddress_, type_);
660 
661         HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BLUETOOTH, "SPP_CONNECT_STATE",
662             HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "connect", "ID", acceptFd_, "ADDRESS",
663             GetEncryptAddr(acceptAddress_), "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid());
664         ReportDataToRss("connect", acceptFd_, GetEncryptAddr(acceptAddress_), IPCSkeleton::GetCallingPid(),
665             IPCSkeleton::GetCallingUid());
666         return clientSocket;
667     }
668 
RecvSocketFdOHOS::Bluetooth::ServerSocket::impl669     int RecvSocketFd()
670     {
671         HILOGD("enter");
672         char ccmsg[CMSG_SPACE(sizeof(int))];
673         char buffer[SOCKET_RECV_FD_SIZE];
674         struct iovec io = {.iov_base = buffer, .iov_len = sizeof(buffer)};
675         struct msghdr msg;
676         (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
677         msg.msg_control = ccmsg;
678         msg.msg_controllen = sizeof(ccmsg);
679         msg.msg_iov = &io;
680         msg.msg_iovlen = 1;
681 
682 #ifdef DARWIN_PLATFORM
683         int rv = TEMP_FAILURE_RETRY(recvmsg(fd_, &msg, 0));
684 #else
685         int rv = TEMP_FAILURE_RETRY(recvmsg(fd_, &msg, MSG_NOSIGNAL));
686 #endif
687         if (rv == -1) {
688             HILOGE("[sock] recvmsg error  %{public}d, fd: %{public}d", errno, fd_);
689             return BtStatus::BT_FAILURE;
690         }
691         struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg);
692         CHECK_AND_RETURN_LOG_RET(cmptr != nullptr, BtStatus::BT_FAILURE, "cmptr error");
693         CHECK_AND_RETURN_LOG_RET(cmptr->cmsg_len == CMSG_LEN(sizeof(int)) && cmptr->cmsg_level == SOL_SOCKET
694             && cmptr->cmsg_type == SCM_RIGHTS, BtStatus::BT_FAILURE,
695             "recvmsg error, len:%{public}d level:%{public}d type:%{public}d",
696             cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);
697         int clientFd = *(reinterpret_cast<int *>(CMSG_DATA(cmptr)));
698 
699         uint8_t recvBuf[rv];
700         (void)memset_s(&recvBuf, sizeof(recvBuf), 0, sizeof(recvBuf));
701         CHECK_AND_RETURN_LOG_RET(memcpy_s(recvBuf, sizeof(recvBuf), (uint8_t *)msg.msg_iov[0].iov_base, rv) == EOK,
702             BtStatus::BT_FAILURE, "RecvSocketFd, recvBuf memcpy_s fail");
703 
704         uint8_t buf[SOCKET_RECV_ADDR_SIZE] = {0};
705         CHECK_AND_RETURN_LOG_RET(memcpy_s(buf, sizeof(buf), &recvBuf[ADDR_OFFSET], sizeof(buf)) == EOK,
706             BtStatus::BT_FAILURE, "RecvSocketFd, buf memcpy_s fail");
707 
708         char token[LENGTH] = {0};
709         (void)sprintf_s(token, sizeof(token), "%02X:%02X:%02X:%02X:%02X:%02X",
710             buf[0x05], buf[0x04], buf[0x03], buf[0x02], buf[0x01], buf[0x00]);
711         BluetoothRawAddress rawAddr {token};
712         // If the random address fails to be obtained, the actual address is returned by default.
713         std::string randomAddr = rawAddr.GetAddress();
714         BluetoothHost *host = &BluetoothHost::GetDefaultHost();
715         host->GetRandomAddress(rawAddr.GetAddress(), randomAddr);
716         acceptAddress_ = randomAddr;
717 
718         maxTxPacketSize_ = GetPacketSizeFromBuf(recvBuf + TX_OFFSET, rv - TX_OFFSET);
719         maxRxPacketSize_ = GetPacketSizeFromBuf(recvBuf + RX_OFFSET, rv - RX_OFFSET);
720         return clientFd;
721     }
722 
GetPacketSizeFromBufOHOS::Bluetooth::ServerSocket::impl723     uint16_t GetPacketSizeFromBuf(uint8_t recvBuf[], int recvBufLen)
724     {
725         uint16_t shortBuf;
726         CHECK_AND_RETURN_LOG_RET(recvBuf, 0, "getpacketsize fail, invalid recvBuf");
727         CHECK_AND_RETURN_LOG_RET(recvBufLen >= SOCKET_RECV_TXRX_SIZE, 0, "getpacketsize fail, invalid recvBufLen");
728         CHECK_AND_RETURN_LOG_RET(memcpy_s(&shortBuf, sizeof(shortBuf), &recvBuf[0], sizeof(shortBuf)) == EOK, 0,
729             "getpacketsize failed, memcpy_s fail");
730         return shortBuf;
731     }
732 
RecvSocketPsmOrScnOHOS::Bluetooth::ServerSocket::impl733     bool RecvSocketPsmOrScn()
734     {
735         int channel = 0;
736 #ifdef DARWIN_PLATFORM
737         int recvBufSize = recv(fd_, &channel, sizeof(channel), 0);
738 #else
739         int recvBufSize = recv(fd_, &channel, sizeof(channel), MSG_WAITALL);
740 #endif
741         CHECK_AND_RETURN_LOG_RET(recvBufSize == SOCKET_RECV_CHANNEL_SIZE, false,
742             "recv psm or scn error, errno:%{public}d, fd_:%{public}d", errno, fd_);
743         CHECK_AND_RETURN_LOG_RET(channel > 0, false,
744             "recv channel error, errno:%{public}d, fd_:%{public}d", errno, fd_);
745         HILOGI("psm or scn = %{public}d, type = %{public}d", channel, type_);
746         socketChannel_ = channel;
747         return true;
748     }
749 
CloseOHOS::Bluetooth::ServerSocket::impl750     void Close()
751     {
752         HILOGD("enter");
753         if (socketStatus_ == SOCKET_CLOSED) {
754             HILOGD("The socketStatus_ is already SOCKET_CLOSED");
755             return;
756         } else {
757             socketStatus_ = SOCKET_CLOSED;
758             if (fd_ > 0) {
759                 shutdown(fd_, SHUT_RD);
760                 shutdown(fd_, SHUT_WR);
761                 HILOGI("fd closed, fd_: %{public}d", fd_);
762                 close(fd_);
763                 fd_ = -1;
764                 sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
765                 CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is nullptr");
766                 proxy->DeregisterServerObserver(observer_);
767                 return;
768             } else {
769                 HILOGE("socket not created");
770                 return;
771             }
772         }
773     }
774 
GetStringTagOHOS::Bluetooth::ServerSocket::impl775     const std::string &GetStringTag()
776     {
777         HILOGD("enter");
778         if (socketStatus_ == SOCKET_CLOSED) {
779             HILOGE("socketStatus_ is SOCKET_CLOSED");
780             socketServiceType_ = "";
781         } else {
782             socketServiceType_ = "ServerSocket:";
783             socketServiceType_.append(" Type: ").append(ConvertTypeToString(type_))
784                 .append(" ServerName: ").append(name_);
785         }
786         return socketServiceType_;
787     }
788 
ConvertTypeToStringOHOS::Bluetooth::ServerSocket::impl789     static std::string ConvertTypeToString(BtSocketType type)
790     {
791         std::string retStr;
792         if (type == TYPE_RFCOMM) {
793             retStr = "TYPE_RFCOMM";
794         } else if (type == TYPE_L2CAP) {
795             retStr = "TYPE_L2CAP";
796         } else if (type == TYPE_L2CAP_LE) {
797             retStr = "TYPE_L2CAP_LE";
798         } else {
799             retStr = "TYPE_UNKNOW";
800         }
801         return retStr;
802     }
803 
804     sptr<BluetoothServerSocketObserverStub> observer_ = nullptr;
805 
806     sptr<IBluetoothSocket> proxy;
807     UUID uuid_;
808     BtSocketType type_;
809     bool encrypt_;
810     int fd_;
811     int socketStatus_;
812     int psm_;
813     std::string name_ {
814         ""
815         };
816     int acceptFd_ = 0;
817     std::string acceptAddress_;
818     std::string socketServiceType_ {
819         ""
820     };
821     std::atomic<int> socketChannel_{ -1 };
822     std::atomic<uint32_t> maxTxPacketSize_{ 0 };
823     std::atomic<uint32_t> maxRxPacketSize_{ 0 };
824 };
825 
impl(const std::string & name,UUID uuid,BtSocketType type,bool encrypt,int psm)826 ServerSocket::impl::impl(const std::string &name, UUID uuid, BtSocketType type, bool encrypt, int psm)
827     : uuid_(uuid), type_(type), encrypt_(encrypt), fd_(-1), socketStatus_(SOCKET_INIT), psm_(psm), name_(name)
828 {
829     HILOGD("(5 parameters) starts");
830     observer_ = new BluetoothServerSocketObserverStub();
831 }
832 
ServerSocket(const std::string & name,UUID uuid,BtSocketType type,bool encrypt,int psm)833 ServerSocket::ServerSocket(const std::string &name, UUID uuid, BtSocketType type, bool encrypt, int psm)
834     : pimpl(new ServerSocket::impl(name, uuid, type, encrypt, psm))
835 {
836     HILOGD("type:%{public}d encrypt:%{public}d psm:%{public}d", type, encrypt, psm);
837 }
838 
ServerSocket(const std::string & name,UUID uuid,BtSocketType type,bool encrypt)839 ServerSocket::ServerSocket(const std::string &name, UUID uuid, BtSocketType type, bool encrypt)
840     : pimpl(new ServerSocket::impl(name, uuid, type, encrypt, -1))
841 {
842     HILOGD("type:%{public}d encrypt:%{public}d", type, encrypt);
843 }
844 
~ServerSocket()845 ServerSocket::~ServerSocket()
846 {}
847 
Listen()848 int ServerSocket::Listen()
849 {
850     HILOGD("enter");
851     return pimpl->Listen();
852 }
853 
Accept(int timeout)854 std::shared_ptr<ClientSocket> ServerSocket::Accept(int timeout)
855 {
856     HILOGD("enter");
857     return pimpl->Accept(timeout);
858 }
859 
Close()860 void ServerSocket::Close()
861 {
862     HILOGD("enter");
863     return pimpl->Close();
864 }
865 
GetStringTag()866 const std::string &ServerSocket::GetStringTag()
867 {
868     HILOGD("enter");
869     return pimpl->GetStringTag();
870 }
871 
GetL2capPsm()872 int ServerSocket::GetL2capPsm()
873 {
874     HILOGI("psm:%{public}d", pimpl->socketChannel_.load());
875     return pimpl->socketChannel_;
876 }
877 
GetRfcommScn()878 int ServerSocket::GetRfcommScn()
879 {
880     HILOGI("scn:%{public}d", pimpl->socketChannel_.load());
881     return pimpl->socketChannel_;
882 }
883 
GetMaxTransmitPacketSize()884 uint32_t ServerSocket::GetMaxTransmitPacketSize()
885 {
886     HILOGI("MaxTransmitPacketSize:%{public}d", pimpl->maxTxPacketSize_.load());
887     return pimpl->maxTxPacketSize_;
888 }
889 
GetMaxReceivePacketSize()890 uint32_t ServerSocket::GetMaxReceivePacketSize()
891 {
892     HILOGI("MaxReceivePacketSize:%{public}d", pimpl->maxRxPacketSize_.load());
893     return pimpl->maxRxPacketSize_;
894 }
895 
GetSocketFd()896 int ServerSocket::GetSocketFd()
897 {
898     return pimpl->fd_;
899 }
900 
BuildInsecureRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)901 std::shared_ptr<ClientSocket> SocketFactory::BuildInsecureRfcommDataSocketByServiceRecord(
902     const BluetoothRemoteDevice &device, const UUID &uuid)
903 {
904     HILOGD("enter");
905     if (device.IsValidBluetoothRemoteDevice()) {
906         return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, false);
907     } else {
908         HILOGE("[sock] Device is not valid.");
909         return nullptr;
910     }
911 }
912 
BuildRfcommDataSocketByServiceRecord(const BluetoothRemoteDevice & device,const UUID & uuid)913 std::shared_ptr<ClientSocket> SocketFactory::BuildRfcommDataSocketByServiceRecord(
914     const BluetoothRemoteDevice &device, const UUID &uuid)
915 {
916     HILOGD("enter");
917     if (device.IsValidBluetoothRemoteDevice()) {
918         return std::make_shared<ClientSocket>(device, uuid, TYPE_RFCOMM, true);
919     } else {
920         HILOGE("[sock] Device is not valid.");
921         return nullptr;
922     }
923 }
924 
DataListenInsecureRfcommByServiceRecord(const std::string & name,const UUID & uuid)925 std::shared_ptr<ServerSocket> SocketFactory::DataListenInsecureRfcommByServiceRecord(
926     const std::string &name, const UUID &uuid)
927 {
928     HILOGD("enter");
929     return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, false);
930 }
931 
DataListenRfcommByServiceRecord(const std::string & name,const UUID & uuid)932 std::shared_ptr<ServerSocket> SocketFactory::DataListenRfcommByServiceRecord(const std::string &name, const UUID &uuid)
933 {
934     HILOGD("enter");
935     return std::make_shared<ServerSocket>(name, uuid, TYPE_RFCOMM, true);
936 }
937 
UpdateCocConnectionParams(CocUpdateSocketParam & param)938 int ClientSocket::UpdateCocConnectionParams(CocUpdateSocketParam &param)
939 {
940     HILOGI("UpdateCocConnectionParams enter");
941     BluetoothSocketCocInfo info;
942 
943     info.addr = param.addr;
944     info.minInterval = param.minInterval;
945     info.maxInterval = param.maxInterval;
946     info.peripheralLatency = param.peripheralLatency;
947     info.supervisionTimeout = param.supervisionTimeout;
948     info.minConnEventLen = param.minConnEventLen;
949     info.maxConnEventLen = param.maxConnEventLen;
950     sptr<IBluetoothSocket> proxy = GetRemoteProxy<IBluetoothSocket>(PROFILE_SOCKET);
951     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_STATE, "proxy is null");
952     return proxy->UpdateCocConnectionParams(info);
953 }
954 }  // namespace Bluetooth
955 }  // namespace OHOS