119e95205Sopenharmony_ci/*
219e95205Sopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
319e95205Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
419e95205Sopenharmony_ci * you may not use this file except in compliance with the License.
519e95205Sopenharmony_ci * You may obtain a copy of the License at
619e95205Sopenharmony_ci *
719e95205Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
819e95205Sopenharmony_ci *
919e95205Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1019e95205Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1119e95205Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1219e95205Sopenharmony_ci * See the License for the specific language governing permissions and
1319e95205Sopenharmony_ci * limitations under the License.
1419e95205Sopenharmony_ci */
1519e95205Sopenharmony_ci
1619e95205Sopenharmony_ci#ifndef SOCKET_H
1719e95205Sopenharmony_ci#define SOCKET_H
1819e95205Sopenharmony_ci
1919e95205Sopenharmony_ci#include <map>
2019e95205Sopenharmony_ci#include <mutex>
2119e95205Sopenharmony_ci#include <string>
2219e95205Sopenharmony_ci#include <vector>
2319e95205Sopenharmony_ci#include "base_def.h"
2419e95205Sopenharmony_ci#include "transport/transport.h"
2519e95205Sopenharmony_ci#include "transport/transport_factory.h"
2619e95205Sopenharmony_ci#include "transport/transport_rfcomm.h"
2719e95205Sopenharmony_ci
2819e95205Sopenharmony_ci#include "socket_def.h"
2919e95205Sopenharmony_ci#include "socket_gap_client.h"
3019e95205Sopenharmony_ci#include "socket_gap_server.h"
3119e95205Sopenharmony_ci#include "socket_sdp_client.h"
3219e95205Sopenharmony_ci#include "socket_sdp_server.h"
3319e95205Sopenharmony_ci
3419e95205Sopenharmony_cinamespace OHOS {
3519e95205Sopenharmony_cinamespace bluetooth {
3619e95205Sopenharmony_ci// result of sending data to app
3719e95205Sopenharmony_citypedef enum {
3819e95205Sopenharmony_ci    SOCKET_SEND_NONE = 0,
3919e95205Sopenharmony_ci    SOCKET_SEND_ERROR,
4019e95205Sopenharmony_ci    SOCKET_SEND_PARTIAL,
4119e95205Sopenharmony_ci    SOCKET_SEND_ALL,
4219e95205Sopenharmony_ci} SocketSendRet;
4319e95205Sopenharmony_ci
4419e95205Sopenharmony_ci/**
4519e95205Sopenharmony_ci * @brief This Socket class provides a set of methods that client initiates the connection and
4619e95205Sopenharmony_ci *        server listen and accept the connection.
4719e95205Sopenharmony_ci */
4819e95205Sopenharmony_ciclass Socket {
4919e95205Sopenharmony_cipublic:
5019e95205Sopenharmony_ci    /**
5119e95205Sopenharmony_ci     * @brief Constructor.
5219e95205Sopenharmony_ci     */
5319e95205Sopenharmony_ci    Socket();
5419e95205Sopenharmony_ci
5519e95205Sopenharmony_ci    /**
5619e95205Sopenharmony_ci     * @brief Destructor.
5719e95205Sopenharmony_ci     */
5819e95205Sopenharmony_ci    virtual ~Socket();
5919e95205Sopenharmony_ci
6019e95205Sopenharmony_ci    /**
6119e95205Sopenharmony_ci     * @brief The client initiates the connection.
6219e95205Sopenharmony_ci     * @details The client queries the SDP and finds the channel to be connected through UUID.
6319e95205Sopenharmony_ci     *          Client sets security level to GAP.
6419e95205Sopenharmony_ci     * @param addr address.
6519e95205Sopenharmony_ci     * @param uuid server record uuid to search scn.
6619e95205Sopenharmony_ci     * @param securityFlag require the connection to be encrypted and authenticated.
6719e95205Sopenharmony_ci     * @param sockfd the upper socket fd that generated by the socketpair.
6819e95205Sopenharmony_ci     * @return int
6919e95205Sopenharmony_ci     */
7019e95205Sopenharmony_ci    int Connect(const std::string &addr, const Uuid &uuid, int securityFlag, int &sockfd);
7119e95205Sopenharmony_ci
7219e95205Sopenharmony_ci    /**
7319e95205Sopenharmony_ci     * @brief The server listen and accept the connection.
7419e95205Sopenharmony_ci     * @details The server registers service records to SDP with service name, uuid and server channel
7519e95205Sopenharmony_ci     *          number that assigned by rfcomm. Server sets security level to GAP.
7619e95205Sopenharmony_ci     * @param name server service name.
7719e95205Sopenharmony_ci     * @param uuid server uuid.
7819e95205Sopenharmony_ci     * @param securityFlag require the connection to be encrypted and authenticated.
7919e95205Sopenharmony_ci     * @param sockfd the upper socket fd that generated by the socketpair.
8019e95205Sopenharmony_ci     * @return int
8119e95205Sopenharmony_ci     */
8219e95205Sopenharmony_ci    int Listen(const std::string &name, const Uuid &uuid, int securityFlag, int &sockfd);
8319e95205Sopenharmony_ci
8419e95205Sopenharmony_ci    /**
8519e95205Sopenharmony_ci     * @brief SDP query completed.
8619e95205Sopenharmony_ci     *
8719e95205Sopenharmony_ci     * @param context socket object.
8819e95205Sopenharmony_ci     * @return int
8919e95205Sopenharmony_ci     */
9019e95205Sopenharmony_ci    int ReceiveSdpResult(uint8_t scn);
9119e95205Sopenharmony_ci
9219e95205Sopenharmony_ci    /**
9319e95205Sopenharmony_ci     * @brief close socket.
9419e95205Sopenharmony_ci     *
9519e95205Sopenharmony_ci     */
9619e95205Sopenharmony_ci    void CloseSocket(bool isDisable);
9719e95205Sopenharmony_ci
9819e95205Sopenharmony_ci    /**
9919e95205Sopenharmony_ci     * @brief erase socket
10019e95205Sopenharmony_ci     *
10119e95205Sopenharmony_ci     * @param socket
10219e95205Sopenharmony_ci     */
10319e95205Sopenharmony_ci    void RemoveServerSocket();
10419e95205Sopenharmony_ci
10519e95205Sopenharmony_ci    /**
10619e95205Sopenharmony_ci     * @brief close socket fd
10719e95205Sopenharmony_ci     *
10819e95205Sopenharmony_ci     * @param socket
10919e95205Sopenharmony_ci     */
11019e95205Sopenharmony_ci    void CloseSocketFd();
11119e95205Sopenharmony_ci
11219e95205Sopenharmony_ci    /**
11319e95205Sopenharmony_ci     * @brief clear up socket
11419e95205Sopenharmony_ci     *
11519e95205Sopenharmony_ci     * @param socket
11619e95205Sopenharmony_ci     */
11719e95205Sopenharmony_ci    static void ClearUpAllSocket();
11819e95205Sopenharmony_ci
11919e95205Sopenharmony_ci    /**
12019e95205Sopenharmony_ci     * @brief Poll thread notify the socket that it has data.
12119e95205Sopenharmony_ci     *
12219e95205Sopenharmony_ci     * @param context socket object.
12319e95205Sopenharmony_ci     */
12419e95205Sopenharmony_ci    static void OnSocketReadReady(Socket &sock);
12519e95205Sopenharmony_ci
12619e95205Sopenharmony_ci    /**
12719e95205Sopenharmony_ci     * @brief Poll thread notify the socket that it can receive data.
12819e95205Sopenharmony_ci     *
12919e95205Sopenharmony_ci     * @param context socket object.
13019e95205Sopenharmony_ci     */
13119e95205Sopenharmony_ci    static void OnSocketWriteReady(Socket &sock);
13219e95205Sopenharmony_ci
13319e95205Sopenharmony_ci    /**
13419e95205Sopenharmony_ci     * @brief Poll thread notify the socket that it exception occurred.
13519e95205Sopenharmony_ci     *
13619e95205Sopenharmony_ci     * @param context socket object.
13719e95205Sopenharmony_ci     */
13819e95205Sopenharmony_ci    static void OnSocketException(Socket &sock);
13919e95205Sopenharmony_ci
14019e95205Sopenharmony_ciprivate:
14119e95205Sopenharmony_ci    // remote device address.
14219e95205Sopenharmony_ci    BtAddr remoteAddr_ {{0}, 0};
14319e95205Sopenharmony_ci    // server channel number.
14419e95205Sopenharmony_ci    uint8_t scn_ {0};
14519e95205Sopenharmony_ci    // send mtu.
14619e95205Sopenharmony_ci    uint16_t sendMTU_ {0};
14719e95205Sopenharmony_ci    // recv mtu
14819e95205Sopenharmony_ci    uint16_t recvMTU_ {0};
14919e95205Sopenharmony_ci    // is server or not.
15019e95205Sopenharmony_ci    bool isServer_ {false};
15119e95205Sopenharmony_ci    // connect state.
15219e95205Sopenharmony_ci    SocketState state_ {};
15319e95205Sopenharmony_ci    // the transport socket fd that generated by the socketpair.
15419e95205Sopenharmony_ci    int upperlayerFd_ {-1};
15519e95205Sopenharmony_ci    // the transport socket fd that generated by the socketpair.
15619e95205Sopenharmony_ci    int transportFd_ {-1};
15719e95205Sopenharmony_ci    // require the connection to be encrypted and authenticated.
15819e95205Sopenharmony_ci    int securityFlag_ {0};
15919e95205Sopenharmony_ci    // number of connected clients.
16019e95205Sopenharmony_ci    int clientNumber_ {0};
16119e95205Sopenharmony_ci    // The maximum number of connected devices.
16219e95205Sopenharmony_ci    int maxConnectedNum_ {SOCK_MAX_CLIENT};
16319e95205Sopenharmony_ci    // service id.
16419e95205Sopenharmony_ci    GAP_Service serviceId_ {SPP_ID_START};
16519e95205Sopenharmony_ci    // can read data from Rfcomm.
16619e95205Sopenharmony_ci    bool isCanRead_ {true};
16719e95205Sopenharmony_ci    // can read data from Rfcomm.
16819e95205Sopenharmony_ci    bool isCanWrite_ {true};
16919e95205Sopenharmony_ci    // is or not new socket
17019e95205Sopenharmony_ci    bool isNewSocket_ {false};
17119e95205Sopenharmony_ci    // length of data that send to app failed.
17219e95205Sopenharmony_ci    size_t recvBufLen_ {0};
17319e95205Sopenharmony_ci    // length of data that send to stack failed.
17419e95205Sopenharmony_ci    size_t sendBufLen_ {0};
17519e95205Sopenharmony_ci    // save data that sent to app failed.
17619e95205Sopenharmony_ci    uint8_t recvDataBuf_[SOCK_DEF_RFC_MTU] = {0};
17719e95205Sopenharmony_ci    // save data that sent to stack failed.
17819e95205Sopenharmony_ci    uint8_t sendDataBuf_[SOCK_DEF_RFC_MTU] = {0};
17919e95205Sopenharmony_ci    std::mutex mutex_ {};
18019e95205Sopenharmony_ci    std::mutex fdMutex_ {};
18119e95205Sopenharmony_ci    std::recursive_mutex writeMutex_ {};
18219e95205Sopenharmony_ci    static std::recursive_mutex g_socketMutex;
18319e95205Sopenharmony_ci    // new transport that server accept
18419e95205Sopenharmony_ci    DataTransport *newSockTransport_ {nullptr};
18519e95205Sopenharmony_ci    // the pointer of the SockTransport.
18619e95205Sopenharmony_ci    std::unique_ptr<DataTransport> sockTransport_ {nullptr};
18719e95205Sopenharmony_ci    // the pointer of the transportFactory_.
18819e95205Sopenharmony_ci    std::unique_ptr<TransportFactory> transportFactory_ {nullptr};
18919e95205Sopenharmony_ci    // the pointer of the SocketSdpClient.
19019e95205Sopenharmony_ci    std::unique_ptr<SocketSdpClient> sdpClient_ {nullptr};
19119e95205Sopenharmony_ci    // the pointer of the SocketSdpServer.
19219e95205Sopenharmony_ci    std::unique_ptr<SocketSdpServer> sdpServer_ {nullptr};
19319e95205Sopenharmony_ci    // the pointer of the SocketGapClient.
19419e95205Sopenharmony_ci    std::unique_ptr<SocketGapClient> socketGapClient_ {nullptr};
19519e95205Sopenharmony_ci    // the pointer of the SocketGapServer.
19619e95205Sopenharmony_ci    std::unique_ptr<SocketGapServer> socketGapServer_ {nullptr};
19719e95205Sopenharmony_ci    // the map manages the correspondence between new socket and transport.
19819e95205Sopenharmony_ci    std::map<DataTransport *, std::unique_ptr<Socket>> socketMap_ {};
19919e95205Sopenharmony_ci    // the map manages all sockets;
20019e95205Sopenharmony_ci    static std::vector<Socket *> g_allServerSockets;
20119e95205Sopenharmony_ci
20219e95205Sopenharmony_ci    /**
20319e95205Sopenharmony_ci     * @brief is server or not.
20419e95205Sopenharmony_ci     *
20519e95205Sopenharmony_ci     * @return true: the role is server.
20619e95205Sopenharmony_ci     * @return false :the role is client.
20719e95205Sopenharmony_ci     */
20819e95205Sopenharmony_ci    bool IsServer() const
20919e95205Sopenharmony_ci    {
21019e95205Sopenharmony_ci        return isServer_;
21119e95205Sopenharmony_ci    }
21219e95205Sopenharmony_ci
21319e95205Sopenharmony_ci    /**
21419e95205Sopenharmony_ci     * @brief address translation.
21519e95205Sopenharmony_ci     *
21619e95205Sopenharmony_ci     * @param addr remote device address.
21719e95205Sopenharmony_ci     */
21819e95205Sopenharmony_ci    void SetRemoteAddr(std::string addr);
21919e95205Sopenharmony_ci
22019e95205Sopenharmony_ci    /**
22119e95205Sopenharmony_ci     * @brief Send connection scn to app.
22219e95205Sopenharmony_ci     *
22319e95205Sopenharmony_ci     * @param fd socket fd.
22419e95205Sopenharmony_ci     * @param scn socket scn.
22519e95205Sopenharmony_ci     * @return true
22619e95205Sopenharmony_ci     * @return false
22719e95205Sopenharmony_ci     */
22819e95205Sopenharmony_ci    static bool SendAppConnectScn(int fd, int scn);
22919e95205Sopenharmony_ci
23019e95205Sopenharmony_ci    /**
23119e95205Sopenharmony_ci     * @brief Send connection information to app.
23219e95205Sopenharmony_ci     *
23319e95205Sopenharmony_ci     * @param fd socket fd.
23419e95205Sopenharmony_ci     * @param addr remote device address.
23519e95205Sopenharmony_ci     * @param status connect state.
23619e95205Sopenharmony_ci     * @param send_fd accept socket fd.
23719e95205Sopenharmony_ci     * @return true
23819e95205Sopenharmony_ci     * @return false
23919e95205Sopenharmony_ci     */
24019e95205Sopenharmony_ci    static bool SendAppConnectInfo(int fd, int acceptFd, const SocketConnectInfo &connectInfo);
24119e95205Sopenharmony_ci
24219e95205Sopenharmony_ci    /**
24319e95205Sopenharmony_ci     * @brief When server accept a connection request, generate a new socket.
24419e95205Sopenharmony_ci     *
24519e95205Sopenharmony_ci     * @param addr remote device address.
24619e95205Sopenharmony_ci     * @param transport transport object.
24719e95205Sopenharmony_ci     */
24819e95205Sopenharmony_ci    int AddSocketInternal(BtAddr addr, DataTransport *transport, uint16_t sendMTU, uint16_t recvMTU);
24919e95205Sopenharmony_ci
25019e95205Sopenharmony_ci    /**
25119e95205Sopenharmony_ci     * @brief PPoll thread notify the socket that it can receive data.
25219e95205Sopenharmony_ci     *
25319e95205Sopenharmony_ci     * @param context socket object.
25419e95205Sopenharmony_ci     */
25519e95205Sopenharmony_ci    void OnSocketWriteReadyNative(Socket &sock);
25619e95205Sopenharmony_ci
25719e95205Sopenharmony_ci    /**
25819e95205Sopenharmony_ci     * @brief Poll thread notify the socket that it exception occurred.
25919e95205Sopenharmony_ci     *
26019e95205Sopenharmony_ci     * @param context socket object.
26119e95205Sopenharmony_ci     */
26219e95205Sopenharmony_ci    void OnSocketExceptionNative(Socket &sock);
26319e95205Sopenharmony_ci
26419e95205Sopenharmony_ci    /**
26519e95205Sopenharmony_ci     * @brief Assign serviceId to service
26619e95205Sopenharmony_ci     *
26719e95205Sopenharmony_ci     * @return int
26819e95205Sopenharmony_ci     */
26919e95205Sopenharmony_ci    static GAP_Service AssignServiceId();
27019e95205Sopenharmony_ci
27119e95205Sopenharmony_ci    /**
27219e95205Sopenharmony_ci     * @brief free  serviceId
27319e95205Sopenharmony_ci     *
27419e95205Sopenharmony_ci     * @param serviceId
27519e95205Sopenharmony_ci     */
27619e95205Sopenharmony_ci    static void FreeServiceId(GAP_Service serviceId);
27719e95205Sopenharmony_ci
27819e95205Sopenharmony_ci    /**
27919e95205Sopenharmony_ci     * @brief Send data to app.
28019e95205Sopenharmony_ci     *
28119e95205Sopenharmony_ci     * @param fd socket fd.
28219e95205Sopenharmony_ci     * @param buf data to send.
28319e95205Sopenharmony_ci     * @param len the size of the data to send.
28419e95205Sopenharmony_ci     * @return SocketSendRet
28519e95205Sopenharmony_ci     */
28619e95205Sopenharmony_ci    static SocketSendRet SendDataToApp(int fd, const uint8_t *buf, size_t len);
28719e95205Sopenharmony_ci
28819e95205Sopenharmony_ci    /**
28919e95205Sopenharmony_ci     * @brief Read data from Rfcomm.
29019e95205Sopenharmony_ci     *
29119e95205Sopenharmony_ci     */
29219e95205Sopenharmony_ci    void ReadData();
29319e95205Sopenharmony_ci
29419e95205Sopenharmony_ci    /**
29519e95205Sopenharmony_ci     * @brief Write data from Rfcomm.
29619e95205Sopenharmony_ci     *
29719e95205Sopenharmony_ci     */
29819e95205Sopenharmony_ci    void WriteData();
29919e95205Sopenharmony_ci
30019e95205Sopenharmony_ci    /**
30119e95205Sopenharmony_ci     * @brief Write data to transport.
30219e95205Sopenharmony_ci     *
30319e95205Sopenharmony_ci     */
30419e95205Sopenharmony_ci    int TransportWrite(Packet *subPkt);
30519e95205Sopenharmony_ci
30619e95205Sopenharmony_ci    /**
30719e95205Sopenharmony_ci     * @brief Notify Service Delete Socket
30819e95205Sopenharmony_ci     *
30919e95205Sopenharmony_ci     * @param socket
31019e95205Sopenharmony_ci     */
31119e95205Sopenharmony_ci    static void NotifyServiceDeleteSocket(Socket &sock);
31219e95205Sopenharmony_ci
31319e95205Sopenharmony_ci    /**
31419e95205Sopenharmony_ci     * @brief erase socket
31519e95205Sopenharmony_ci     *
31619e95205Sopenharmony_ci     * @param socket
31719e95205Sopenharmony_ci     */
31819e95205Sopenharmony_ci    static void EraseSocket(Socket &socket);
31919e95205Sopenharmony_ci
32019e95205Sopenharmony_ci    /**
32119e95205Sopenharmony_ci     * @brief write data to app
32219e95205Sopenharmony_ci     *
32319e95205Sopenharmony_ci     * @param socket
32419e95205Sopenharmony_ci     */
32519e95205Sopenharmony_ci    void WriteDataToAPP(const uint8_t *buffer, size_t len);
32619e95205Sopenharmony_ci
32719e95205Sopenharmony_ci    /**
32819e95205Sopenharmony_ci     * @brief process disconnect
32919e95205Sopenharmony_ci     *
33019e95205Sopenharmony_ci     * @param socket
33119e95205Sopenharmony_ci     */
33219e95205Sopenharmony_ci    void ProcessDisconnection(Socket &socket, DataTransport *transport);
33319e95205Sopenharmony_ci
33419e95205Sopenharmony_ci    /**
33519e95205Sopenharmony_ci     * @brief Get service dispatcher.
33619e95205Sopenharmony_ci     *
33719e95205Sopenharmony_ci     * @return service dispatcher.
33819e95205Sopenharmony_ci     */
33919e95205Sopenharmony_ci    utility::Dispatcher *GetDispatchter();
34019e95205Sopenharmony_ci
34119e95205Sopenharmony_ci    BT_DISALLOW_COPY_AND_ASSIGN(Socket);
34219e95205Sopenharmony_ci    DECLARE_IMPL();
34319e95205Sopenharmony_ci};
34419e95205Sopenharmony_ci}  // namespace bluetooth
34519e95205Sopenharmony_ci}  // namespace OHOS
34619e95205Sopenharmony_ci#endif  // SOCKET_H