blob: 9dce2198c3bbc47e91c487543e4adcf31d8be375 [file] [log] [blame]
/*
*
* Copyright (c) 2020-2021 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <lib/core/CHIPError.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/Pool.h>
#include <system/TimeSource.h>
#include <transport/SecureSession.h>
namespace chip {
namespace Transport {
// TODO; use 0xffff to match any key id, this is a temporary solution for
// InteractionModel, where key id is not obtainable. This will be removed when
// InteractionModel is migrated to messaging layer
constexpr const uint16_t kAnyKeyId = 0xffff;
/**
* Handles a set of sessions.
*
* Intended for:
* - handle session active time and expiration
* - allocate and free space for sessions.
*/
template <size_t kMaxSessionCount>
class SecureSessionTable
{
public:
~SecureSessionTable() { mEntries.ReleaseAll(); }
/**
* Allocates a new secure session out of the internal resource pool.
*
* @param secureSessionType secure session type
* @param localSessionId represents the encryption key ID assigned by local node
* @param peerNodeId represents peer Node's ID
* @param peerCATs represents peer CASE Authenticated Tags
* @param peerSessionId represents the encryption key ID assigned by peer node
* @param fabric represents fabric ID for the session
* @param config represents the reliable message protocol configuration
*
* @note the newly created state will have an 'active' time set based on the current time source.
*
* @returns CHIP_NO_ERROR if state could be initialized. May fail if maximum session count
* has been reached (with CHIP_ERROR_NO_MEMORY).
*/
CHECK_RETURN_VALUE
Optional<SessionHandle> CreateNewSecureSession(SecureSession::Type secureSessionType, uint16_t localSessionId,
NodeId peerNodeId, CATValues peerCATs, uint16_t peerSessionId,
FabricIndex fabric, const ReliableMessageProtocolConfig & config)
{
SecureSession * result =
mEntries.CreateObject(secureSessionType, localSessionId, peerNodeId, peerCATs, peerSessionId, fabric, config);
return result != nullptr ? MakeOptional<SessionHandle>(*result) : Optional<SessionHandle>::Missing();
}
void ReleaseSession(SecureSession * session) { mEntries.ReleaseObject(session); }
template <typename Function>
Loop ForEachSession(Function && function)
{
return mEntries.ForEachActiveObject(std::forward<Function>(function));
}
/**
* Get a secure session given a Node Id and Peer's Encryption Key Id.
*
* @param localSessionId Encryption key ID used by the local node.
*
* @return the state found, nullptr if not found
*/
CHECK_RETURN_VALUE
Optional<SessionHandle> FindSecureSessionByLocalKey(uint16_t localSessionId)
{
SecureSession * result = nullptr;
mEntries.ForEachActiveObject([&](auto session) {
if (session->GetLocalSessionId() == localSessionId)
{
result = session;
return Loop::Break;
}
return Loop::Continue;
});
return result != nullptr ? MakeOptional<SessionHandle>(*result) : Optional<SessionHandle>::Missing();
}
/**
* Iterates through all active sessions and expires any sessions with an idle time
* larger than the given amount.
*
* Expiring a session involves callback execution and then clearing the internal state.
*/
template <typename Callback>
void ExpireInactiveSessions(System::Clock::Timestamp maxIdleTime, Callback callback)
{
mEntries.ForEachActiveObject([&](auto session) {
if (session->GetLastActivityTime() + maxIdleTime < System::SystemClock().GetMonotonicTimestamp())
{
callback(*session);
ReleaseSession(session);
}
return Loop::Continue;
});
}
private:
BitMapObjectPool<SecureSession, kMaxSessionCount> mEntries;
};
} // namespace Transport
} // namespace chip