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