|
16 | 16 |
|
17 | 17 | #pragma once
|
18 | 18 |
|
| 19 | +#include <access/SubjectDescriptor.h> |
19 | 20 | #include <credentials/FabricTable.h>
|
20 | 21 | #include <lib/core/CHIPConfig.h>
|
| 22 | +#include <lib/core/Optional.h> |
21 | 23 | #include <lib/core/PeerId.h>
|
22 | 24 | #include <lib/core/ScopedNodeId.h>
|
| 25 | +#include <lib/support/IntrusiveList.h> |
| 26 | +#include <lib/support/ReferenceCountedHandle.h> |
23 | 27 | #include <messaging/ReliableMessageProtocolConfig.h>
|
24 | 28 | #include <platform/LockTracker.h>
|
25 |
| -#include <transport/SessionHolder.h> |
| 29 | +#include <transport/SessionDelegate.h> |
26 | 30 | #include <transport/raw/PeerAddress.h>
|
27 | 31 |
|
28 | 32 | namespace chip {
|
| 33 | +namespace Transport { |
| 34 | +class Session; |
| 35 | +} // namespace Transport |
| 36 | + |
| 37 | +/** @brief |
| 38 | + * Non-copyable session reference. All SessionHandles are created within SessionManager. It is not allowed to store SessionHandle |
| 39 | + * anywhere except for function arguments and return values. |
| 40 | + * |
| 41 | + * SessionHandle is reference counted such that it is never dangling, but there can be a gray period when the session is marked |
| 42 | + * as pending removal but not actually removed yet. During this period, the handle is functional, but the underlying session |
| 43 | + * won't be able to be grabbed by any SessionHolder. SessionHandle->IsActiveSession can be used to check if the session is |
| 44 | + * active. |
| 45 | + */ |
| 46 | +class SessionHandle |
| 47 | +{ |
| 48 | +public: |
| 49 | + SessionHandle(Transport::Session & session) : mSession(session) {} |
| 50 | + ~SessionHandle() {} |
| 51 | + |
| 52 | + SessionHandle(const SessionHandle &) = delete; |
| 53 | + SessionHandle operator=(const SessionHandle &) = delete; |
| 54 | + SessionHandle(SessionHandle &&) = default; |
| 55 | + SessionHandle & operator=(SessionHandle &&) = delete; |
| 56 | + |
| 57 | + bool operator==(const SessionHandle & that) const { return &mSession.Get() == &that.mSession.Get(); } |
| 58 | + |
| 59 | + Transport::Session * operator->() const { return mSession.operator->(); } |
| 60 | + |
| 61 | +private: |
| 62 | + friend class SessionHolder; |
| 63 | + ReferenceCountedHandle<Transport::Session> mSession; |
| 64 | +}; |
| 65 | + |
| 66 | +/** @brief |
| 67 | + * Managed session reference. The object is used to store a session, the stored session will be automatically |
| 68 | + * released when the underlying session is released. One must verify it is available before use. The object can be |
| 69 | + * created using SessionHandle.Grab() |
| 70 | + */ |
| 71 | +class SessionHolder : public IntrusiveListNodeBase<> |
| 72 | +{ |
| 73 | +public: |
| 74 | + SessionHolder() {} |
| 75 | + SessionHolder(const SessionHandle & handle) { Grab(handle); } |
| 76 | + virtual ~SessionHolder(); |
| 77 | + |
| 78 | + SessionHolder(const SessionHolder &); |
| 79 | + SessionHolder(SessionHolder && that); |
| 80 | + SessionHolder & operator=(const SessionHolder &); |
| 81 | + SessionHolder & operator=(SessionHolder && that); |
| 82 | + |
| 83 | + virtual void SessionReleased() { Release(); } |
| 84 | + virtual void ShiftToSession(const SessionHandle & session) |
| 85 | + { |
| 86 | + Release(); |
| 87 | + Grab(session); |
| 88 | + } |
| 89 | + |
| 90 | + bool Contains(const SessionHandle & session) const |
| 91 | + { |
| 92 | + return mSession.HasValue() && &mSession.Value().Get() == &session.mSession.Get(); |
| 93 | + } |
| 94 | + |
| 95 | + bool GrabPairingSession(const SessionHandle & session); // Should be only used inside CASE/PASE pairing. |
| 96 | + bool Grab(const SessionHandle & session); |
| 97 | + void Release(); |
| 98 | + |
| 99 | + explicit operator bool() const { return mSession.HasValue(); } |
| 100 | + Optional<SessionHandle> Get() const |
| 101 | + { |
| 102 | + // |
| 103 | + // We cannot return mSession directly even if Optional<SessionHandle> is internally composed of the same bits, |
| 104 | + // since they are not actually equivalent type-wise, and SessionHandle does not permit copy-construction. |
| 105 | + // |
| 106 | + // So, construct a new Optional<SessionHandle> from the underlying Transport::Session reference. |
| 107 | + // |
| 108 | + return mSession.HasValue() ? chip::MakeOptional<SessionHandle>(mSession.Value().Get()) |
| 109 | + : chip::Optional<SessionHandle>::Missing(); |
| 110 | + } |
| 111 | + |
| 112 | + Transport::Session * operator->() const { return &mSession.Value().Get(); } |
| 113 | + |
| 114 | + // There is not delegate, nothing to do here |
| 115 | + virtual void DispatchSessionEvent(SessionDelegate::Event event) {} |
| 116 | + |
| 117 | +protected: |
| 118 | + // Helper for use by the Grab methods. |
| 119 | + void GrabUnchecked(const SessionHandle & session); |
| 120 | + |
| 121 | + Optional<ReferenceCountedHandle<Transport::Session>> mSession; |
| 122 | +}; |
| 123 | + |
| 124 | +/// @brief Extends SessionHolder to allow propagate SessionDelegate::* events to a given destination |
| 125 | +class SessionHolderWithDelegate : public SessionHolder |
| 126 | +{ |
| 127 | +public: |
| 128 | + SessionHolderWithDelegate(SessionDelegate & delegate) : mDelegate(delegate) {} |
| 129 | + SessionHolderWithDelegate(const SessionHandle & handle, SessionDelegate & delegate) : SessionHolder(handle), mDelegate(delegate) |
| 130 | + {} |
| 131 | + operator bool() const { return SessionHolder::operator bool(); } |
| 132 | + |
| 133 | + void SessionReleased() override |
| 134 | + { |
| 135 | + Release(); |
| 136 | + |
| 137 | + // Note, the session is already cleared during mDelegate.OnSessionReleased |
| 138 | + mDelegate.OnSessionReleased(); |
| 139 | + } |
| 140 | + |
| 141 | + void ShiftToSession(const SessionHandle & session) override |
| 142 | + { |
| 143 | + if (mDelegate.GetNewSessionHandlingPolicy() == SessionDelegate::NewSessionHandlingPolicy::kShiftToNewSession) |
| 144 | + SessionHolder::ShiftToSession(session); |
| 145 | + } |
| 146 | + |
| 147 | + void DispatchSessionEvent(SessionDelegate::Event event) override { (mDelegate.*event)(); } |
| 148 | + |
| 149 | +private: |
| 150 | + SessionDelegate & mDelegate; |
| 151 | +}; |
| 152 | + |
29 | 153 | namespace Transport {
|
30 | 154 |
|
31 | 155 | class SecureSession;
|
|
0 commit comments