From 9806ece4f598c3c9b1ca1f7378a75546a272266d Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Tue, 11 Mar 2025 13:28:06 -0400 Subject: [PATCH] add KMM opcodes for dereg, reg, NACK, no service, and zeroize; --- src/common/p25/P25Defines.h | 33 +++++++ .../p25/kmm/KMMDeregistrationCommand.cpp | 79 ++++++++++++++++ src/common/p25/kmm/KMMDeregistrationCommand.h | 85 ++++++++++++++++++ .../p25/kmm/KMMDeregistrationResponse.cpp | 74 +++++++++++++++ .../p25/kmm/KMMDeregistrationResponse.h | 81 +++++++++++++++++ src/common/p25/kmm/KMMFactory.cpp | 15 ++++ src/common/p25/kmm/KMMFactory.h | 7 ++ src/common/p25/kmm/KMMHello.h | 1 - src/common/p25/kmm/KMMInventoryCommand.h | 1 - .../p25/kmm/KMMInventoryResponseHeader.h | 1 - .../p25/kmm/KMMInventoryResponseListKeyIDs.h | 1 - .../p25/kmm/KMMInventoryResponseListKeysets.h | 1 - src/common/p25/kmm/KMMNegativeAck.cpp | 82 +++++++++++++++++ src/common/p25/kmm/KMMNegativeAck.h | 89 +++++++++++++++++++ src/common/p25/kmm/KMMNoService.cpp | 67 ++++++++++++++ src/common/p25/kmm/KMMNoService.h | 76 ++++++++++++++++ src/common/p25/kmm/KMMRegistrationCommand.cpp | 79 ++++++++++++++++ src/common/p25/kmm/KMMRegistrationCommand.h | 85 ++++++++++++++++++ .../p25/kmm/KMMRegistrationResponse.cpp | 74 +++++++++++++++ src/common/p25/kmm/KMMRegistrationResponse.h | 81 +++++++++++++++++ src/common/p25/kmm/KMMZeroize.cpp | 67 ++++++++++++++ src/common/p25/kmm/KMMZeroize.h | 76 ++++++++++++++++ 22 files changed, 1150 insertions(+), 5 deletions(-) create mode 100644 src/common/p25/kmm/KMMDeregistrationCommand.cpp create mode 100644 src/common/p25/kmm/KMMDeregistrationCommand.h create mode 100644 src/common/p25/kmm/KMMDeregistrationResponse.cpp create mode 100644 src/common/p25/kmm/KMMDeregistrationResponse.h create mode 100644 src/common/p25/kmm/KMMNegativeAck.cpp create mode 100644 src/common/p25/kmm/KMMNegativeAck.h create mode 100644 src/common/p25/kmm/KMMNoService.cpp create mode 100644 src/common/p25/kmm/KMMNoService.h create mode 100644 src/common/p25/kmm/KMMRegistrationCommand.cpp create mode 100644 src/common/p25/kmm/KMMRegistrationCommand.h create mode 100644 src/common/p25/kmm/KMMRegistrationResponse.cpp create mode 100644 src/common/p25/kmm/KMMRegistrationResponse.h create mode 100644 src/common/p25/kmm/KMMZeroize.cpp create mode 100644 src/common/p25/kmm/KMMZeroize.h diff --git a/src/common/p25/P25Defines.h b/src/common/p25/P25Defines.h index bd69f1da..eaf100a4 100644 --- a/src/common/p25/P25Defines.h +++ b/src/common/p25/P25Defines.h @@ -439,9 +439,15 @@ namespace p25 MODIFY_KEY_CMD = 0x13U, //! Modify Key Command NAK = 0x16U, //! Negative Ack + NO_SERVICE = 0x17U, //! No Service ZEROIZE_CMD = 0x21U, //! Zeroize Command ZEROIZE_RSP = 0x22U, //! Zeroize Response + + DEREG_CMD = 0x23U, //! SU Deregistration Command + DEREG_RSP = 0x24U, //! SU Deregistration Response + REG_CMD = 0x25U, //! SU Registration Command + REG_RSP = 0x26U, //! SU Registration Response }; } @@ -485,6 +491,31 @@ namespace p25 }; } + /** @brief KMM Status */ + namespace KMM_Status { + enum : uint8_t { + CMD_PERFORMED = 0x00U, //! Command Performed + CMD_NOT_PERFORMED = 0x01U, //! Command Was Not Performed + + ITEM_NOT_EXIST = 0x02U, //! Item does not exist + INVALID_MSG_ID = 0x03U, //! Invalid Message ID + INVALID_MAC = 0x04U, //! Invalid Message Authentication Code + + OUT_OF_MEMORY = 0x05U, //! Out of Memory + FAILED_TO_DECRYPT = 0x06U, //! Failed to decrypt message + + INVALID_MSG_NUMBER = 0x07U, //! Invalid Message Number + INVALID_KID = 0x08U, //! Invalid Key ID + INVALID_ALGID = 0x09U, //! Invalid Algorithm ID + INVALID_MFID = 0x0AU, //! Invalid Manufacturer ID + + MI_ALL_ZERO = 0x0CU, //! Message Indicator All Zero + KEY_FAIL = 0x0DU, //! Key Identified by Alg/KID is Erased + + UNKNOWN = 0xFFU, //! Unknown + }; + } + /** @brief KMM Decryption Instruction - None */ const uint8_t KMM_DECRYPT_INSTRUCT_NONE = 0x00U; /** @brief KMM Decryption Instruction - Message Indicator */ @@ -492,6 +523,8 @@ namespace p25 /** @brief KMM Key Format TEK */ const uint8_t KEY_FORMAT_TEK = 0x80U; + /** @brief KMM Key Format TEK */ + const uint8_t KEY_FORMAT_KEK_EXISTS = 0x40U; /** @brief KMM Key Format Delete Key */ const uint8_t KEY_FORMAT_DELETE = 0x20U; diff --git a/src/common/p25/kmm/KMMDeregistrationCommand.cpp b/src/common/p25/kmm/KMMDeregistrationCommand.cpp new file mode 100644 index 00000000..16d2012c --- /dev/null +++ b/src/common/p25/kmm/KMMDeregistrationCommand.cpp @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +#include "Defines.h" +#include "p25/P25Defines.h" +#include "p25/kmm/KMMDeregistrationCommand.h" +#include "Log.h" + +using namespace p25; +using namespace p25::defines; +using namespace p25::kmm; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/* Initializes a new instance of the KMMDeregistrationCommand class. */ + +KMMDeregistrationCommand::KMMDeregistrationCommand() : KMMFrame(), + m_bodyFormat(0U), + m_kmfRSI(9999999U) +{ + m_messageId = KMM_MessageType::DEREG_CMD; + m_respKind = KMM_ResponseKind::IMMEDIATE; +} + +/* Finalizes a instance of the KMMDeregistrationCommand class. */ + +KMMDeregistrationCommand::~KMMDeregistrationCommand() = default; + +/* Decode a KMM modify key. */ + +bool KMMDeregistrationCommand::decode(const uint8_t* data) +{ + assert(data != nullptr); + + KMMFrame::decodeHeader(data); + + m_bodyFormat = data[10U]; // Body Format + m_kmfRSI = __GET_UINT16(data, 11U); // KMF RSI + + return true; +} + +/* Encode a KMM modify key. */ + +void KMMDeregistrationCommand::encode(uint8_t* data) +{ + assert(data != nullptr); + m_messageLength = KMM_DEREGISTRATION_CMD_LENGTH; + m_bodyFormat = 0U; // reset this to none -- we don't support warm start right now + + KMMFrame::encodeHeader(data); + + data[10U] = m_bodyFormat; // Body Format + __SET_UINT16(m_kmfRSI, data, 11U); // KMF RSI +} + +// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + +/* Internal helper to copy the the class. */ + +void KMMDeregistrationCommand::copy(const KMMDeregistrationCommand& data) +{ + KMMFrame::copy(data); + + m_bodyFormat = data.m_bodyFormat; + m_kmfRSI = data.m_kmfRSI; +} diff --git a/src/common/p25/kmm/KMMDeregistrationCommand.h b/src/common/p25/kmm/KMMDeregistrationCommand.h new file mode 100644 index 00000000..053a690a --- /dev/null +++ b/src/common/p25/kmm/KMMDeregistrationCommand.h @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +/** + * @file KMMDeregistrationCommand.h + * @ingroup p25_kmm + * @file KMMDeregistrationCommand.cpp + * @ingroup p25_kmm + */ +#if !defined(__P25_KMM__KMM_DEREGISTRATION_CMD_H__) +#define __P25_KMM__KMM_DEREGISTRATION_CMD_H__ + +#include "common/Defines.h" +#include "common/p25/kmm/KMMFrame.h" +#include "common/Utils.h" + +#include +#include + +namespace p25 +{ + namespace kmm + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + /** + * @addtogroup p25_kmm + * @{ + */ + + const uint32_t KMM_DEREGISTRATION_CMD_LENGTH = KMM_FRAME_LENGTH + 4U; + + /** @} */ + + // --------------------------------------------------------------------------- + // Class Declaration + // --------------------------------------------------------------------------- + + class HOST_SW_API KMMDeregistrationCommand : public KMMFrame { + public: + /** + * @brief Initializes a new instance of the KMMDeregistrationCommand class. + */ + KMMDeregistrationCommand(); + /** + * @brief Finalizes a instance of the KMMDeregistrationCommand class. + */ + ~KMMDeregistrationCommand(); + + /** + * @brief Decode a KMM deregistration command. + * @param[in] data Buffer containing KMM frame data to decode. + * @returns bool True, if decoded, otherwise false. + */ + bool decode(const uint8_t* data) override; + /** + * @brief Encode a KMM deregistration command. + * @param[out] data Buffer to encode KMM frame data to. + */ + void encode(uint8_t* data) override; + + public: + /** + * @brief + */ + __PROPERTY(uint8_t, bodyFormat, BodyFormat); + /** + * @brief + */ + __PROPERTY(uint32_t, kmfRSI, KMFRSI); + + __COPY(KMMDeregistrationCommand); + }; + } // namespace kmm +} // namespace p25 + +#endif // __P25_KMM__KMM_DEREGISTRATION_CMD_H__ diff --git a/src/common/p25/kmm/KMMDeregistrationResponse.cpp b/src/common/p25/kmm/KMMDeregistrationResponse.cpp new file mode 100644 index 00000000..f3ace584 --- /dev/null +++ b/src/common/p25/kmm/KMMDeregistrationResponse.cpp @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +#include "Defines.h" +#include "p25/P25Defines.h" +#include "p25/kmm/KMMDeregistrationResponse.h" +#include "Log.h" + +using namespace p25; +using namespace p25::defines; +using namespace p25::kmm; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/* Initializes a new instance of the KMMDeregistrationResponse class. */ + +KMMDeregistrationResponse::KMMDeregistrationResponse() : KMMFrame(), + m_status(KMM_Status::CMD_PERFORMED) +{ + m_messageId = KMM_MessageType::DEREG_RSP; + m_respKind = KMM_ResponseKind::IMMEDIATE; +} + +/* Finalizes a instance of the KMMDeregistrationResponse class. */ + +KMMDeregistrationResponse::~KMMDeregistrationResponse() = default; + +/* Decode a KMM modify key. */ + +bool KMMDeregistrationResponse::decode(const uint8_t* data) +{ + assert(data != nullptr); + + KMMFrame::decodeHeader(data); + + m_status = data[10U]; // Status + + return true; +} + +/* Encode a KMM modify key. */ + +void KMMDeregistrationResponse::encode(uint8_t* data) +{ + assert(data != nullptr); + m_messageLength = KMM_DEREGISTRATION_RSP_LENGTH; + + KMMFrame::encodeHeader(data); + + data[10U] = m_status; // Status +} + +// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + +/* Internal helper to copy the the class. */ + +void KMMDeregistrationResponse::copy(const KMMDeregistrationResponse& data) +{ + KMMFrame::copy(data); + + m_status = data.m_status; +} diff --git a/src/common/p25/kmm/KMMDeregistrationResponse.h b/src/common/p25/kmm/KMMDeregistrationResponse.h new file mode 100644 index 00000000..ab5b3876 --- /dev/null +++ b/src/common/p25/kmm/KMMDeregistrationResponse.h @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +/** + * @file KMMDeregistrationResponse.h + * @ingroup p25_kmm + * @file KMMDeregistrationResponse.cpp + * @ingroup p25_kmm + */ +#if !defined(__P25_KMM__KMM_DEREGISTRATION_RSP_H__) +#define __P25_KMM__KMM_DEREGISTRATION_RSP_H__ + +#include "common/Defines.h" +#include "common/p25/kmm/KMMFrame.h" +#include "common/Utils.h" + +#include +#include + +namespace p25 +{ + namespace kmm + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + /** + * @addtogroup p25_kmm + * @{ + */ + + const uint32_t KMM_DEREGISTRATION_RSP_LENGTH = KMM_FRAME_LENGTH + 1U; + + /** @} */ + + // --------------------------------------------------------------------------- + // Class Declaration + // --------------------------------------------------------------------------- + + class HOST_SW_API KMMDeregistrationResponse : public KMMFrame { + public: + /** + * @brief Initializes a new instance of the KMMDeregistrationResponse class. + */ + KMMDeregistrationResponse(); + /** + * @brief Finalizes a instance of the KMMDeregistrationResponse class. + */ + ~KMMDeregistrationResponse(); + + /** + * @brief Decode a KMM deregistration response. + * @param[in] data Buffer containing KMM frame data to decode. + * @returns bool True, if decoded, otherwise false. + */ + bool decode(const uint8_t* data) override; + /** + * @brief Encode a KMM deregistration response. + * @param[out] data Buffer to encode KMM frame data to. + */ + void encode(uint8_t* data) override; + + public: + /** + * @brief + */ + __PROPERTY(uint8_t, status, Status); + + __COPY(KMMDeregistrationResponse); + }; + } // namespace kmm +} // namespace p25 + +#endif // __P25_KMM__KMM_DEREGISTRATION_RSP_H__ diff --git a/src/common/p25/kmm/KMMFactory.cpp b/src/common/p25/kmm/KMMFactory.cpp index 30515c97..eec2a2fa 100644 --- a/src/common/p25/kmm/KMMFactory.cpp +++ b/src/common/p25/kmm/KMMFactory.cpp @@ -72,6 +72,21 @@ std::unique_ptr KMMFactory::create(const uint8_t* data) break; case KMM_MessageType::MODIFY_KEY_CMD: return decode(new KMMModifyKey(), data); + case KMM_MessageType::NAK: + return decode(new KMMNegativeAck(), data); + case KMM_MessageType::NO_SERVICE: + return decode(new KMMNoService(), data); + case KMM_MessageType::ZEROIZE_CMD: + case KMM_MessageType::ZEROIZE_RSP: + return decode(new KMMZeroize(), data); + case KMM_MessageType::DEREG_CMD: + return decode(new KMMDeregistrationCommand(), data); + case KMM_MessageType::DEREG_RSP: + return decode(new KMMDeregistrationResponse(), data); + case KMM_MessageType::REG_CMD: + return decode(new KMMRegistrationCommand(), data); + case KMM_MessageType::REG_RSP: + return decode(new KMMRegistrationResponse(), data); default: LogError(LOG_P25, "KMMFactory::create(), unknown KMM message ID value, messageId = $%02X", messageId); break; diff --git a/src/common/p25/kmm/KMMFactory.h b/src/common/p25/kmm/KMMFactory.h index 4b6bb35e..ce9dd010 100644 --- a/src/common/p25/kmm/KMMFactory.h +++ b/src/common/p25/kmm/KMMFactory.h @@ -21,12 +21,19 @@ #include "common/p25/kmm/KeysetItem.h" #include "common/p25/kmm/KMMFrame.h" +#include "common/p25/kmm/KMMDeregistrationCommand.h" +#include "common/p25/kmm/KMMDeregistrationResponse.h" #include "common/p25/kmm/KMMHello.h" #include "common/p25/kmm/KMMInventoryCommand.h" #include "common/p25/kmm/KMMInventoryResponseHeader.h" #include "common/p25/kmm/KMMInventoryResponseListKeysets.h" #include "common/p25/kmm/KMMInventoryResponseListKeyIDs.h" #include "common/p25/kmm/KMMModifyKey.h" +#include "common/p25/kmm/KMMNegativeAck.h" +#include "common/p25/kmm/KMMNoService.h" +#include "common/p25/kmm/KMMRegistrationCommand.h" +#include "common/p25/kmm/KMMRegistrationResponse.h" +#include "common/p25/kmm/KMMZeroize.h" namespace p25 { diff --git a/src/common/p25/kmm/KMMHello.h b/src/common/p25/kmm/KMMHello.h index 316d8650..0d220243 100644 --- a/src/common/p25/kmm/KMMHello.h +++ b/src/common/p25/kmm/KMMHello.h @@ -18,7 +18,6 @@ #include "common/Defines.h" #include "common/p25/kmm/KMMFrame.h" -#include "common/p25/kmm/KeysetItem.h" #include "common/Utils.h" #include diff --git a/src/common/p25/kmm/KMMInventoryCommand.h b/src/common/p25/kmm/KMMInventoryCommand.h index a4a9cd98..1f18bed6 100644 --- a/src/common/p25/kmm/KMMInventoryCommand.h +++ b/src/common/p25/kmm/KMMInventoryCommand.h @@ -18,7 +18,6 @@ #include "common/Defines.h" #include "common/p25/kmm/KMMFrame.h" -#include "common/p25/kmm/KeysetItem.h" #include "common/Utils.h" #include diff --git a/src/common/p25/kmm/KMMInventoryResponseHeader.h b/src/common/p25/kmm/KMMInventoryResponseHeader.h index 10a5baf9..07d3877c 100644 --- a/src/common/p25/kmm/KMMInventoryResponseHeader.h +++ b/src/common/p25/kmm/KMMInventoryResponseHeader.h @@ -18,7 +18,6 @@ #include "common/Defines.h" #include "common/p25/kmm/KMMFrame.h" -#include "common/p25/kmm/KeysetItem.h" #include "common/Utils.h" #include diff --git a/src/common/p25/kmm/KMMInventoryResponseListKeyIDs.h b/src/common/p25/kmm/KMMInventoryResponseListKeyIDs.h index 4f5cc6a4..6f56a2cd 100644 --- a/src/common/p25/kmm/KMMInventoryResponseListKeyIDs.h +++ b/src/common/p25/kmm/KMMInventoryResponseListKeyIDs.h @@ -19,7 +19,6 @@ #include "common/Defines.h" #include "common/p25/kmm/KMMFrame.h" #include "common/p25/kmm/KMMInventoryResponseHeader.h" -#include "common/p25/kmm/KeysetItem.h" #include "common/Utils.h" #include diff --git a/src/common/p25/kmm/KMMInventoryResponseListKeysets.h b/src/common/p25/kmm/KMMInventoryResponseListKeysets.h index 8f142093..403ce7fc 100644 --- a/src/common/p25/kmm/KMMInventoryResponseListKeysets.h +++ b/src/common/p25/kmm/KMMInventoryResponseListKeysets.h @@ -19,7 +19,6 @@ #include "common/Defines.h" #include "common/p25/kmm/KMMFrame.h" #include "common/p25/kmm/KMMInventoryResponseHeader.h" -#include "common/p25/kmm/KeysetItem.h" #include "common/Utils.h" #include diff --git a/src/common/p25/kmm/KMMNegativeAck.cpp b/src/common/p25/kmm/KMMNegativeAck.cpp new file mode 100644 index 00000000..82f16dcf --- /dev/null +++ b/src/common/p25/kmm/KMMNegativeAck.cpp @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +#include "Defines.h" +#include "p25/P25Defines.h" +#include "p25/kmm/KMMNegativeAck.h" +#include "Log.h" + +using namespace p25; +using namespace p25::defines; +using namespace p25::kmm; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/* Initializes a new instance of the KMMNegativeAck class. */ + +KMMNegativeAck::KMMNegativeAck() : KMMFrame(), + m_messageId(0U), + m_messageNo(0U), + m_status(KMM_Status::CMD_NOT_PERFORMED) +{ + m_messageId = KMM_MessageType::NAK; + m_respKind = KMM_ResponseKind::IMMEDIATE; +} + +/* Finalizes a instance of the KMMNegativeAck class. */ + +KMMNegativeAck::~KMMNegativeAck() = default; + +/* Decode a KMM NAK. */ + +bool KMMNegativeAck::decode(const uint8_t* data) +{ + assert(data != nullptr); + + KMMFrame::decodeHeader(data); + + m_messageId = data[10U]; // Message ID + m_messageNo = __GET_UINT16B(data, 11U); // Message Number + m_status = data[13U]; // Status + + return true; +} + +/* Encode a KMM NAK. */ + +void KMMNegativeAck::encode(uint8_t* data) +{ + assert(data != nullptr); + m_messageLength = KMM_NEGATIVE_ACK_LENGTH; + + KMMFrame::encodeHeader(data); + + data[10U] = m_messageId; // Message ID + __SET_UINT16B(m_messageNo, data, 11U); // Message Number + data[13U] = m_status; +} + +// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + +/* Internal helper to copy the the class. */ + +void KMMNegativeAck::copy(const KMMNegativeAck& data) +{ + KMMFrame::copy(data); + + m_messageId = data.m_messageId; + m_messageNo = data.m_messageNo; + m_status = data.m_status; +} diff --git a/src/common/p25/kmm/KMMNegativeAck.h b/src/common/p25/kmm/KMMNegativeAck.h new file mode 100644 index 00000000..e0e8967c --- /dev/null +++ b/src/common/p25/kmm/KMMNegativeAck.h @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +/** + * @file KMMNegativeAck.h + * @ingroup p25_kmm + * @file KMMNegativeAck.cpp + * @ingroup p25_kmm + */ +#if !defined(__P25_KMM__KMM_NEGATIVE_ACK_H__) +#define __P25_KMM__KMM_NEGATIVE_ACK_H__ + +#include "common/Defines.h" +#include "common/p25/kmm/KMMFrame.h" +#include "common/Utils.h" + +#include +#include + +namespace p25 +{ + namespace kmm + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + /** + * @addtogroup p25_kmm + * @{ + */ + + const uint32_t KMM_NEGATIVE_ACK_LENGTH = KMM_FRAME_LENGTH + 4U; + + /** @} */ + + // --------------------------------------------------------------------------- + // Class Declaration + // --------------------------------------------------------------------------- + + class HOST_SW_API KMMNegativeAck : public KMMFrame { + public: + /** + * @brief Initializes a new instance of the KMMNegativeAck class. + */ + KMMNegativeAck(); + /** + * @brief Finalizes a instance of the KMMNegativeAck class. + */ + ~KMMNegativeAck(); + + /** + * @brief Decode a KMM NAK. + * @param[in] data Buffer containing KMM frame data to decode. + * @returns bool True, if decoded, otherwise false. + */ + bool decode(const uint8_t* data) override; + /** + * @brief Encode a KMM NAK. + * @param[out] data Buffer to encode KMM frame data to. + */ + void encode(uint8_t* data) override; + + public: + /** + * @brief + */ + __PROPERTY(uint8_t, messageId, MessageId); + /** + * @brief + */ + __PROPERTY(uint16_t, messageNo, MessageNumber); + /** + * @brief + */ + __PROPERTY(uint8_t, status, Status); + + __COPY(KMMNegativeAck); + }; + } // namespace kmm +} // namespace p25 + +#endif // __P25_KMM__KMM_NEGATIVE_ACK_H__ diff --git a/src/common/p25/kmm/KMMNoService.cpp b/src/common/p25/kmm/KMMNoService.cpp new file mode 100644 index 00000000..d231d283 --- /dev/null +++ b/src/common/p25/kmm/KMMNoService.cpp @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +#include "Defines.h" +#include "p25/P25Defines.h" +#include "p25/kmm/KMMNoService.h" +#include "Log.h" + +using namespace p25; +using namespace p25::defines; +using namespace p25::kmm; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/* Initializes a new instance of the KMMNoService class. */ + +KMMNoService::KMMNoService() : KMMFrame() +{ + m_messageId = KMM_MessageType::NO_SERVICE; + m_respKind = KMM_ResponseKind::NONE; +} + +/* Finalizes a instance of the KMMNoService class. */ + +KMMNoService::~KMMNoService() = default; + +/* Decode a KMM modify key. */ + +bool KMMNoService::decode(const uint8_t* data) +{ + assert(data != nullptr); + + KMMFrame::decodeHeader(data); + + return true; +} + +/* Encode a KMM modify key. */ + +void KMMNoService::encode(uint8_t* data) +{ + assert(data != nullptr); + m_messageLength = KMM_NO_SERVICE_LENGTH; + + KMMFrame::encodeHeader(data); +} + +// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + +/* Internal helper to copy the the class. */ + +void KMMNoService::copy(const KMMNoService& data) +{ + KMMFrame::copy(data); +} diff --git a/src/common/p25/kmm/KMMNoService.h b/src/common/p25/kmm/KMMNoService.h new file mode 100644 index 00000000..5cccdf3e --- /dev/null +++ b/src/common/p25/kmm/KMMNoService.h @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +/** + * @file KMMNoService.h + * @ingroup p25_kmm + * @file KMMNoService.cpp + * @ingroup p25_kmm + */ +#if !defined(__P25_KMM__KMM_NO_SERVICE_H__) +#define __P25_KMM__KMM_NO_SERVICE_H__ + +#include "common/Defines.h" +#include "common/p25/kmm/KMMFrame.h" +#include "common/Utils.h" + +#include +#include + +namespace p25 +{ + namespace kmm + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + /** + * @addtogroup p25_kmm + * @{ + */ + + const uint32_t KMM_NO_SERVICE_LENGTH = KMM_FRAME_LENGTH; + + /** @} */ + + // --------------------------------------------------------------------------- + // Class Declaration + // --------------------------------------------------------------------------- + + class HOST_SW_API KMMNoService : public KMMFrame { + public: + /** + * @brief Initializes a new instance of the KMMNoService class. + */ + KMMNoService(); + /** + * @brief Finalizes a instance of the KMMNoService class. + */ + ~KMMNoService(); + + /** + * @brief Decode a KMM hello. + * @param[in] data Buffer containing KMM frame data to decode. + * @returns bool True, if decoded, otherwise false. + */ + bool decode(const uint8_t* data) override; + /** + * @brief Encode a KMM hello. + * @param[out] data Buffer to encode KMM frame data to. + */ + void encode(uint8_t* data) override; + + public: + __COPY(KMMNoService); + }; + } // namespace kmm +} // namespace p25 + +#endif // __P25_KMM__KMM_NO_SERVICE_H__ diff --git a/src/common/p25/kmm/KMMRegistrationCommand.cpp b/src/common/p25/kmm/KMMRegistrationCommand.cpp new file mode 100644 index 00000000..464f7378 --- /dev/null +++ b/src/common/p25/kmm/KMMRegistrationCommand.cpp @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +#include "Defines.h" +#include "p25/P25Defines.h" +#include "p25/kmm/KMMRegistrationCommand.h" +#include "Log.h" + +using namespace p25; +using namespace p25::defines; +using namespace p25::kmm; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/* Initializes a new instance of the KMMRegistrationCommand class. */ + +KMMRegistrationCommand::KMMRegistrationCommand() : KMMFrame(), + m_bodyFormat(0U), + m_kmfRSI(9999999U) +{ + m_messageId = KMM_MessageType::REG_CMD; + m_respKind = KMM_ResponseKind::IMMEDIATE; +} + +/* Finalizes a instance of the KMMRegistrationCommand class. */ + +KMMRegistrationCommand::~KMMRegistrationCommand() = default; + +/* Decode a KMM modify key. */ + +bool KMMRegistrationCommand::decode(const uint8_t* data) +{ + assert(data != nullptr); + + KMMFrame::decodeHeader(data); + + m_bodyFormat = data[10U]; // Body Format + m_kmfRSI = __GET_UINT16(data, 11U); // KMF RSI + + return true; +} + +/* Encode a KMM modify key. */ + +void KMMRegistrationCommand::encode(uint8_t* data) +{ + assert(data != nullptr); + m_messageLength = KMM_REGISTRATION_CMD_LENGTH; + m_bodyFormat = 0U; // reset this to none -- we don't support warm start right now + + KMMFrame::encodeHeader(data); + + data[10U] = m_bodyFormat; // Body Format + __SET_UINT16(m_kmfRSI, data, 11U); // KMF RSI +} + +// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + +/* Internal helper to copy the the class. */ + +void KMMRegistrationCommand::copy(const KMMRegistrationCommand& data) +{ + KMMFrame::copy(data); + + m_bodyFormat = data.m_bodyFormat; + m_kmfRSI = data.m_kmfRSI; +} diff --git a/src/common/p25/kmm/KMMRegistrationCommand.h b/src/common/p25/kmm/KMMRegistrationCommand.h new file mode 100644 index 00000000..efc944a6 --- /dev/null +++ b/src/common/p25/kmm/KMMRegistrationCommand.h @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +/** + * @file KMMRegistrationCommand.h + * @ingroup p25_kmm + * @file KMMRegistrationCommand.cpp + * @ingroup p25_kmm + */ +#if !defined(__P25_KMM__KMM_REGISTRATION_CMD_H__) +#define __P25_KMM__KMM_REGISTRATION_CMD_H__ + +#include "common/Defines.h" +#include "common/p25/kmm/KMMFrame.h" +#include "common/Utils.h" + +#include +#include + +namespace p25 +{ + namespace kmm + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + /** + * @addtogroup p25_kmm + * @{ + */ + + const uint32_t KMM_REGISTRATION_CMD_LENGTH = KMM_FRAME_LENGTH + 4U; + + /** @} */ + + // --------------------------------------------------------------------------- + // Class Declaration + // --------------------------------------------------------------------------- + + class HOST_SW_API KMMRegistrationCommand : public KMMFrame { + public: + /** + * @brief Initializes a new instance of the KMMRegistrationCommand class. + */ + KMMRegistrationCommand(); + /** + * @brief Finalizes a instance of the KMMRegistrationCommand class. + */ + ~KMMRegistrationCommand(); + + /** + * @brief Decode a KMM deregistration command. + * @param[in] data Buffer containing KMM frame data to decode. + * @returns bool True, if decoded, otherwise false. + */ + bool decode(const uint8_t* data) override; + /** + * @brief Encode a KMM deregistration command. + * @param[out] data Buffer to encode KMM frame data to. + */ + void encode(uint8_t* data) override; + + public: + /** + * @brief + */ + __PROPERTY(uint8_t, bodyFormat, BodyFormat); + /** + * @brief + */ + __PROPERTY(uint32_t, kmfRSI, KMFRSI); + + __COPY(KMMRegistrationCommand); + }; + } // namespace kmm +} // namespace p25 + +#endif // __P25_KMM__KMM_REGISTRATION_CMD_H__ diff --git a/src/common/p25/kmm/KMMRegistrationResponse.cpp b/src/common/p25/kmm/KMMRegistrationResponse.cpp new file mode 100644 index 00000000..eeba92ff --- /dev/null +++ b/src/common/p25/kmm/KMMRegistrationResponse.cpp @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +#include "Defines.h" +#include "p25/P25Defines.h" +#include "p25/kmm/KMMRegistrationResponse.h" +#include "Log.h" + +using namespace p25; +using namespace p25::defines; +using namespace p25::kmm; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/* Initializes a new instance of the KMMRegistrationResponse class. */ + +KMMRegistrationResponse::KMMRegistrationResponse() : KMMFrame(), + m_status(KMM_Status::CMD_PERFORMED) +{ + m_messageId = KMM_MessageType::DEREG_RSP; + m_respKind = KMM_ResponseKind::IMMEDIATE; +} + +/* Finalizes a instance of the KMMRegistrationResponse class. */ + +KMMRegistrationResponse::~KMMRegistrationResponse() = default; + +/* Decode a KMM modify key. */ + +bool KMMRegistrationResponse::decode(const uint8_t* data) +{ + assert(data != nullptr); + + KMMFrame::decodeHeader(data); + + m_status = data[10U]; // Status + + return true; +} + +/* Encode a KMM modify key. */ + +void KMMRegistrationResponse::encode(uint8_t* data) +{ + assert(data != nullptr); + m_messageLength = KMM_REGISTRATION_RSP_LENGTH; + + KMMFrame::encodeHeader(data); + + data[10U] = m_status; // Status +} + +// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + +/* Internal helper to copy the the class. */ + +void KMMRegistrationResponse::copy(const KMMRegistrationResponse& data) +{ + KMMFrame::copy(data); + + m_status = data.m_status; +} diff --git a/src/common/p25/kmm/KMMRegistrationResponse.h b/src/common/p25/kmm/KMMRegistrationResponse.h new file mode 100644 index 00000000..0f6f3fb7 --- /dev/null +++ b/src/common/p25/kmm/KMMRegistrationResponse.h @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +/** + * @file KMMRegistrationResponse.h + * @ingroup p25_kmm + * @file KMMRegistrationResponse.cpp + * @ingroup p25_kmm + */ +#if !defined(__P25_KMM__KMM_REGISTRATION_RSP_H__) +#define __P25_KMM__KMM_REGISTRATION_RSP_H__ + +#include "common/Defines.h" +#include "common/p25/kmm/KMMFrame.h" +#include "common/Utils.h" + +#include +#include + +namespace p25 +{ + namespace kmm + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + /** + * @addtogroup p25_kmm + * @{ + */ + + const uint32_t KMM_REGISTRATION_RSP_LENGTH = KMM_FRAME_LENGTH + 1U; + + /** @} */ + + // --------------------------------------------------------------------------- + // Class Declaration + // --------------------------------------------------------------------------- + + class HOST_SW_API KMMRegistrationResponse : public KMMFrame { + public: + /** + * @brief Initializes a new instance of the KMMRegistrationResponse class. + */ + KMMRegistrationResponse(); + /** + * @brief Finalizes a instance of the KMMRegistrationResponse class. + */ + ~KMMRegistrationResponse(); + + /** + * @brief Decode a KMM deregistration response. + * @param[in] data Buffer containing KMM frame data to decode. + * @returns bool True, if decoded, otherwise false. + */ + bool decode(const uint8_t* data) override; + /** + * @brief Encode a KMM deregistration response. + * @param[out] data Buffer to encode KMM frame data to. + */ + void encode(uint8_t* data) override; + + public: + /** + * @brief + */ + __PROPERTY(uint8_t, status, Status); + + __COPY(KMMRegistrationResponse); + }; + } // namespace kmm +} // namespace p25 + +#endif // __P25_KMM__KMM_REGISTRATION_RSP_H__ diff --git a/src/common/p25/kmm/KMMZeroize.cpp b/src/common/p25/kmm/KMMZeroize.cpp new file mode 100644 index 00000000..ac31089b --- /dev/null +++ b/src/common/p25/kmm/KMMZeroize.cpp @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +#include "Defines.h" +#include "p25/P25Defines.h" +#include "p25/kmm/KMMZeroize.h" +#include "Log.h" + +using namespace p25; +using namespace p25::defines; +using namespace p25::kmm; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/* Initializes a new instance of the KMMZeroize class. */ + +KMMZeroize::KMMZeroize() : KMMFrame() +{ + m_messageId = KMM_MessageType::ZEROIZE_CMD; + m_respKind = KMM_ResponseKind::NONE; +} + +/* Finalizes a instance of the KMMZeroize class. */ + +KMMZeroize::~KMMZeroize() = default; + +/* Decode a KMM modify key. */ + +bool KMMZeroize::decode(const uint8_t* data) +{ + assert(data != nullptr); + + KMMFrame::decodeHeader(data); + + return true; +} + +/* Encode a KMM modify key. */ + +void KMMZeroize::encode(uint8_t* data) +{ + assert(data != nullptr); + m_messageLength = KMM_ZEROIZE_LENGTH; + + KMMFrame::encodeHeader(data); +} + +// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + +/* Internal helper to copy the the class. */ + +void KMMZeroize::copy(const KMMZeroize& data) +{ + KMMFrame::copy(data); +} diff --git a/src/common/p25/kmm/KMMZeroize.h b/src/common/p25/kmm/KMMZeroize.h new file mode 100644 index 00000000..69ef4a50 --- /dev/null +++ b/src/common/p25/kmm/KMMZeroize.h @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Digital Voice Modem - Common Library + * GPLv2 Open Source. Use is subject to license terms. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright (C) 2025 Bryan Biedenkapp, N2PLL + * + */ +/** + * @file KMMZeroize.h + * @ingroup p25_kmm + * @file KMMZeroize.cpp + * @ingroup p25_kmm + */ +#if !defined(__P25_KMM__KMM_ZEROIZE_H__) +#define __P25_KMM__KMM_ZEROIZE_H__ + +#include "common/Defines.h" +#include "common/p25/kmm/KMMFrame.h" +#include "common/Utils.h" + +#include +#include + +namespace p25 +{ + namespace kmm + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + /** + * @addtogroup p25_kmm + * @{ + */ + + const uint32_t KMM_ZEROIZE_LENGTH = KMM_FRAME_LENGTH; + + /** @} */ + + // --------------------------------------------------------------------------- + // Class Declaration + // --------------------------------------------------------------------------- + + class HOST_SW_API KMMZeroize : public KMMFrame { + public: + /** + * @brief Initializes a new instance of the KMMZeroize class. + */ + KMMZeroize(); + /** + * @brief Finalizes a instance of the KMMZeroize class. + */ + ~KMMZeroize(); + + /** + * @brief Decode a KMM hello. + * @param[in] data Buffer containing KMM frame data to decode. + * @returns bool True, if decoded, otherwise false. + */ + bool decode(const uint8_t* data) override; + /** + * @brief Encode a KMM hello. + * @param[out] data Buffer to encode KMM frame data to. + */ + void encode(uint8_t* data) override; + + public: + __COPY(KMMZeroize); + }; + } // namespace kmm +} // namespace p25 + +#endif // __P25_KMM__KMM_ZEROIZE_H__