blob: b1b9b5101955a87b269d43b47b8104be37861c58 [file] [log] [blame]
/*
*
* Copyright (c) 2020 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.
*/
/**
* @brief Defines state relevant for an active connection to a peer.
*/
#pragma once
#include <transport/AdminPairingTable.h>
#include <transport/SecureSession.h>
#include <transport/raw/Base.h>
#include <transport/raw/MessageHeader.h>
#include <transport/raw/PeerAddress.h>
namespace chip {
namespace Transport {
static constexpr uint32_t kUndefinedMessageIndex = UINT32_MAX;
/**
* Defines state of a peer connection at a transport layer.
*
* Information contained within the state:
* - PeerAddress represents how to talk to the peer
* - PeerNodeId is the unique ID of the peer
* - SendMessageIndex is an ever increasing index for sending messages
* - LastActivityTimeMs is a monotonic timestamp of when this connection was
* last used. Inactive connections can expire.
* - SecureSession contains the encryption context of a connection
*
* TODO: to add any message ACK information
*/
class PeerConnectionState
{
public:
PeerConnectionState() : mMsgCounterSynStatus(MsgCounterSyncStatus::NotSync), mPeerAddress(PeerAddress::Uninitialized()) {}
PeerConnectionState(const PeerAddress & addr) : mPeerAddress(addr) {}
PeerConnectionState(PeerAddress && addr) : mPeerAddress(addr) {}
PeerConnectionState(PeerConnectionState &&) = default;
PeerConnectionState(const PeerConnectionState &) = default;
PeerConnectionState & operator=(const PeerConnectionState &) = default;
PeerConnectionState & operator=(PeerConnectionState &&) = default;
const PeerAddress & GetPeerAddress() const { return mPeerAddress; }
PeerAddress & GetPeerAddress() { return mPeerAddress; }
void SetPeerAddress(const PeerAddress & address) { mPeerAddress = address; }
void SetTransport(Transport::Base * transport) { mTransport = transport; }
Transport::Base * GetTransport() { return mTransport; }
bool IsPeerMsgCounterSynced() { return (mPeerMessageIndex != kUndefinedMessageIndex); }
void SetPeerMessageIndex(uint32_t id) { mPeerMessageIndex = id; }
NodeId GetPeerNodeId() const { return mPeerNodeId; }
void SetPeerNodeId(NodeId peerNodeId) { mPeerNodeId = peerNodeId; }
uint32_t GetSendMessageIndex() const { return mSendMessageIndex; }
void IncrementSendMessageIndex() { mSendMessageIndex++; }
uint16_t GetPeerKeyID() const { return mPeerKeyID; }
void SetPeerKeyID(uint16_t id) { mPeerKeyID = id; }
uint16_t GetLocalKeyID() const { return mLocalKeyID; }
void SetLocalKeyID(uint16_t id) { mLocalKeyID = id; }
uint64_t GetLastActivityTimeMs() const { return mLastActivityTimeMs; }
void SetLastActivityTimeMs(uint64_t value) { mLastActivityTimeMs = value; }
SecureSession & GetSenderSecureSession() { return mSenderSecureSession; }
SecureSession & GetReceiverSecureSession() { return mReceiverSecureSession; }
Transport::AdminId GetAdminId() const { return mAdmin; }
void SetAdminId(Transport::AdminId admin) { mAdmin = admin; }
void SetMsgCounterSyncInProgress(bool value)
{
mMsgCounterSynStatus = value ? MsgCounterSyncStatus::SyncInProcess : MsgCounterSyncStatus::Synced;
}
bool IsInitialized()
{
return (mPeerAddress.IsInitialized() || mPeerNodeId != kUndefinedNodeId || mPeerKeyID != UINT16_MAX ||
mLocalKeyID != UINT16_MAX);
}
bool IsMsgCounterSyncInProgress() { return mMsgCounterSynStatus == MsgCounterSyncStatus::SyncInProcess; }
/**
* Reset the connection state to a completely uninitialized status.
*/
void Reset()
{
mPeerAddress = PeerAddress::Uninitialized();
mPeerNodeId = kUndefinedNodeId;
mSendMessageIndex = 0;
mLastActivityTimeMs = 0;
mSenderSecureSession.Reset();
mReceiverSecureSession.Reset();
mMsgCounterSynStatus = MsgCounterSyncStatus::NotSync;
}
CHIP_ERROR EncryptBeforeSend(const uint8_t * input, size_t input_length, uint8_t * output, PacketHeader & header,
MessageAuthenticationCode & mac) const
{
return mSenderSecureSession.Encrypt(input, input_length, output, header, mac);
}
CHIP_ERROR DecryptOnReceive(const uint8_t * input, size_t input_length, uint8_t * output, const PacketHeader & header,
const MessageAuthenticationCode & mac) const
{
return mReceiverSecureSession.Decrypt(input, input_length, output, header, mac);
}
private:
enum class MsgCounterSyncStatus
{
NotSync,
SyncInProcess,
Synced,
} mMsgCounterSynStatus;
PeerAddress mPeerAddress;
NodeId mPeerNodeId = kUndefinedNodeId;
uint32_t mSendMessageIndex = 0;
uint32_t mPeerMessageIndex = kUndefinedMessageIndex;
uint16_t mPeerKeyID = UINT16_MAX;
uint16_t mLocalKeyID = UINT16_MAX;
uint64_t mLastActivityTimeMs = 0;
Transport::Base * mTransport = nullptr;
SecureSession mSenderSecureSession;
SecureSession mReceiverSecureSession;
Transport::AdminId mAdmin = kUndefinedAdminId;
};
} // namespace Transport
} // namespace chip