1 /*
2  * Copyright (c) 2024 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 #ifndef DSOFTBUS_ADAPTER_IMPL_H
17 #define DSOFTBUS_ADAPTER_IMPL_H
18 
19 #include <map>
20 #include <set>
21 
22 #include "nocopyable.h"
23 #include "socket.h"
24 
25 #include "circle_stream_buffer.h"
26 #include "i_dsoftbus_adapter.h"
27 #include "net_packet.h"
28 #include <shared_mutex>
29 
30 namespace OHOS {
31 namespace Msdp {
32 namespace DeviceStatus {
33 class DSoftbusAdapterImpl final : public IDSoftbusAdapter {
34     class Observer final {
35     public:
Observer(std::shared_ptr<IDSoftbusObserver> observer)36         explicit Observer(std::shared_ptr<IDSoftbusObserver> observer)
37             : observer_(observer) {}
38 
39         Observer() = default;
40         ~Observer() = default;
41         DISALLOW_COPY_AND_MOVE(Observer);
42 
43         std::shared_ptr<IDSoftbusObserver> Lock() const noexcept
44         {
45             return observer_.lock();
46         }
47 
48         bool operator<(const Observer &other) const noexcept
49         {
50             return (observer_.lock() < other.observer_.lock());
51         }
52 
53     private:
54         std::weak_ptr<IDSoftbusObserver> observer_;
55     };
56 
57     struct Session {
SessionOHOS::Msdp::DeviceStatus::final::Session58         Session(int32_t socket) : socket_(socket) {}
SessionOHOS::Msdp::DeviceStatus::final::Session59         Session(const Session &other) : socket_(other.socket_) {}
60         DISALLOW_MOVE(Session);
61 
62         Session& operator=(const Session &other) = delete;
63 
64         int32_t socket_;
65         CircleStreamBuffer buffer_;
66     };
67 
68 public:
69     DSoftbusAdapterImpl() = default;
70     ~DSoftbusAdapterImpl();
71     DISALLOW_COPY_AND_MOVE(DSoftbusAdapterImpl);
72 
73     int32_t Enable() override;
74     void Disable() override;
75 
76     void AddObserver(std::shared_ptr<IDSoftbusObserver> observer) override;
77     void RemoveObserver(std::shared_ptr<IDSoftbusObserver> observer) override;
78 
79     int32_t OpenSession(const std::string &networkId) override;
80     void CloseSession(const std::string &networkId) override;
81     void CloseAllSessions() override;
82 
83     int32_t SendPacket(const std::string &networkId, NetPacket &packet) override;
84     int32_t SendParcel(const std::string &networkId, Parcel &parcel) override;
85     int32_t BroadcastPacket(NetPacket &packet) override;
86     bool HasSessionExisted(const std::string &networkId) override;
87 
88     void OnBind(int32_t socket, PeerSocketInfo info);
89     void OnShutdown(int32_t socket, ShutdownReason reason);
90     void OnBytes(int32_t socket, const void *data, uint32_t dataLen);
91 
92     static std::shared_ptr<DSoftbusAdapterImpl> GetInstance();
93     static void DestroyInstance();
94 
95 private:
96     int32_t InitSocket(SocketInfo info, int32_t socketType, int32_t &socket);
97     int32_t SetupServer();
98     void ShutdownServer();
99     int32_t OpenSessionLocked(const std::string &networkId);
100     void CloseAllSessionsLocked();
101     void OnConnectedLocked(const std::string &networkId);
102     void ConfigTcpAlive(int32_t socket);
103     int32_t FindConnection(const std::string &networkId);
104     void HandleSessionData(const std::string &networkId, CircleStreamBuffer &circleBuffer);
105     void HandlePacket(const std::string &networkId, NetPacket &packet);
106     void HandleRawData(const std::string &networkId, const void *data, uint32_t dataLen);
107     bool CheckDeviceOnline(const std::string &networkId);
108 
109     /*
110     These four interfaces followed only read members, use shared_lock to avoid dead lock.
111         SendPacket
112         SendParcel
113         BroadcastPacket
114         OnBytes
115     */
116     std::shared_mutex lock_;
117     int32_t socketFd_ { -1 };
118     std::string localSessionName_;
119     std::set<Observer> observers_;
120     std::map<std::string, Session> sessions_;
121 
122     static std::mutex mutex_;
123     static std::shared_ptr<DSoftbusAdapterImpl> instance_;
124 };
125 } // namespace DeviceStatus
126 } // namespace Msdp
127 } // namespace OHOS
128 #endif // DSOFTBUS_ADAPTER_IMPL_H
129