From 05b0dbdbac38ea66672b5981ffd0aff8c950c2f6 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 18:19:46 +0000 Subject: [PATCH 01/32] Add whitespace after single line code sections in readme so they wrap onto a new line --- plugins/kinet/README.md | 6 +++--- plugins/uartdmx/README.md | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/kinet/README.md b/plugins/kinet/README.md index 68bca96c5f..e2872ec783 100644 --- a/plugins/kinet/README.md +++ b/plugins/kinet/README.md @@ -8,13 +8,13 @@ the Port Out (V2) modes of the KiNET protocol. ## Config file: `ola-kinet.conf` -`power_supply = ` +`power_supply = ` The IP of the power supply to send to. You can communicate with more than one power supply by adding multiple `power_supply =` lines. ### Per Power Supply Settings -`-mode = [dmxout|portout]` +`-mode = [dmxout|portout]` The mode of KiNET to send to the power supply. DMX Out is sometimes known as V1 and Port Out as V2. @@ -32,7 +32,7 @@ for the wildcard universe on each device. Instead, the universe for each device may be patched by assigning this output port to the intended universe in OLA. -`-ports = ` +`-ports = ` The number of physical ports available on the power supply in Port Out mode. Each physical port will create an OLA port that may be assigned to any universe. This setting is ignored in DMX Out mode. The default and maximum diff --git a/plugins/uartdmx/README.md b/plugins/uartdmx/README.md index 409b532d3f..79e1a7139a 100644 --- a/plugins/uartdmx/README.md +++ b/plugins/uartdmx/README.md @@ -12,10 +12,10 @@ http://eastertrail.blogspot.co.uk/2014/04/command-and-control-ii.html ## Config file: `ola-uartdmx.conf` -`enabled = true` +`enabled = true` Enable this plugin (DISABLED by default). -`device = /dev/ttyAMA0` +`device = /dev/ttyAMA0` The device to use for DMX output (optional). Multiple devices are supported if the hardware exists. On later software it may also be /dev/serial0. Using USB-serial adapters is not supported (try the @@ -24,8 +24,8 @@ Using USB-serial adapters is not supported (try the ### Per Device Settings (using above device name) -`-break = 100` +`-break = 100` The DMX break time in microseconds for this device (optional). -`-malf = 100` +`-malf = 100` The Mark After Last Frame time in microseconds for this device (optional). From e85c5a59c8bd6131307a245f352aebc9a1b377f6 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 20:00:03 +0000 Subject: [PATCH 02/32] Fix a typo --- plugins/e131/E131Plugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/e131/E131Plugin.h b/plugins/e131/E131Plugin.h index fed52781b3..1bcfced735 100644 --- a/plugins/e131/E131Plugin.h +++ b/plugins/e131/E131Plugin.h @@ -14,7 +14,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * E131Plugin.h - * Interface for the E1.131 plugin class + * Interface for the E1.31 plugin class * Copyright (C) 2007 Simon Newton */ From 2e0d488a19291869fca965e3de79c4d3a4678d7a Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 6 Feb 2020 15:00:48 +0000 Subject: [PATCH 03/32] Initial handling of LLRPProbeRequest PDUs (cherry picked from commit f3b751195ab17d9796dfc4cc3eaa89a8db200699) --- libs/acn/LLRPProbeRequestInflator.cpp | 119 ++++++++++++++++++++++++++ libs/acn/LLRPProbeRequestInflator.h | 71 +++++++++++++++ libs/acn/Makefile.mk | 2 + 3 files changed, 192 insertions(+) create mode 100644 libs/acn/LLRPProbeRequestInflator.cpp create mode 100644 libs/acn/LLRPProbeRequestInflator.h diff --git a/libs/acn/LLRPProbeRequestInflator.cpp b/libs/acn/LLRPProbeRequestInflator.cpp new file mode 100644 index 0000000000..cbc2fff04d --- /dev/null +++ b/libs/acn/LLRPProbeRequestInflator.cpp @@ -0,0 +1,119 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * LLRPProbeRequestInflator.cpp + * The Inflator for the LLRP Probe Request PDUs + * Copyright (C) 2020 Peter Newman + */ + +#include +#include +#include "ola/Logging.h" +#include "include/ola/rdm/UID.h" +#include "include/ola/rdm/UIDSet.h" +#include "include/ola/strings/Format.h" +#include "libs/acn/LLRPProbeRequestInflator.h" +#include "libs/acn/LLRPProbeRequestPDU.h" + +namespace ola { +namespace acn { + +using ola::acn::LLRPProbeRequestPDU; +using ola::rdm::UID; +using ola::rdm::UIDSet; + +/** + * Create a new LLRP Probe Request inflator + */ +LLRPProbeRequestInflator::LLRPProbeRequestInflator() + : BaseInflator(PDU::ONE_BYTE) { +} + +/** + * Set a RDMHandler to run when receiving a RDM message. + * @param handler the callback to invoke when there is rdm data for this + * universe. + */ +void LLRPProbeRequestInflator::SetLLRPProbeRequestHandler( + LLRPProbeRequestHandler *handler) { + m_llrp_probe_request_handler.reset(handler); +} + + +/* + * Decode the LLRP Probe Request 'header', which is 0 bytes in length. + * @param headers the HeaderSet to add to + * @param data a pointer to the data + * @param length length of the data + * @returns true if successful, false otherwise + */ +bool LLRPProbeRequestInflator::DecodeHeader(HeaderSet *, + const uint8_t*, + unsigned int, + unsigned int *bytes_used) { + *bytes_used = 0; + return true; +} + + +/* + * Handle a LLRP Probe Request PDU for E1.33. + */ +bool LLRPProbeRequestInflator::HandlePDUData(uint32_t vector, + const HeaderSet &headers, + const uint8_t *data, + unsigned int pdu_len) { + if (vector != LLRPProbeRequestPDU::VECTOR_PROBE_REQUEST_DATA) { + OLA_INFO << "Not a probe request, vector was " << vector; + return true; + } + + ola::strings::FormatData(&std::cout, data, pdu_len); + + LLRPProbeRequestPDU::llrp_probe_request_pdu_data pdu_data; + if (pdu_len > sizeof(pdu_data)) { + OLA_WARN << "Got too much data, received " << pdu_len << " only expecting " + << sizeof(pdu_data); + return false; + } + + unsigned int known_uids_size = static_cast( + pdu_len - (sizeof(pdu_data) - + sizeof(pdu_data.known_uids))); + if (known_uids_size % UID::UID_SIZE != 0) { + OLA_WARN << "Got a partial known UID, received " << known_uids_size << " bytes"; + return false; + } + + memcpy(reinterpret_cast(&pdu_data), data, sizeof(pdu_data)); + + OLA_DEBUG << "Probe from " << UID(pdu_data.lower_uid) << " to " << UID(pdu_data.upper_uid); + +// string rdm_message(reinterpret_cast(&data[0]), pdu_len); + + if (m_llrp_probe_request_handler.get()) { + m_llrp_probe_request_handler->Run(&headers, + UID(pdu_data.lower_uid), + UID(pdu_data.upper_uid) +//, +// UIDSet() +); + } else { + OLA_WARN << "No LLRP Probe Request handler defined!"; + } + return true; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/LLRPProbeRequestInflator.h b/libs/acn/LLRPProbeRequestInflator.h new file mode 100644 index 0000000000..1d63b84e9f --- /dev/null +++ b/libs/acn/LLRPProbeRequestInflator.h @@ -0,0 +1,71 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * LLRPProbeRequestInflator.h + * Copyright (C) 2020 Peter Newman + */ + +#ifndef LIBS_ACN_LLRPPROBEREQUESTINFLATOR_H_ +#define LIBS_ACN_LLRPPROBEREQUESTINFLATOR_H_ + +#include "ola/Callback.h" +#include "ola/acn/ACNVectors.h" +#include "ola/rdm/UID.h" +#include "ola/rdm/UIDSet.h" +#include "libs/acn/BaseInflator.h" +#include "libs/acn/HeaderSet.h" + +namespace ola { +namespace acn { + +class LLRPProbeRequestInflator: public BaseInflator { + friend class LLRPProbeRequestInflatorTest; + + public: + // These are pointers so the callers don't have to pull in all the headers. + typedef ola::Callback3 LLRPProbeRequestHandler; + + LLRPProbeRequestInflator(); + ~LLRPProbeRequestInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_LLRP_PROBE_REQUEST; } + + void SetLLRPProbeRequestHandler(LLRPProbeRequestHandler *handler); + + protected: + bool DecodeHeader(HeaderSet *headers, + const uint8_t *data, + unsigned int len, + unsigned int *bytes_used); + + void ResetHeaderField() {} // namespace noop + + virtual bool HandlePDUData(uint32_t vector, + const HeaderSet &headers, + const uint8_t *data, + unsigned int pdu_len); + + private: + std::auto_ptr m_llrp_probe_request_handler; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_LLRPPROBEREQUESTINFLATOR_H_ diff --git a/libs/acn/Makefile.mk b/libs/acn/Makefile.mk index b203c5b258..7c81ef9031 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -66,6 +66,8 @@ libs_acn_libolae131core_la_SOURCES = \ libs/acn/LLRPInflator.h \ libs/acn/LLRPProbeReplyPDU.cpp \ libs/acn/LLRPProbeReplyPDU.h \ + libs/acn/LLRPProbeRequestInflator.cpp \ + libs/acn/LLRPProbeRequestInflator.h \ libs/acn/LLRPProbeRequestPDU.cpp \ libs/acn/LLRPProbeRequestPDU.h \ libs/acn/LLRPPDU.cpp \ From f608d4e86982df68c9f0a36627215e1461a2cbb6 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 11 Feb 2020 00:08:26 +0000 Subject: [PATCH 04/32] Allow the RDMInflator to be used with both native E1.33 and LLRP RDM messages (cherry picked from commit 1955638b07cb996447b8ba3c7274ce79514d244e) --- libs/acn/RDMInflator.cpp | 25 +++++++++++++++++++------ libs/acn/RDMInflator.h | 12 ++++++++++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/libs/acn/RDMInflator.cpp b/libs/acn/RDMInflator.cpp index a18f634e01..a4e32166e1 100644 --- a/libs/acn/RDMInflator.cpp +++ b/libs/acn/RDMInflator.cpp @@ -32,13 +32,14 @@ using std::string; /** * Create a new RDM inflator */ -RDMInflator::RDMInflator() - : BaseInflator(PDU::ONE_BYTE) { +RDMInflator::RDMInflator(unsigned int vector) + : BaseInflator(PDU::ONE_BYTE), + m_vector(vector) { } /** - * Set a RDMHandler to run when receiving a RDM message. - * @param handler the callback to invoke when there is rdm data for this + * Set an RDMMessageHandler to run when receiving a RDM message. + * @param handler the callback to invoke when there is RDM data for this * universe. */ void RDMInflator::SetRDMHandler(RDMMessageHandler *handler) { @@ -46,6 +47,16 @@ void RDMInflator::SetRDMHandler(RDMMessageHandler *handler) { } +/** + * Set a GenericRDMHandler to run when receiving a RDM message. + * @param handler the callback to invoke when there is RDM data for this + * universe. + */ +void RDMInflator::SetGenericRDMHandler(GenericRDMMessageHandler *handler) { + m_generic_rdm_handler.reset(handler); +} + + /* * Decode the RDM 'header', which is 0 bytes in length. * @param headers the HeaderSet to add to @@ -76,11 +87,13 @@ bool RDMInflator::HandlePDUData(uint32_t vector, string rdm_message(reinterpret_cast(&data[0]), pdu_len); - E133Header e133_header = headers.GetE133Header(); - if (m_rdm_handler.get()) { + E133Header e133_header = headers.GetE133Header(); + m_rdm_handler->Run(&headers.GetTransportHeader(), &e133_header, rdm_message); + } else if (m_generic_rdm_handler.get()) { + m_generic_rdm_handler->Run(&headers, rdm_message); } else { OLA_WARN << "No RDM handler defined!"; } diff --git a/libs/acn/RDMInflator.h b/libs/acn/RDMInflator.h index 36ccf48930..4c37cf6c0c 100644 --- a/libs/acn/RDMInflator.h +++ b/libs/acn/RDMInflator.h @@ -41,12 +41,18 @@ class RDMInflator: public BaseInflator { const std::string& // rdm data > RDMMessageHandler; - RDMInflator(); + typedef ola::Callback2 GenericRDMMessageHandler; + + RDMInflator(unsigned int vector = ola::acn::VECTOR_FRAMING_RDMNET); ~RDMInflator() {} - uint32_t Id() const { return ola::acn::VECTOR_FRAMING_RDMNET; } + uint32_t Id() const { return m_vector; } void SetRDMHandler(RDMMessageHandler *handler); + void SetGenericRDMHandler(GenericRDMMessageHandler *handler); static const unsigned int VECTOR_RDMNET_DATA = 0xcc; @@ -65,6 +71,8 @@ class RDMInflator: public BaseInflator { private: std::auto_ptr m_rdm_handler; + std::auto_ptr m_generic_rdm_handler; + unsigned int m_vector; }; } // namespace acn } // namespace ola From 7e821e22576991024749ee98439d19432d356156 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 11 Feb 2020 00:53:01 +0000 Subject: [PATCH 05/32] Add the ability to pack an RDMPDU (cherry picked from commit 32ecc529a99a243c79afc85e5174bf6e8507ca3b) --- libs/acn/RDMPDU.cpp | 15 ++++++ libs/acn/RDMPDU.h | 24 +++++++++- libs/acn/RDMPDUTest.cpp | 103 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 1 deletion(-) diff --git a/libs/acn/RDMPDU.cpp b/libs/acn/RDMPDU.cpp index 7b7b61f6c8..cab7d20a5c 100644 --- a/libs/acn/RDMPDU.cpp +++ b/libs/acn/RDMPDU.cpp @@ -29,6 +29,21 @@ namespace acn { using ola::io::OutputStream; using ola::network::HostToNetwork; +unsigned int RDMPDU::DataSize() const { + return static_cast(m_command.size()); +} + +bool RDMPDU::PackData(uint8_t *data, unsigned int *length) const { + *length = static_cast(m_command.size()); + memcpy(data, reinterpret_cast(m_command.data()), *length); + return true; +} + +void RDMPDU::PackData(ola::io::OutputStream *stream) const { + stream->Write(reinterpret_cast(m_command.data()), + static_cast(m_command.size())); +} + void RDMPDU::PrependPDU(ola::io::IOStack *stack) { uint8_t vector = HostToNetwork(ola::rdm::START_CODE); stack->Write(reinterpret_cast(&vector), sizeof(vector)); diff --git a/libs/acn/RDMPDU.h b/libs/acn/RDMPDU.h index 8d36e0ced7..c51d9a140f 100644 --- a/libs/acn/RDMPDU.h +++ b/libs/acn/RDMPDU.h @@ -21,16 +21,38 @@ #ifndef LIBS_ACN_RDMPDU_H_ #define LIBS_ACN_RDMPDU_H_ +#include +#include #include +#include #include "libs/acn/PDU.h" namespace ola { namespace acn { -class RDMPDU : private PDU { +class RDMPDU : public PDU { public: + explicit RDMPDU(const ola::io::ByteString &command): + PDU(ola::rdm::START_CODE, ONE_BYTE, true), + m_command(command) {} + + unsigned int HeaderSize() const { return 0; } + bool PackHeader(OLA_UNUSED uint8_t *data, + unsigned int *length) const { + *length = 0; + return true; + } + void PackHeader(OLA_UNUSED ola::io::OutputStream *stream) const {} + + unsigned int DataSize() const; + bool PackData(uint8_t *data, unsigned int *length) const; + void PackData(ola::io::OutputStream *stream) const; + static void PrependPDU(ola::io::IOStack *stack); + + private: + const ola::io::ByteString m_command; }; } // namespace acn } // namespace ola diff --git a/libs/acn/RDMPDUTest.cpp b/libs/acn/RDMPDUTest.cpp index 4c6ce89df2..ff6489d0fb 100644 --- a/libs/acn/RDMPDUTest.cpp +++ b/libs/acn/RDMPDUTest.cpp @@ -23,6 +23,8 @@ #include #include "ola/Logging.h" +#include "ola/io/ByteString.h" +#include "ola/io/IOQueue.h" #include "ola/io/IOStack.h" #include "ola/network/NetworkUtils.h" #include "ola/testing/TestUtils.h" @@ -32,24 +34,125 @@ namespace ola { namespace acn { +using ola::io::ByteString; +using ola::io::IOQueue; using ola::io::IOStack; +using ola::io::OutputStream; +using ola::network::HostToNetwork; class RDMPDUTest: public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(RDMPDUTest); + CPPUNIT_TEST(testSimpleRDMPDU); + CPPUNIT_TEST(testSimpleRDMPDUToOutputStream); CPPUNIT_TEST(testPrepend); CPPUNIT_TEST_SUITE_END(); public: + void testSimpleRDMPDU(); + void testSimpleRDMPDUToOutputStream(); void testPrepend(); private: static const unsigned int TEST_VECTOR; + static const uint8_t EXPECTED_GET_RESPONSE_BUFFER[]; }; CPPUNIT_TEST_SUITE_REGISTRATION(RDMPDUTest); const unsigned int RDMPDUTest::TEST_VECTOR = 0xcc; +const uint8_t RDMPDUTest::EXPECTED_GET_RESPONSE_BUFFER[] = { + 1, 28, // sub code & length + 0, 3, 0, 0, 0, 4, // dst uid + 0, 1, 0, 0, 0, 2, // src uid + 0, 0, 0, 0, 10, // transaction, port id, msg count & sub device + 0x21, 1, 40, 4, // command, param id, param data length + 0x5a, 0x5a, 0x5a, 0x5a, // param data + 0x02, 0xb3 // checksum +}; + +/* + * Test that packing an RDMPDU works. + */ +void RDMPDUTest::testSimpleRDMPDU() { + ByteString empty; + RDMPDU empty_pdu(empty); + + OLA_ASSERT_EQ(0u, empty_pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, empty_pdu.DataSize()); + OLA_ASSERT_EQ(4u, empty_pdu.Size()); + + ByteString response(EXPECTED_GET_RESPONSE_BUFFER, + sizeof(EXPECTED_GET_RESPONSE_BUFFER)); + RDMPDU pdu(response); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(29u, pdu.DataSize()); + OLA_ASSERT_EQ(33u, pdu.Size()); + + unsigned int size = pdu.Size(); + uint8_t *data = new uint8_t[size]; + unsigned int bytes_used = size; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + + // spot check the data + OLA_ASSERT_EQ((uint8_t) 0xf0, data[0]); + // bytes_used is technically data[1] and data[2] if > 255 + OLA_ASSERT_EQ((uint8_t) bytes_used, data[2]); + OLA_ASSERT_EQ(HostToNetwork((uint8_t) TEST_VECTOR), data[3]); + + // test undersized buffer + bytes_used = size - 1; + OLA_ASSERT_FALSE(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(0u, bytes_used); + + // test oversized buffer + bytes_used = size + 1; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + delete[] data; +} + + +/* + * Test that writing to an output stream works. + */ +void RDMPDUTest::testSimpleRDMPDUToOutputStream() { + ByteString response(EXPECTED_GET_RESPONSE_BUFFER, + sizeof(EXPECTED_GET_RESPONSE_BUFFER)); + RDMPDU pdu(response); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(29u, pdu.DataSize()); + OLA_ASSERT_EQ(33u, pdu.Size()); + + IOQueue output; + OutputStream stream(&output); + pdu.Write(&stream); + OLA_ASSERT_EQ(33u, output.Size()); + + uint8_t *pdu_data = new uint8_t[output.Size()]; + unsigned int pdu_size = output.Peek(pdu_data, output.Size()); + OLA_ASSERT_EQ(output.Size(), pdu_size); + + uint8_t EXPECTED[] = { + 0xf0, 0x00, 0x21, + 0xcc, + 1, 28, // sub code & length + 0, 3, 0, 0, 0, 4, // dst uid + 0, 1, 0, 0, 0, 2, // src uid + 0, 0, 0, 0, 10, // transaction, port id, msg count & sub device + 0x21, 1, 40, 4, // command, param id, param data length + 0x5a, 0x5a, 0x5a, 0x5a, // param data + 0x02, 0xb3 // checksum + }; + OLA_ASSERT_DATA_EQUALS(EXPECTED, sizeof(EXPECTED), pdu_data, pdu_size); + output.Pop(output.Size()); + delete[] pdu_data; +} + + void RDMPDUTest::testPrepend() { IOStack stack; RDMPDU::PrependPDU(&stack); From 76d73f330e6f1c19f5e5610342aad70e13e90e09 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 18 Feb 2020 05:41:54 +0000 Subject: [PATCH 06/32] Add the ability to inflate an LLRP Probe Reply and build a Probe Request (cherry picked from commit 8db5131776b31ada6cf78a0bd6c78a280840432b) --- libs/acn/LLRPProbeReplyInflator.cpp | 107 +++++++++++++++++++++++++ libs/acn/LLRPProbeReplyInflator.h | 79 +++++++++++++++++++ libs/acn/LLRPProbeRequestPDU.cpp | 50 ++++++++++++ libs/acn/LLRPProbeRequestPDU.h | 34 +++++++- libs/acn/LLRPProbeRequestPDUTest.cpp | 112 +++++++++++++++++++++++++++ libs/acn/Makefile.mk | 2 + 6 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 libs/acn/LLRPProbeReplyInflator.cpp create mode 100644 libs/acn/LLRPProbeReplyInflator.h diff --git a/libs/acn/LLRPProbeReplyInflator.cpp b/libs/acn/LLRPProbeReplyInflator.cpp new file mode 100644 index 0000000000..153433c166 --- /dev/null +++ b/libs/acn/LLRPProbeReplyInflator.cpp @@ -0,0 +1,107 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * LLRPProbeReplyInflator.cpp + * The Inflator for the LLRP Probe Reply PDUs + * Copyright (C) 2020 Peter Newman + */ + +#include +#include +#include "ola/Logging.h" +#include "include/ola/rdm/UID.h" +#include "include/ola/rdm/UIDSet.h" +#include "include/ola/strings/Format.h" +#include "libs/acn/LLRPProbeReplyInflator.h" +#include "libs/acn/LLRPProbeReplyPDU.h" + +namespace ola { +namespace acn { + +using ola::acn::LLRPProbeReplyPDU; +using ola::rdm::UID; +using ola::rdm::UIDSet; + +/** + * Create a new LLRP Probe Reply inflator + */ +LLRPProbeReplyInflator::LLRPProbeReplyInflator() + : BaseInflator(PDU::ONE_BYTE) { +} + +/** + * Set an LLRPProbeReplyHandler to run when receiving an LLRP Probe Reply + * message. + * @param handler the callback to invoke when there is and LLRP Probe Reply. + */ +void LLRPProbeReplyInflator::SetLLRPProbeReplyHandler( + LLRPProbeReplyHandler *handler) { + m_llrp_probe_reply_handler.reset(handler); +} + + +/* + * Decode the LLRP Probe Reply 'header', which is 0 bytes in length. + * @param headers the HeaderSet to add to + * @param data a pointer to the data + * @param length length of the data + * @returns true if successful, false otherwise + */ +bool LLRPProbeReplyInflator::DecodeHeader(HeaderSet *, + const uint8_t*, + unsigned int, + unsigned int *bytes_used) { + *bytes_used = 0; + return true; +} + + +/* + * Handle a LLRP Probe Reply PDU for E1.33. + */ +bool LLRPProbeReplyInflator::HandlePDUData(uint32_t vector, + const HeaderSet &headers, + const uint8_t *data, + unsigned int pdu_len) { + if (vector != LLRPProbeReplyPDU::VECTOR_PROBE_REPLY_DATA) { + OLA_INFO << "Not a probe reply, vector was " << vector; + return true; + } + + ola::strings::FormatData(&std::cout, data, pdu_len); + + LLRPProbeReplyPDU::llrp_probe_reply_pdu_data pdu_data; + if (pdu_len > sizeof(pdu_data)) { + OLA_WARN << "Got too much data, received " << pdu_len << " only expecting " + << sizeof(pdu_data); + return false; + } + + memcpy(reinterpret_cast(&pdu_data), data, sizeof(pdu_data)); + + OLA_DEBUG << "Probe from " << UID(pdu_data.target_uid); + + LLRPProbeReply reply(UID(pdu_data.target_uid)); + + if (m_llrp_probe_reply_handler.get()) { + m_llrp_probe_reply_handler->Run(&headers, + reply); + } else { + OLA_WARN << "No LLRP Probe Reply handler defined!"; + } + return true; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/LLRPProbeReplyInflator.h b/libs/acn/LLRPProbeReplyInflator.h new file mode 100644 index 0000000000..3aab45f7b1 --- /dev/null +++ b/libs/acn/LLRPProbeReplyInflator.h @@ -0,0 +1,79 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * LLRPProbeReplyInflator.h + * Copyright (C) 2020 Peter Newman + */ + +#ifndef LIBS_ACN_LLRPPROBEREPLYINFLATOR_H_ +#define LIBS_ACN_LLRPPROBEREPLYINFLATOR_H_ + +#include "ola/Callback.h" +#include "ola/acn/ACNVectors.h" +#include "ola/rdm/UID.h" +#include "ola/rdm/UIDSet.h" +#include "libs/acn/BaseInflator.h" +#include "libs/acn/HeaderSet.h" +#include "libs/acn/LLRPProbeReplyPDU.h" + +namespace ola { +namespace acn { + +class LLRPProbeReplyInflator: public BaseInflator { + friend class LLRPProbeReplyInflatorTest; + + public: + struct LLRPProbeReply { + LLRPProbeReply(const ola::rdm::UID &_uid) + : uid(_uid) { + } + ola::rdm::UID uid; + ola::network::MACAddress hardware_address; + ola::acn::LLRPProbeReplyPDU::LLRPComponentType component_type; + }; + + + // These are pointers so the callers don't have to pull in all the headers. + typedef ola::Callback2 LLRPProbeReplyHandler; + + LLRPProbeReplyInflator(); + ~LLRPProbeReplyInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_LLRP_PROBE_REPLY; } + + void SetLLRPProbeReplyHandler(LLRPProbeReplyHandler *handler); + + protected: + bool DecodeHeader(HeaderSet *headers, + const uint8_t *data, + unsigned int len, + unsigned int *bytes_used); + + void ResetHeaderField() {} // namespace noop + + virtual bool HandlePDUData(uint32_t vector, + const HeaderSet &headers, + const uint8_t *data, + unsigned int pdu_len); + + private: + std::auto_ptr m_llrp_probe_reply_handler; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_LLRPPROBEREPLYINFLATOR_H_ diff --git a/libs/acn/LLRPProbeRequestPDU.cpp b/libs/acn/LLRPProbeRequestPDU.cpp index ba1623ed3a..a6ad150130 100644 --- a/libs/acn/LLRPProbeRequestPDU.cpp +++ b/libs/acn/LLRPProbeRequestPDU.cpp @@ -32,6 +32,56 @@ using ola::network::HostToNetwork; using ola::rdm::UID; using std::vector; +unsigned int LLRPProbeRequestPDU::DataSize() const { + llrp_probe_request_pdu_data data; + return static_cast(sizeof(llrp_probe_request_pdu_data) - + sizeof(data.known_uids) + + (m_known_uids.Size() * UID::LENGTH)); + +} + +bool LLRPProbeRequestPDU::PackData(uint8_t *data, unsigned int *length) const { + llrp_probe_request_pdu_data pdu_data; + m_lower_uid.Pack(pdu_data.lower_uid, sizeof(pdu_data.lower_uid)); + m_upper_uid.Pack(pdu_data.upper_uid, sizeof(pdu_data.upper_uid)); + uint16_t filter = 0; + if (m_client_tcp_connection_inactive) { + filter |= FILTER_CLIENT_TCP_CONNECTION_INACTIVE; + } + if (m_brokers_only) { + filter |= FILTER_BROKERS_ONLY; + } + pdu_data.filter = HostToNetwork(filter); + // TODO(Peter): We need to check we've got <= 200 UIDs here + m_known_uids.Pack(pdu_data.known_uids, sizeof(pdu_data.known_uids)); + *length = static_cast(sizeof(llrp_probe_request_pdu_data) - + sizeof(pdu_data.known_uids) + + (m_known_uids.Size() * UID::LENGTH)); + + memcpy(data, &pdu_data, *length); + return true; +} + +void LLRPProbeRequestPDU::PackData(ola::io::OutputStream *stream) const { + llrp_probe_request_pdu_data data; + m_lower_uid.Pack(data.lower_uid, sizeof(data.lower_uid)); + m_upper_uid.Pack(data.upper_uid, sizeof(data.upper_uid)); + uint16_t filter = 0; + if (m_client_tcp_connection_inactive) { + filter |= FILTER_CLIENT_TCP_CONNECTION_INACTIVE; + } + if (m_brokers_only) { + filter |= FILTER_BROKERS_ONLY; + } + data.filter = HostToNetwork(filter); + // TODO(Peter): We need to check we've got <= 200 UIDs here + m_known_uids.Pack(data.known_uids, sizeof(data.known_uids)); + stream->Write(reinterpret_cast(&data), + static_cast(sizeof(llrp_probe_request_pdu_data) - + sizeof(data.known_uids) + + (m_known_uids.Size() * UID::LENGTH))); +} + void LLRPProbeRequestPDU::PrependPDU(ola::io::IOStack *stack, const UID &lower_uid, const UID &upper_uid, diff --git a/libs/acn/LLRPProbeRequestPDU.h b/libs/acn/LLRPProbeRequestPDU.h index b39b768cf9..1a103eaf6e 100644 --- a/libs/acn/LLRPProbeRequestPDU.h +++ b/libs/acn/LLRPProbeRequestPDU.h @@ -30,8 +30,33 @@ namespace ola { namespace acn { -class LLRPProbeRequestPDU : private PDU { +class LLRPProbeRequestPDU : public PDU { public: + explicit LLRPProbeRequestPDU(unsigned int vector, + const ola::rdm::UID &lower_uid, + const ola::rdm::UID &upper_uid, + bool client_tcp_connection_inactive, + bool brokers_only, + const ola::rdm::UIDSet &known_uids): + PDU(vector, ONE_BYTE, true), + m_lower_uid(lower_uid), + m_upper_uid(upper_uid), + m_client_tcp_connection_inactive(client_tcp_connection_inactive), + m_brokers_only(brokers_only), + m_known_uids(known_uids) {} + + unsigned int HeaderSize() const { return 0; } + bool PackHeader(OLA_UNUSED uint8_t *data, + unsigned int *length) const { + *length = 0; + return true; + } + void PackHeader(OLA_UNUSED ola::io::OutputStream *stream) const {} + + unsigned int DataSize() const; + bool PackData(uint8_t *data, unsigned int *length) const; + void PackData(ola::io::OutputStream *stream) const; + static void PrependPDU(ola::io::IOStack *stack, const ola::rdm::UID &lower_uid, const ola::rdm::UID &upper_uid, @@ -56,6 +81,13 @@ class LLRPProbeRequestPDU : private PDU { uint8_t known_uids[ola::rdm::UID::LENGTH * LLRP_KNOWN_UID_SIZE]; }); typedef struct llrp_probe_request_pdu_data_s llrp_probe_request_pdu_data; + + private: + const ola::rdm::UID m_lower_uid; + const ola::rdm::UID m_upper_uid; + bool m_client_tcp_connection_inactive; + bool m_brokers_only; + const ola::rdm::UIDSet m_known_uids; }; } // namespace acn } // namespace ola diff --git a/libs/acn/LLRPProbeRequestPDUTest.cpp b/libs/acn/LLRPProbeRequestPDUTest.cpp index 6666002b6a..88f39d587c 100644 --- a/libs/acn/LLRPProbeRequestPDUTest.cpp +++ b/libs/acn/LLRPProbeRequestPDUTest.cpp @@ -23,7 +23,9 @@ #include #include "ola/Logging.h" +#include "ola/io/IOQueue.h" #include "ola/io/IOStack.h" +#include "ola/io/OutputStream.h" #include "ola/network/NetworkUtils.h" #include "ola/rdm/UID.h" #include "ola/rdm/UIDSet.h" @@ -34,16 +36,24 @@ namespace ola { namespace acn { +using ola::acn::LLRPProbeRequestPDU; +using ola::io::IOQueue; using ola::io::IOStack; +using ola::io::OutputStream; +using ola::network::HostToNetwork; using ola::rdm::UID; using ola::rdm::UIDSet; class LLRPProbeRequestPDUTest: public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(LLRPProbeRequestPDUTest); + CPPUNIT_TEST(testSimpleLLRPProbeRequestPDU); + CPPUNIT_TEST(testSimpleLLRPProbeRequestPDUToOutputStream); CPPUNIT_TEST(testPrepend); CPPUNIT_TEST_SUITE_END(); public: + void testSimpleLLRPProbeRequestPDU(); + void testSimpleLLRPProbeRequestPDUToOutputStream(); void testPrepend(); private: @@ -52,6 +62,108 @@ class LLRPProbeRequestPDUTest: public CppUnit::TestFixture { CPPUNIT_TEST_SUITE_REGISTRATION(LLRPProbeRequestPDUTest); +const unsigned int LLRPProbeRequestPDUTest::TEST_VECTOR = 39; + + +/* + * Test that packing a LLRPProbeRequestPDU works. + */ +void LLRPProbeRequestPDUTest::testSimpleLLRPProbeRequestPDU() { + UID lower_uid = UID(0x4321, 0x12345678); + UID upper_uid = UID(0x5678, 0x00abcdef); + UIDSet known_uids; + known_uids.AddUID(UID(0x1234, 0x00000001)); + known_uids.AddUID(UID(0x5678, 0x00000002)); + known_uids.AddUID(UID(0x4321, 0x56789abc)); + LLRPProbeRequestPDU pdu( + TEST_VECTOR, + lower_uid, + upper_uid, + false, + false, + known_uids); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(32u, pdu.DataSize()); + OLA_ASSERT_EQ(36u, pdu.Size()); + + unsigned int size = pdu.Size(); + uint8_t *data = new uint8_t[size]; + unsigned int bytes_used = size; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + + // spot check the data + OLA_ASSERT_EQ((uint8_t) 0xf0, data[0]); + // bytes_used is technically data[1] and data[2] if > 255 + OLA_ASSERT_EQ((uint8_t) bytes_used, data[2]); + OLA_ASSERT_EQ(HostToNetwork((uint8_t) TEST_VECTOR), data[3]); + + uint8_t buffer[UID::LENGTH]; + lower_uid.Pack(buffer, sizeof(buffer)); + OLA_ASSERT_DATA_EQUALS(&data[4], UID::LENGTH, buffer, sizeof(buffer)); + upper_uid.Pack(buffer, sizeof(buffer)); + OLA_ASSERT_DATA_EQUALS(&data[10], UID::LENGTH, buffer, sizeof(buffer)); + + // test undersized buffer + bytes_used = size - 1; + OLA_ASSERT_FALSE(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(0u, bytes_used); + + // test oversized buffer + bytes_used = size + 1; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + delete[] data; +} + +/* + * Test that writing to an output stream works. + */ +void LLRPProbeRequestPDUTest::testSimpleLLRPProbeRequestPDUToOutputStream() { + UID lower_uid = UID(0x4321, 0x12345678); + UID upper_uid = UID(0x5678, 0x00abcdef); + UIDSet known_uids; + known_uids.AddUID(UID(0x1234, 0x00000001)); + known_uids.AddUID(UID(0x5678, 0x00000002)); + known_uids.AddUID(UID(0x4321, 0x56789abc)); + LLRPProbeRequestPDU pdu( + TEST_VECTOR, + lower_uid, + upper_uid, + false, + false, + known_uids); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(32u, pdu.DataSize()); + OLA_ASSERT_EQ(36u, pdu.Size()); + + IOQueue output; + OutputStream stream(&output); + pdu.Write(&stream); + OLA_ASSERT_EQ(36u, output.Size()); + + uint8_t *pdu_data = new uint8_t[output.Size()]; + unsigned int pdu_size = output.Peek(pdu_data, output.Size()); + OLA_ASSERT_EQ(output.Size(), pdu_size); + + uint8_t EXPECTED[] = { + 0xf0, 0x00, 0x24, + 39, + 0x43, 0x21, 0x12, 0x34, 0x56, 0x78, + 0x56, 0x78, 0x00, 0xab, 0xcd, 0xef, + 0x00, 0x00, + 0x12, 0x34, 0, 0, 0, 1, + 0x43, 0x21, 0x56, 0x78, 0x9a, 0xbc, + 0x56, 0x78, 0, 0, 0, 2 + }; + OLA_ASSERT_DATA_EQUALS(EXPECTED, sizeof(EXPECTED), pdu_data, pdu_size); + output.Pop(output.Size()); + delete[] pdu_data; +} + + void LLRPProbeRequestPDUTest::testPrepend() { IOStack stack; UIDSet known_uids; diff --git a/libs/acn/Makefile.mk b/libs/acn/Makefile.mk index 7c81ef9031..a036a3f55a 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -64,6 +64,8 @@ libs_acn_libolae131core_la_SOURCES = \ libs/acn/LLRPHeader.h \ libs/acn/LLRPInflator.cpp \ libs/acn/LLRPInflator.h \ + libs/acn/LLRPProbeReplyInflator.cpp \ + libs/acn/LLRPProbeReplyInflator.h \ libs/acn/LLRPProbeReplyPDU.cpp \ libs/acn/LLRPProbeReplyPDU.h \ libs/acn/LLRPProbeRequestInflator.cpp \ From 090648309e270673dfb464d9bd78e38186026d6d Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 7 Mar 2023 14:44:52 +0000 Subject: [PATCH 07/32] First attempt at the E1.33 Broker PDU (cherry picked from commit c2126d1d1d686671db65c58bad9acd7b90243514) --- libs/acn/BrokerPDU.cpp | 68 ++++++++++++++++++++ libs/acn/BrokerPDU.h | 62 ++++++++++++++++++ libs/acn/BrokerPDUTest.cpp | 127 +++++++++++++++++++++++++++++++++++++ libs/acn/Makefile.mk | 3 + 4 files changed, 260 insertions(+) create mode 100644 libs/acn/BrokerPDU.cpp create mode 100644 libs/acn/BrokerPDU.h create mode 100644 libs/acn/BrokerPDUTest.cpp diff --git a/libs/acn/BrokerPDU.cpp b/libs/acn/BrokerPDU.cpp new file mode 100644 index 0000000000..8dcf9a844e --- /dev/null +++ b/libs/acn/BrokerPDU.cpp @@ -0,0 +1,68 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerPDU.cpp + * The BrokerPDU + * Copyright (C) 2023 Peter Newman + */ + + +#include "ola/Logging.h" +#include "ola/base/Array.h" +#include "ola/network/NetworkUtils.h" +#include "libs/acn/BrokerPDU.h" + +namespace ola { +namespace acn { + +using ola::io::OutputStream; +using ola::network::HostToNetwork; + +/* + * Size of the data portion + */ +unsigned int BrokerPDU::DataSize() const { + return m_pdu ? m_pdu->Size() : 0; +} + + +/* + * Pack the data portion. + */ +bool BrokerPDU::PackData(uint8_t *data, unsigned int *length) const { + if (m_pdu) + return m_pdu->Pack(data, length); + *length = 0; + return true; +} + + +/* + * Pack the data into a buffer + */ +void BrokerPDU::PackData(OutputStream *stream) const { + if (m_pdu) + m_pdu->Write(stream); +} + + +void BrokerPDU::PrependPDU(ola::io::IOStack *stack, + uint32_t vector) { + vector = HostToNetwork(vector); + stack->Write(reinterpret_cast(&vector), sizeof(vector)); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/BrokerPDU.h b/libs/acn/BrokerPDU.h new file mode 100644 index 0000000000..788f409b5a --- /dev/null +++ b/libs/acn/BrokerPDU.h @@ -0,0 +1,62 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerPDU.h + * Interface for the BrokerPDU class + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERPDU_H_ +#define LIBS_ACN_BROKERPDU_H_ + +#include +#include + +#include "libs/acn/PDU.h" +#include "libs/acn/BrokerHeader.h" + +namespace ola { +namespace acn { + +class BrokerPDU: public PDU { + public: + BrokerPDU(unsigned int vector, + const PDU *pdu): + PDU(vector, FOUR_BYTES, true), + m_pdu(pdu) {} + ~BrokerPDU() {} + + unsigned int HeaderSize() const { return 0; } + bool PackHeader(OLA_UNUSED uint8_t *data, + unsigned int *length) const { + *length = 0; + return true; + } + void PackHeader(OLA_UNUSED ola::io::OutputStream *stream) const {} + + unsigned int DataSize() const; + bool PackData(uint8_t *data, unsigned int *length) const; + + void PackData(ola::io::OutputStream *stream) const; + + static void PrependPDU(ola::io::IOStack *stack, + uint32_t vector); + + private: + const PDU *m_pdu; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERPDU_H_ diff --git a/libs/acn/BrokerPDUTest.cpp b/libs/acn/BrokerPDUTest.cpp new file mode 100644 index 0000000000..e4c2c6ef60 --- /dev/null +++ b/libs/acn/BrokerPDUTest.cpp @@ -0,0 +1,127 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerPDUTest.cpp + * Test fixture for the BrokerPDU class + * Copyright (C) 2023 Peter Newman + */ + +#include + +#include "ola/Logging.h" +#include "ola/io/IOQueue.h" +#include "ola/io/OutputStream.h" +#include "ola/network/NetworkUtils.h" +#include "ola/testing/TestUtils.h" +#include "libs/acn/BrokerPDU.h" +#include "libs/acn/PDUTestCommon.h" + + +namespace ola { +namespace acn { + +using ola::io::IOQueue; +using ola::io::OutputStream; +using ola::network::HostToNetwork; + +class BrokerPDUTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(BrokerPDUTest); + CPPUNIT_TEST(testSimpleBrokerPDU); + CPPUNIT_TEST(testSimpleBrokerPDUToOutputStream); + CPPUNIT_TEST_SUITE_END(); + + public: + void testSimpleBrokerPDU(); + void testSimpleBrokerPDUToOutputStream(); + + void setUp() { + ola::InitLogging(ola::OLA_LOG_DEBUG, ola::OLA_LOG_STDERR); + } + + private: + static const unsigned int TEST_VECTOR; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(BrokerPDUTest); + +const unsigned int BrokerPDUTest::TEST_VECTOR = 39; + + +/* + * Test that packing a BrokerPDU without data works. + */ +void BrokerPDUTest::testSimpleBrokerPDU() { + BrokerPDU pdu(TEST_VECTOR, NULL); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(7u, pdu.Size()); + + unsigned int size = pdu.Size(); + uint8_t *data = new uint8_t[size]; + unsigned int bytes_used = size; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + + // spot check the data + OLA_ASSERT_EQ((uint8_t) 0xf0, data[0]); + // bytes_used is technically data[1] and data[2] if > 255 + OLA_ASSERT_EQ((uint8_t) bytes_used, data[2]); + unsigned int actual_value; + memcpy(&actual_value, data + 3, sizeof(actual_value)); + OLA_ASSERT_EQ(HostToNetwork(TEST_VECTOR), actual_value); + + // test undersized buffer + bytes_used = size - 1; + OLA_ASSERT_FALSE(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(0u, bytes_used); + + // test oversized buffer + bytes_used = size + 1; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + delete[] data; +} + + +/* + * Test that writing to an output stream works. + */ +void BrokerPDUTest::testSimpleBrokerPDUToOutputStream() { + BrokerPDU pdu(TEST_VECTOR, NULL); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(7u, pdu.Size()); + + IOQueue output; + OutputStream stream(&output); + pdu.Write(&stream); + OLA_ASSERT_EQ(7u, output.Size()); + + uint8_t *pdu_data = new uint8_t[output.Size()]; + unsigned int pdu_size = output.Peek(pdu_data, output.Size()); + OLA_ASSERT_EQ(output.Size(), pdu_size); + + uint8_t EXPECTED[] = { + 0xf0, 0x00, 0x07, + 0, 0, 0, 39 + }; + OLA_ASSERT_DATA_EQUALS(EXPECTED, sizeof(EXPECTED), pdu_data, pdu_size); + output.Pop(output.Size()); + delete[] pdu_data; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/Makefile.mk b/libs/acn/Makefile.mk index a036a3f55a..82466ec2a3 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -31,6 +31,8 @@ noinst_LTLIBRARIES += libs/acn/libolae131core.la libs_acn_libolae131core_la_SOURCES = \ libs/acn/BaseInflator.cpp \ libs/acn/BaseInflator.h \ + libs/acn/BrokerPDU.cpp \ + libs/acn/BrokerPDU.h \ libs/acn/DMPAddress.cpp \ libs/acn/DMPAddress.h \ libs/acn/DMPE131Inflator.cpp \ @@ -146,6 +148,7 @@ libs_acn_E131Tester_LDADD = \ $(COMMON_TESTING_LIBS) libs_acn_E133Tester_SOURCES = \ + libs/acn/BrokerPDUTest.cpp \ libs/acn/E133InflatorTest.cpp \ libs/acn/E133PDUTest.cpp \ libs/acn/RDMPDUTest.cpp From a81c83d1829a795f456150cadb6ae0ff320dd587 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 7 Mar 2023 16:23:26 +0000 Subject: [PATCH 08/32] First attempt at BrokerClientEntryPDU (cherry picked from commit 2a43710c8e595911c2981ce08bf0dc47d5888f27) --- libs/acn/BrokerClientEntryHeader.h | 63 ++++++++++++ libs/acn/BrokerClientEntryPDU.cpp | 114 +++++++++++++++++++++ libs/acn/BrokerClientEntryPDU.h | 61 +++++++++++ libs/acn/BrokerClientEntryPDUTest.cpp | 141 ++++++++++++++++++++++++++ libs/acn/BrokerPDU.h | 1 - libs/acn/Makefile.mk | 4 + 6 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 libs/acn/BrokerClientEntryHeader.h create mode 100644 libs/acn/BrokerClientEntryPDU.cpp create mode 100644 libs/acn/BrokerClientEntryPDU.h create mode 100644 libs/acn/BrokerClientEntryPDUTest.cpp diff --git a/libs/acn/BrokerClientEntryHeader.h b/libs/acn/BrokerClientEntryHeader.h new file mode 100644 index 0000000000..d2277d9671 --- /dev/null +++ b/libs/acn/BrokerClientEntryHeader.h @@ -0,0 +1,63 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerClientEntryHeader.h + * The E1.33 Broker Client Entry Header + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERCLIENTENTRYHEADER_H_ +#define LIBS_ACN_BROKERCLIENTENTRYHEADER_H_ + +#include +#include + +#include + +namespace ola { +namespace acn { + +// TODO(Peter): I think technically this probably shouldn't be a header and +// instead is just data at this level! +/* + * Header for the Broker Client Entry level + */ +class BrokerClientEntryHeader { + public: + BrokerClientEntryHeader() {} + + BrokerClientEntryHeader(const ola::acn::CID &client_cid) + : m_client_cid(client_cid) { + } + ~BrokerClientEntryHeader() {} + + const ola::acn::CID ClientCid() const { return m_client_cid; } + + bool operator==(const BrokerClientEntryHeader &other) const { + return m_client_cid == other.m_client_cid; + } + + PACK( + struct broker_client_entry_pdu_header_s { + uint8_t client_cid[CID::CID_LENGTH]; + }); + typedef struct broker_client_entry_pdu_header_s broker_client_entry_pdu_header; + + private: + ola::acn::CID m_client_cid; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERCLIENTENTRYHEADER_H_ diff --git a/libs/acn/BrokerClientEntryPDU.cpp b/libs/acn/BrokerClientEntryPDU.cpp new file mode 100644 index 0000000000..521604e742 --- /dev/null +++ b/libs/acn/BrokerClientEntryPDU.cpp @@ -0,0 +1,114 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerClientEntryPDU.cpp + * The BrokerClientEntryPDU + * Copyright (C) 2023 Peter Newman + */ + + +#include "ola/Logging.h" +#include "ola/base/Array.h" +#include "ola/network/NetworkUtils.h" +#include "libs/acn/BrokerClientEntryPDU.h" + +namespace ola { +namespace acn { + +using ola::io::OutputStream; +using ola::network::HostToNetwork; + +/* + * Size of the header portion. + */ +unsigned int BrokerClientEntryPDU::HeaderSize() const { + return sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header); +} + + +/* + * Size of the data portion + */ +unsigned int BrokerClientEntryPDU::DataSize() const { + return m_pdu ? m_pdu->Size() : 0; +} + + +/* + * Pack the header portion. + */ +bool BrokerClientEntryPDU::PackHeader(uint8_t *data, unsigned int *length) const { + unsigned int header_size = HeaderSize(); + + if (*length < header_size) { + OLA_WARN << "BrokerClientEntryPDU::PackHeader: buffer too small, got " << *length + << " required " << header_size; + *length = 0; + return false; + } + + BrokerClientEntryHeader::broker_client_entry_pdu_header header; + m_header.ClientCid().Pack(header.client_cid); + *length = sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header); + memcpy(data, &header, *length); + return true; +} + + +/* + * Pack the data portion. + */ +bool BrokerClientEntryPDU::PackData(uint8_t *data, unsigned int *length) const { + if (m_pdu) + return m_pdu->Pack(data, length); + *length = 0; + return true; +} + + +/* + * Pack the header into a buffer. + */ +void BrokerClientEntryPDU::PackHeader(OutputStream *stream) const { + BrokerClientEntryHeader::broker_client_entry_pdu_header header; + m_header.ClientCid().Pack(header.client_cid); + stream->Write(reinterpret_cast(&header), + sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header)); +} + + +/* + * Pack the data into a buffer + */ +void BrokerClientEntryPDU::PackData(OutputStream *stream) const { + if (m_pdu) + m_pdu->Write(stream); +} + + +void BrokerClientEntryPDU::PrependPDU(ola::io::IOStack *stack, + uint32_t vector, + const ola::acn::CID &client_cid) { + BrokerClientEntryHeader::broker_client_entry_pdu_header header; + client_cid.Pack(header.client_cid); + stack->Write(reinterpret_cast(&header), + sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header)); + + vector = HostToNetwork(vector); + stack->Write(reinterpret_cast(&vector), sizeof(vector)); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/BrokerClientEntryPDU.h b/libs/acn/BrokerClientEntryPDU.h new file mode 100644 index 0000000000..cd6c83b4eb --- /dev/null +++ b/libs/acn/BrokerClientEntryPDU.h @@ -0,0 +1,61 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerClientEntryPDU.h + * Interface for the BrokerClientEntryPDU class + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERCLIENTENTRYPDU_H_ +#define LIBS_ACN_BROKERCLIENTENTRYPDU_H_ + +#include +#include + +#include "libs/acn/PDU.h" +#include "libs/acn/BrokerClientEntryHeader.h" + +namespace ola { +namespace acn { + +class BrokerClientEntryPDU: public PDU { + public: + BrokerClientEntryPDU(unsigned int vector, + const BrokerClientEntryHeader &header, + const PDU *pdu): + PDU(vector, FOUR_BYTES, true), + m_header(header), + m_pdu(pdu) {} + ~BrokerClientEntryPDU() {} + + unsigned int HeaderSize() const; + unsigned int DataSize() const; + bool PackHeader(uint8_t *data, unsigned int *length) const; + bool PackData(uint8_t *data, unsigned int *length) const; + + void PackHeader(ola::io::OutputStream *stream) const; + void PackData(ola::io::OutputStream *stream) const; + + static void PrependPDU(ola::io::IOStack *stack, + uint32_t vector, + const ola::acn::CID &client_cid); + + private: + BrokerClientEntryHeader m_header; + const PDU *m_pdu; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERCLIENTENTRYPDU_H_ diff --git a/libs/acn/BrokerClientEntryPDUTest.cpp b/libs/acn/BrokerClientEntryPDUTest.cpp new file mode 100644 index 0000000000..bdeedc3175 --- /dev/null +++ b/libs/acn/BrokerClientEntryPDUTest.cpp @@ -0,0 +1,141 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerClientEntryPDUTest.cpp + * Test fixture for the BrokerClientEntryPDU class + * Copyright (C) 2023 Peter Newman + */ + +#include + +#include "ola/Logging.h" +#include "ola/io/IOQueue.h" +#include "ola/io/OutputStream.h" +#include "ola/network/NetworkUtils.h" +#include "ola/testing/TestUtils.h" +#include "libs/acn/BrokerClientEntryPDU.h" +#include "libs/acn/PDUTestCommon.h" + + +namespace ola { +namespace acn { + +using ola::io::IOQueue; +using ola::io::OutputStream; +using ola::network::HostToNetwork; + +class BrokerClientEntryPDUTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(BrokerClientEntryPDUTest); + CPPUNIT_TEST(testSimpleBrokerClientEntryPDU); + CPPUNIT_TEST(testSimpleBrokerClientEntryPDUToOutputStream); + CPPUNIT_TEST_SUITE_END(); + + public: + void testSimpleBrokerClientEntryPDU(); + void testSimpleBrokerClientEntryPDUToOutputStream(); + + void setUp() { + ola::InitLogging(ola::OLA_LOG_DEBUG, ola::OLA_LOG_STDERR); + } + + private: + static const unsigned int TEST_VECTOR; + static const uint8_t TEST_DATA[]; +}; + +const uint8_t BrokerClientEntryPDUTest::TEST_DATA[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15}; + +CPPUNIT_TEST_SUITE_REGISTRATION(BrokerClientEntryPDUTest); + +const unsigned int BrokerClientEntryPDUTest::TEST_VECTOR = 39; + + +/* + * Test that packing a BrokerClientEntryPDU without data works. + */ +void BrokerClientEntryPDUTest::testSimpleBrokerClientEntryPDU() { + const CID client_cid = CID::FromData(TEST_DATA); + BrokerClientEntryHeader header(client_cid); + BrokerClientEntryPDU pdu(TEST_VECTOR, header, NULL); + + OLA_ASSERT_EQ(16u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(23u, pdu.Size()); + + unsigned int size = pdu.Size(); + uint8_t *data = new uint8_t[size]; + unsigned int bytes_used = size; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + + // spot check the data + OLA_ASSERT_EQ((uint8_t) 0xf0, data[0]); + // bytes_used is technically data[1] and data[2] if > 255 + OLA_ASSERT_EQ((uint8_t) bytes_used, data[2]); + unsigned int actual_value; + memcpy(&actual_value, data + 3, sizeof(actual_value)); + OLA_ASSERT_EQ(HostToNetwork(TEST_VECTOR), actual_value); + + uint8_t buffer[CID::CID_LENGTH]; + client_cid.Pack(buffer); + OLA_ASSERT_DATA_EQUALS(&data[7], CID::CID_LENGTH, buffer, sizeof(buffer)); + + // test undersized buffer + bytes_used = size - 1; + OLA_ASSERT_FALSE(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(0u, bytes_used); + + // test oversized buffer + bytes_used = size + 1; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + delete[] data; +} + + +/* + * Test that writing to an output stream works. + */ +void BrokerClientEntryPDUTest::testSimpleBrokerClientEntryPDUToOutputStream() { + const ola::acn::CID client_cid = CID::FromData(TEST_DATA); + BrokerClientEntryHeader header(client_cid); + BrokerClientEntryPDU pdu(TEST_VECTOR, header, NULL); + + OLA_ASSERT_EQ(16u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(23u, pdu.Size()); + + IOQueue output; + OutputStream stream(&output); + pdu.Write(&stream); + OLA_ASSERT_EQ(23u, output.Size()); + + uint8_t *pdu_data = new uint8_t[output.Size()]; + unsigned int pdu_size = output.Peek(pdu_data, output.Size()); + OLA_ASSERT_EQ(output.Size(), pdu_size); + + uint8_t EXPECTED[] = { + 0xf0, 0x00, 0x17, + 0, 0, 0, 39, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15 + }; + OLA_ASSERT_DATA_EQUALS(EXPECTED, sizeof(EXPECTED), pdu_data, pdu_size); + output.Pop(output.Size()); + delete[] pdu_data; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/BrokerPDU.h b/libs/acn/BrokerPDU.h index 788f409b5a..9c6b50322b 100644 --- a/libs/acn/BrokerPDU.h +++ b/libs/acn/BrokerPDU.h @@ -25,7 +25,6 @@ #include #include "libs/acn/PDU.h" -#include "libs/acn/BrokerHeader.h" namespace ola { namespace acn { diff --git a/libs/acn/Makefile.mk b/libs/acn/Makefile.mk index 82466ec2a3..965052a1d8 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -31,6 +31,9 @@ noinst_LTLIBRARIES += libs/acn/libolae131core.la libs_acn_libolae131core_la_SOURCES = \ libs/acn/BaseInflator.cpp \ libs/acn/BaseInflator.h \ + libs/acn/BrokerClientEntryHeader.h \ + libs/acn/BrokerClientEntryPDU.cpp \ + libs/acn/BrokerClientEntryPDU.h \ libs/acn/BrokerPDU.cpp \ libs/acn/BrokerPDU.h \ libs/acn/DMPAddress.cpp \ @@ -148,6 +151,7 @@ libs_acn_E131Tester_LDADD = \ $(COMMON_TESTING_LIBS) libs_acn_E133Tester_SOURCES = \ + libs/acn/BrokerClientEntryPDUTest.cpp \ libs/acn/BrokerPDUTest.cpp \ libs/acn/E133InflatorTest.cpp \ libs/acn/E133PDUTest.cpp \ From cf6c53b63d55f05b9c8d13bf90ae242af7303d68 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 7 Mar 2023 23:52:15 +0000 Subject: [PATCH 09/32] First go at BrokerConnectPDU, could do with more tests (cherry picked from commit 19eca6fd3ad371c010ca32005b78d12082b34e18) --- include/ola/acn/ACNVectors.h | 21 ++++ include/ola/rdm/RDMEnums.h | 3 + libs/acn/BrokerConnectPDU.cpp | 123 ++++++++++++++++++ libs/acn/BrokerConnectPDU.h | 84 +++++++++++++ libs/acn/BrokerConnectPDUTest.cpp | 199 ++++++++++++++++++++++++++++++ libs/acn/Makefile.mk | 3 + 6 files changed, 433 insertions(+) create mode 100644 libs/acn/BrokerConnectPDU.cpp create mode 100644 libs/acn/BrokerConnectPDU.h create mode 100644 libs/acn/BrokerConnectPDUTest.cpp diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index b058beb810..712d72d628 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -214,6 +214,27 @@ enum ClientProtocolCode { CLIENT_PROTOCOL_EPT = 0x0000000B, /**< Broker EPT Client Entry */ }; +/** + * @brief Vectors used at the E1.33 Broker layer. + */ +enum BrokerVector { + VECTOR_BROKER_CONNECT = 0x0001, /**< Broker Client Connect */ + VECTOR_BROKER_CONNECT_REPLY = 0x0002, /**< Broker Connect Reply */ + VECTOR_BROKER_CLIENT_ENTRY_UPDATE = 0x0003, /**< Broker Client Entry Update */ + VECTOR_BROKER_REDIRECT_V4 = 0x0004, /**< Broker Client Redirect IPv4 */ + VECTOR_BROKER_REDIRECT_V6 = 0x0005, /**< Broker Client Redirect IPv6 */ + VECTOR_BROKER_FETCH_CLIENT_LIST = 0x0006, /**< Broker Fetch Client List */ + VECTOR_BROKER_CONNECTED_CLIENT_LIST = 0x0007, /**< Broker Connected Client List */ + VECTOR_BROKER_CLIENT_ADD = 0x0008, /**< Broker Client Incremental Addition */ + VECTOR_BROKER_CLIENT_REMOVE = 0x0009, /**< Broker Client Incremental Deletion */ + VECTOR_BROKER_CLIENT_ENTRY_CHANGE = 0x000A, /**< Broker Client Entry Change */ + VECTOR_BROKER_REQUEST_DYNAMIC_UIDS = 0x000B, /**< Broker Request Dynamic UID Assignment */ + VECTOR_BROKER_ASSIGNED_DYNAMIC_UIDS = 0x000C, /**< Broker Dynamic UID Assignment List */ + VECTOR_BROKER_FETCH_DYNAMIC_UID_LIST = 0x000D, /**< Broker Fetch Dynamic UID Assignment List */ + VECTOR_BROKER_DISCONNECT = 0x000E, /**< Broker Client Disconnect */ + VECTOR_BROKER_NULL = 0x000F, /**< Broker Client Null */ +}; + /** * @} */ diff --git a/include/ola/rdm/RDMEnums.h b/include/ola/rdm/RDMEnums.h index c57e8f7e97..72bc8aabe0 100644 --- a/include/ola/rdm/RDMEnums.h +++ b/include/ola/rdm/RDMEnums.h @@ -718,6 +718,9 @@ static const uint8_t MAX_RDM_HOSTNAME_LENGTH = 63; static const uint8_t MAX_RDM_DOMAIN_NAME_LENGTH = 231; static const uint8_t DNS_NAME_SERVER_MAX_INDEX = 2; + +// Excluding the mandatory NULL terminator +static const uint8_t MAX_RDM_SCOPE_STRING_LENGTH = 62; } // namespace rdm } // namespace ola #endif // INCLUDE_OLA_RDM_RDMENUMS_H_ diff --git a/libs/acn/BrokerConnectPDU.cpp b/libs/acn/BrokerConnectPDU.cpp new file mode 100644 index 0000000000..753efc0ba0 --- /dev/null +++ b/libs/acn/BrokerConnectPDU.cpp @@ -0,0 +1,123 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerConnectPDU.cpp + * The BrokerConnectPDU + * Copyright (C) 2023 Peter Newman + */ + +#include + +#include "libs/acn/BrokerConnectPDU.h" + +#include +#include + +namespace ola { +namespace acn { + +using ola::io::OutputStream; +using ola::network::HostToNetwork; +using std::min; +using std::string; + +unsigned int BrokerConnectPDU::DataSize() const { + //broker_connect_pdu_data data; + return static_cast(sizeof(broker_connect_pdu_data)); +} + +bool BrokerConnectPDU::PackData(uint8_t *data, unsigned int *length) const { + broker_connect_pdu_data pdu_data; + + size_t client_scope_str_len = min(m_client_scope.size(), sizeof(pdu_data.client_scope)); + strncpy(pdu_data.client_scope, m_client_scope.c_str(), client_scope_str_len); + memset(pdu_data.client_scope + client_scope_str_len, 0, + (sizeof(pdu_data.client_scope) - client_scope_str_len)); + + pdu_data.e133_version = m_e133_version; + + size_t search_domain_str_len = min(m_search_domain.size(), sizeof(pdu_data.search_domain)); + strncpy(pdu_data.search_domain, m_search_domain.c_str(), search_domain_str_len); + memset(pdu_data.search_domain + search_domain_str_len, 0, + (sizeof(pdu_data.search_domain) - search_domain_str_len)); + + uint8_t connection = 0; + if (m_incremental_updates) { + connection |= CONNECTION_INCREMENTAL_UPDATES; + } + pdu_data.connection = HostToNetwork(connection); + *length = static_cast(sizeof(broker_connect_pdu_data)); + + memcpy(data, &pdu_data, *length); + return true; +} + +void BrokerConnectPDU::PackData(ola::io::OutputStream *stream) const { + broker_connect_pdu_data pdu_data; + + size_t client_scope_str_len = min(m_client_scope.size(), sizeof(pdu_data.client_scope)); + strncpy(pdu_data.client_scope, m_client_scope.c_str(), client_scope_str_len); + memset(pdu_data.client_scope + client_scope_str_len, 0, + (sizeof(pdu_data.client_scope) - client_scope_str_len)); + + pdu_data.e133_version = m_e133_version; + + size_t search_domain_str_len = min(m_search_domain.size(), sizeof(pdu_data.search_domain)); + strncpy(pdu_data.search_domain, m_search_domain.c_str(), search_domain_str_len); + memset(pdu_data.search_domain + search_domain_str_len, 0, + (sizeof(pdu_data.search_domain) - search_domain_str_len)); + + uint8_t connection = 0; + if (m_incremental_updates) { + connection |= CONNECTION_INCREMENTAL_UPDATES; + } + pdu_data.connection = HostToNetwork(connection); + + stream->Write(reinterpret_cast(&pdu_data), + static_cast(sizeof(broker_connect_pdu_data))); +} + +void BrokerConnectPDU::PrependPDU(ola::io::IOStack *stack, + const string &client_scope, + uint16_t e133_version, + const string &search_domain, + bool incremental_updates) { + broker_connect_pdu_data pdu_data; + + size_t client_scope_str_len = min(client_scope.size(), sizeof(pdu_data.client_scope)); + strncpy(pdu_data.client_scope, client_scope.c_str(), client_scope_str_len); + memset(pdu_data.client_scope + client_scope_str_len, 0, + (sizeof(pdu_data.client_scope) - client_scope_str_len)); + + pdu_data.e133_version = e133_version; + + size_t search_domain_str_len = min(search_domain.size(), sizeof(pdu_data.search_domain)); + strncpy(pdu_data.search_domain, search_domain.c_str(), search_domain_str_len); + memset(pdu_data.search_domain + search_domain_str_len, 0, + (sizeof(pdu_data.search_domain) - search_domain_str_len)); + + uint8_t connection = 0; + if (incremental_updates) { + connection |= CONNECTION_INCREMENTAL_UPDATES; + } + pdu_data.connection = HostToNetwork(connection); + stack->Write(reinterpret_cast(&pdu_data), + static_cast(sizeof(broker_connect_pdu_data))); + uint16_t vector = HostToNetwork(static_cast(VECTOR_BROKER_CONNECT)); + stack->Write(reinterpret_cast(&vector), sizeof(vector)); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/BrokerConnectPDU.h b/libs/acn/BrokerConnectPDU.h new file mode 100644 index 0000000000..8850ed00c8 --- /dev/null +++ b/libs/acn/BrokerConnectPDU.h @@ -0,0 +1,84 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerConnectPDU.h + * The BrokerConnectPDU class + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERCONNECTPDU_H_ +#define LIBS_ACN_BROKERCONNECTPDU_H_ + +#include +#include + +#include "libs/acn/PDU.h" + +namespace ola { +namespace acn { + +class BrokerConnectPDU : public PDU { + public: + explicit BrokerConnectPDU(unsigned int vector, + const std::string &client_scope, + uint16_t e133_version, + const std::string &search_domain, + bool incremental_updates): + PDU(vector, TWO_BYTES, true), + m_client_scope(client_scope), + m_e133_version(e133_version), + m_search_domain(search_domain), + m_incremental_updates(incremental_updates) {} + + unsigned int HeaderSize() const { return 0; } + bool PackHeader(OLA_UNUSED uint8_t *data, + unsigned int *length) const { + *length = 0; + return true; + } + void PackHeader(OLA_UNUSED ola::io::OutputStream *stream) const {} + + unsigned int DataSize() const; + bool PackData(uint8_t *data, unsigned int *length) const; + void PackData(ola::io::OutputStream *stream) const; + + static void PrependPDU(ola::io::IOStack *stack, + const std::string &client_scope, + uint16_t e133_version, + const std::string &search_domain, + bool incremental_updates); + + // bit masks for connection + static const uint8_t CONNECTION_INCREMENTAL_UPDATES = 0x01; + + PACK( + struct broker_connect_pdu_data_s { + // Plus one to allow for the mandatory null + char client_scope[ola::rdm::MAX_RDM_SCOPE_STRING_LENGTH + 1]; + uint16_t e133_version; + char search_domain[ola::rdm::MAX_RDM_DOMAIN_NAME_LENGTH]; + uint8_t connection; + }); + typedef struct broker_connect_pdu_data_s broker_connect_pdu_data; + + private: + const std::string m_client_scope; + uint16_t m_e133_version; + const std::string m_search_domain; + uint8_t m_incremental_updates; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERCONNECTPDU_H_ diff --git a/libs/acn/BrokerConnectPDUTest.cpp b/libs/acn/BrokerConnectPDUTest.cpp new file mode 100644 index 0000000000..d3add5d2c4 --- /dev/null +++ b/libs/acn/BrokerConnectPDUTest.cpp @@ -0,0 +1,199 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerConnectPDUTest.cpp + * Test fixture for the BrokerConnectPDU class + * Copyright (C) 2023 Peter Newman + */ + +#include +#include +#include + +#include "ola/Logging.h" +#include "ola/io/IOQueue.h" +#include "ola/io/IOStack.h" +#include "ola/io/OutputStream.h" +#include "ola/network/NetworkUtils.h" +#include "ola/testing/TestUtils.h" +#include "libs/acn/PDUTestCommon.h" +#include "libs/acn/BrokerConnectPDU.h" + +namespace ola { +namespace acn { + +using ola::acn::BrokerConnectPDU; +using ola::io::IOQueue; +using ola::io::IOStack; +using ola::io::OutputStream; +using ola::network::HostToNetwork; + +class BrokerConnectPDUTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(BrokerConnectPDUTest); + CPPUNIT_TEST(testSimpleBrokerConnectPDU); + CPPUNIT_TEST(testSimpleBrokerConnectPDUToOutputStream); + CPPUNIT_TEST(testPrepend); + CPPUNIT_TEST_SUITE_END(); + + public: + void testSimpleBrokerConnectPDU(); + void testSimpleBrokerConnectPDUToOutputStream(); + void testPrepend(); + + private: + static const uint16_t TEST_VECTOR; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(BrokerConnectPDUTest); + +const uint16_t BrokerConnectPDUTest::TEST_VECTOR = 39; + + +/* + * Test that packing a BrokerConnectPDU works. + */ +void BrokerConnectPDUTest::testSimpleBrokerConnectPDU() { + BrokerConnectPDU pdu( + TEST_VECTOR, + "default", + 1, + "local.", + true); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(297u, pdu.DataSize()); + OLA_ASSERT_EQ(302u, pdu.Size()); + + unsigned int size = pdu.Size(); + uint8_t *data = new uint8_t[size]; + unsigned int bytes_used = size; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + + // spot check the data + OLA_ASSERT_EQ((uint8_t) 0xf0, data[0]); + // bytes_used is technically data[1] and data[2] if > 255 + OLA_ASSERT_EQ((uint8_t) bytes_used, data[2]); + uint16_t actual_value; + memcpy(&actual_value, data + 3, sizeof(actual_value)); + OLA_ASSERT_EQ(HostToNetwork(TEST_VECTOR), actual_value); + + // TODO(Peter): Better spot check the data! + + // test undersized buffer + bytes_used = size - 1; + OLA_ASSERT_FALSE(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(0u, bytes_used); + + // test oversized buffer + bytes_used = size + 1; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + delete[] data; +} + +/* + * Test that writing to an output stream works. + */ +void BrokerConnectPDUTest::testSimpleBrokerConnectPDUToOutputStream() { + BrokerConnectPDU pdu( + TEST_VECTOR, + "default", + 1, + "local.", + true); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(297u, pdu.DataSize()); + OLA_ASSERT_EQ(302u, pdu.Size()); + + IOQueue output; + OutputStream stream(&output); + pdu.Write(&stream); + OLA_ASSERT_EQ(302u, output.Size()); + + uint8_t *pdu_data = new uint8_t[output.Size()]; + unsigned int pdu_size = output.Peek(pdu_data, output.Size()); + OLA_ASSERT_EQ(output.Size(), pdu_size); + + uint8_t EXPECTED[] = { + 0xf0, 0x01, 0x2e, + 0, 39, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, // default + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0x01, 0, + 0x6c, 0x6f, 0x63, 0x61, 0x6C, 0x2e, // local. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1 + }; + OLA_ASSERT_DATA_EQUALS(EXPECTED, sizeof(EXPECTED), pdu_data, pdu_size); + output.Pop(output.Size()); + delete[] pdu_data; +} + + +void BrokerConnectPDUTest::testPrepend() { + IOStack stack; + BrokerConnectPDU::PrependPDU(&stack, + "default", + 1, + "local.", + true); + + unsigned int length = stack.Size(); + uint8_t *buffer = new uint8_t[length]; + OLA_ASSERT(stack.Read(buffer, length)); + + const uint8_t expected_data[] = { + 0xf0, 0x01, 0x2e, + 0, 1, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, // default + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0x01, 0, + 0x6c, 0x6f, 0x63, 0x61, 0x6C, 0x2e, // local. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1 + }; + OLA_ASSERT_DATA_EQUALS(expected_data, sizeof(expected_data), buffer, length); + delete[] buffer; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/Makefile.mk b/libs/acn/Makefile.mk index 965052a1d8..ad9909be42 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -34,6 +34,8 @@ libs_acn_libolae131core_la_SOURCES = \ libs/acn/BrokerClientEntryHeader.h \ libs/acn/BrokerClientEntryPDU.cpp \ libs/acn/BrokerClientEntryPDU.h \ + libs/acn/BrokerConnectPDU.cpp \ + libs/acn/BrokerConnectPDU.h \ libs/acn/BrokerPDU.cpp \ libs/acn/BrokerPDU.h \ libs/acn/DMPAddress.cpp \ @@ -152,6 +154,7 @@ libs_acn_E131Tester_LDADD = \ libs_acn_E133Tester_SOURCES = \ libs/acn/BrokerClientEntryPDUTest.cpp \ + libs/acn/BrokerConnectPDUTest.cpp \ libs/acn/BrokerPDUTest.cpp \ libs/acn/E133InflatorTest.cpp \ libs/acn/E133PDUTest.cpp \ From 87cb468ccba52983ff4e2bd9939515889274a96f Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 8 Mar 2023 16:55:30 +0000 Subject: [PATCH 10/32] Add the BrokerNullPDU and tests (cherry picked from commit f49c1f83420634a41309898a7cf327795ec3ed10) --- libs/acn/BrokerNullPDU.cpp | 40 +++++++++ libs/acn/BrokerNullPDU.h | 56 +++++++++++++ libs/acn/BrokerNullPDUTest.cpp | 145 +++++++++++++++++++++++++++++++++ libs/acn/Makefile.mk | 3 + 4 files changed, 244 insertions(+) create mode 100644 libs/acn/BrokerNullPDU.cpp create mode 100644 libs/acn/BrokerNullPDU.h create mode 100644 libs/acn/BrokerNullPDUTest.cpp diff --git a/libs/acn/BrokerNullPDU.cpp b/libs/acn/BrokerNullPDU.cpp new file mode 100644 index 0000000000..5f50bb9a8f --- /dev/null +++ b/libs/acn/BrokerNullPDU.cpp @@ -0,0 +1,40 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerNullPDU.cpp + * The BrokerNullPDU + * Copyright (C) 2023 Peter Newman + */ + +#include "libs/acn/BrokerNullPDU.h" + +#include +#include + +namespace ola { +namespace acn { + +using ola::io::OutputStream; +using ola::network::HostToNetwork; +using std::min; +using std::string; + +void BrokerNullPDU::PrependPDU(ola::io::IOStack *stack) { + uint16_t vector = HostToNetwork(static_cast(VECTOR_BROKER_NULL)); + stack->Write(reinterpret_cast(&vector), sizeof(vector)); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/BrokerNullPDU.h b/libs/acn/BrokerNullPDU.h new file mode 100644 index 0000000000..88450f7ad0 --- /dev/null +++ b/libs/acn/BrokerNullPDU.h @@ -0,0 +1,56 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerNullPDU.h + * The BrokerNullPDU class + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERNULLPDU_H_ +#define LIBS_ACN_BROKERNULLPDU_H_ + +#include + +#include "libs/acn/PDU.h" + +namespace ola { +namespace acn { + +class BrokerNullPDU : public PDU { + public: + explicit BrokerNullPDU(unsigned int vector): + PDU(vector, TWO_BYTES, true) {} + + unsigned int HeaderSize() const { return 0; } + bool PackHeader(OLA_UNUSED uint8_t *data, + unsigned int *length) const { + *length = 0; + return true; + } + void PackHeader(OLA_UNUSED ola::io::OutputStream *stream) const {} + + unsigned int DataSize() const { return 0; } + bool PackData(OLA_UNUSED uint8_t *data, + unsigned int *length) const { + *length = 0; + return true; + } + void PackData(OLA_UNUSED ola::io::OutputStream *stream) const {}; + + static void PrependPDU(ola::io::IOStack *stack); +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERNULLPDU_H_ diff --git a/libs/acn/BrokerNullPDUTest.cpp b/libs/acn/BrokerNullPDUTest.cpp new file mode 100644 index 0000000000..46fa712b50 --- /dev/null +++ b/libs/acn/BrokerNullPDUTest.cpp @@ -0,0 +1,145 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerNullPDUTest.cpp + * Test fixture for the BrokerNullPDU class + * Copyright (C) 2023 Peter Newman + */ + +#include +#include +#include + +#include "ola/Logging.h" +#include "ola/io/IOQueue.h" +#include "ola/io/IOStack.h" +#include "ola/io/OutputStream.h" +#include "ola/network/NetworkUtils.h" +#include "ola/testing/TestUtils.h" +#include "libs/acn/PDUTestCommon.h" +#include "libs/acn/BrokerNullPDU.h" + +namespace ola { +namespace acn { + +using ola::acn::BrokerNullPDU; +using ola::io::IOQueue; +using ola::io::IOStack; +using ola::io::OutputStream; +using ola::network::HostToNetwork; + +class BrokerNullPDUTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(BrokerNullPDUTest); + CPPUNIT_TEST(testSimpleBrokerNullPDU); + CPPUNIT_TEST(testSimpleBrokerNullPDUToOutputStream); + CPPUNIT_TEST(testPrepend); + CPPUNIT_TEST_SUITE_END(); + + public: + void testSimpleBrokerNullPDU(); + void testSimpleBrokerNullPDUToOutputStream(); + void testPrepend(); + + private: + static const uint16_t TEST_VECTOR; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(BrokerNullPDUTest); + +const uint16_t BrokerNullPDUTest::TEST_VECTOR = 39; + + +/* + * Test that packing a BrokerNullPDU works. + */ +void BrokerNullPDUTest::testSimpleBrokerNullPDU() { + BrokerNullPDU pdu(TEST_VECTOR); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(5u, pdu.Size()); + + unsigned int size = pdu.Size(); + uint8_t *data = new uint8_t[size]; + unsigned int bytes_used = size; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + + // spot check the data + OLA_ASSERT_EQ((uint8_t) 0xf0, data[0]); + // bytes_used is technically data[1] and data[2] if > 255 + OLA_ASSERT_EQ((uint8_t) bytes_used, data[2]); + uint16_t actual_value; + memcpy(&actual_value, data + 3, sizeof(actual_value)); + OLA_ASSERT_EQ(HostToNetwork(TEST_VECTOR), actual_value); + + // test undersized buffer + bytes_used = size - 1; + OLA_ASSERT_FALSE(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(0u, bytes_used); + + // test oversized buffer + bytes_used = size + 1; + OLA_ASSERT(pdu.Pack(data, &bytes_used)); + OLA_ASSERT_EQ(size, bytes_used); + delete[] data; +} + +/* + * Test that writing to an output stream works. + */ +void BrokerNullPDUTest::testSimpleBrokerNullPDUToOutputStream() { + BrokerNullPDU pdu(TEST_VECTOR); + + OLA_ASSERT_EQ(0u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(5u, pdu.Size()); + + IOQueue output; + OutputStream stream(&output); + pdu.Write(&stream); + OLA_ASSERT_EQ(5u, output.Size()); + + uint8_t *pdu_data = new uint8_t[output.Size()]; + unsigned int pdu_size = output.Peek(pdu_data, output.Size()); + OLA_ASSERT_EQ(output.Size(), pdu_size); + + uint8_t EXPECTED[] = { + 0xf0, 0x00, 0x05, + 0, 39 + }; + OLA_ASSERT_DATA_EQUALS(EXPECTED, sizeof(EXPECTED), pdu_data, pdu_size); + output.Pop(output.Size()); + delete[] pdu_data; +} + + +void BrokerNullPDUTest::testPrepend() { + IOStack stack; + BrokerNullPDU::PrependPDU(&stack); + + unsigned int length = stack.Size(); + uint8_t *buffer = new uint8_t[length]; + OLA_ASSERT(stack.Read(buffer, length)); + + const uint8_t expected_data[] = { + 0xf0, 0x00, 0x05, + 0, 0x0f + }; + OLA_ASSERT_DATA_EQUALS(expected_data, sizeof(expected_data), buffer, length); + delete[] buffer; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/Makefile.mk b/libs/acn/Makefile.mk index ad9909be42..4d89196233 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -36,6 +36,8 @@ libs_acn_libolae131core_la_SOURCES = \ libs/acn/BrokerClientEntryPDU.h \ libs/acn/BrokerConnectPDU.cpp \ libs/acn/BrokerConnectPDU.h \ + libs/acn/BrokerNullPDU.cpp \ + libs/acn/BrokerNullPDU.h \ libs/acn/BrokerPDU.cpp \ libs/acn/BrokerPDU.h \ libs/acn/DMPAddress.cpp \ @@ -155,6 +157,7 @@ libs_acn_E131Tester_LDADD = \ libs_acn_E133Tester_SOURCES = \ libs/acn/BrokerClientEntryPDUTest.cpp \ libs/acn/BrokerConnectPDUTest.cpp \ + libs/acn/BrokerNullPDUTest.cpp \ libs/acn/BrokerPDUTest.cpp \ libs/acn/E133InflatorTest.cpp \ libs/acn/E133PDUTest.cpp \ From 77eefe471f0f507800f4125da778ef06504f18c7 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 9 Mar 2023 15:52:54 +0000 Subject: [PATCH 11/32] Correct the byte order for the E1.33 version field (cherry picked from commit 5b36363f858bb303ddde228328912b70d607dd87) --- libs/acn/BrokerConnectPDU.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/acn/BrokerConnectPDU.cpp b/libs/acn/BrokerConnectPDU.cpp index 753efc0ba0..8bf3114ace 100644 --- a/libs/acn/BrokerConnectPDU.cpp +++ b/libs/acn/BrokerConnectPDU.cpp @@ -46,7 +46,7 @@ bool BrokerConnectPDU::PackData(uint8_t *data, unsigned int *length) const { memset(pdu_data.client_scope + client_scope_str_len, 0, (sizeof(pdu_data.client_scope) - client_scope_str_len)); - pdu_data.e133_version = m_e133_version; + pdu_data.e133_version = HostToNetwork(m_e133_version); size_t search_domain_str_len = min(m_search_domain.size(), sizeof(pdu_data.search_domain)); strncpy(pdu_data.search_domain, m_search_domain.c_str(), search_domain_str_len); @@ -72,7 +72,7 @@ void BrokerConnectPDU::PackData(ola::io::OutputStream *stream) const { memset(pdu_data.client_scope + client_scope_str_len, 0, (sizeof(pdu_data.client_scope) - client_scope_str_len)); - pdu_data.e133_version = m_e133_version; + pdu_data.e133_version = HostToNetwork(m_e133_version); size_t search_domain_str_len = min(m_search_domain.size(), sizeof(pdu_data.search_domain)); strncpy(pdu_data.search_domain, m_search_domain.c_str(), search_domain_str_len); @@ -101,7 +101,7 @@ void BrokerConnectPDU::PrependPDU(ola::io::IOStack *stack, memset(pdu_data.client_scope + client_scope_str_len, 0, (sizeof(pdu_data.client_scope) - client_scope_str_len)); - pdu_data.e133_version = e133_version; + pdu_data.e133_version = HostToNetwork(e133_version); size_t search_domain_str_len = min(search_domain.size(), sizeof(pdu_data.search_domain)); strncpy(pdu_data.search_domain, search_domain.c_str(), search_domain_str_len); From 17b625e4cbc3eba28db348b8f921f370ee0d35da Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 9 Mar 2023 15:53:29 +0000 Subject: [PATCH 12/32] Correct the size of the BrokerPDU's vector (cherry picked from commit eb609f384ee363070180f0954801c85b353c4047) --- libs/acn/BrokerPDU.cpp | 2 +- libs/acn/BrokerPDU.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/acn/BrokerPDU.cpp b/libs/acn/BrokerPDU.cpp index 8dcf9a844e..50364833ce 100644 --- a/libs/acn/BrokerPDU.cpp +++ b/libs/acn/BrokerPDU.cpp @@ -59,7 +59,7 @@ void BrokerPDU::PackData(OutputStream *stream) const { void BrokerPDU::PrependPDU(ola::io::IOStack *stack, - uint32_t vector) { + uint16_t vector) { vector = HostToNetwork(vector); stack->Write(reinterpret_cast(&vector), sizeof(vector)); PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); diff --git a/libs/acn/BrokerPDU.h b/libs/acn/BrokerPDU.h index 9c6b50322b..f77bfe6452 100644 --- a/libs/acn/BrokerPDU.h +++ b/libs/acn/BrokerPDU.h @@ -51,7 +51,7 @@ class BrokerPDU: public PDU { void PackData(ola::io::OutputStream *stream) const; static void PrependPDU(ola::io::IOStack *stack, - uint32_t vector); + uint16_t vector); private: const PDU *m_pdu; From 3ce250c3c21896d156574ef50355be54eb7cbeee Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 9 Mar 2023 15:59:55 +0000 Subject: [PATCH 13/32] Correct a broker endian check for the E1.33 version in our tests (cherry picked from commit e99ec916eb0d6e739f08c29e8f169959091302d6) --- libs/acn/BrokerConnectPDUTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/acn/BrokerConnectPDUTest.cpp b/libs/acn/BrokerConnectPDUTest.cpp index d3add5d2c4..e9d1052e34 100644 --- a/libs/acn/BrokerConnectPDUTest.cpp +++ b/libs/acn/BrokerConnectPDUTest.cpp @@ -135,8 +135,8 @@ void BrokerConnectPDUTest::testSimpleBrokerConnectPDUToOutputStream() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0x01, 0, - 0x6c, 0x6f, 0x63, 0x61, 0x6C, 0x2e, // local. + 0, 0x01, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, // local. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -176,8 +176,8 @@ void BrokerConnectPDUTest::testPrepend() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0x01, 0, - 0x6c, 0x6f, 0x63, 0x61, 0x6C, 0x2e, // local. + 0, 0x01, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, // local. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, From f4db0ee89b27b2091055e43cf15f0e45b85e0b7b Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 9 Mar 2023 17:50:46 +0000 Subject: [PATCH 14/32] Add a testPrepend test for the BrokerClientEntryPDU base class (cherry picked from commit d40a36a4daa1835cd9a4a3057fc6b18b2e8ed773) --- libs/acn/BrokerClientEntryPDUTest.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/libs/acn/BrokerClientEntryPDUTest.cpp b/libs/acn/BrokerClientEntryPDUTest.cpp index bdeedc3175..e907d03a33 100644 --- a/libs/acn/BrokerClientEntryPDUTest.cpp +++ b/libs/acn/BrokerClientEntryPDUTest.cpp @@ -22,6 +22,7 @@ #include "ola/Logging.h" #include "ola/io/IOQueue.h" +#include "ola/io/IOStack.h" #include "ola/io/OutputStream.h" #include "ola/network/NetworkUtils.h" #include "ola/testing/TestUtils.h" @@ -33,6 +34,7 @@ namespace ola { namespace acn { using ola::io::IOQueue; +using ola::io::IOStack; using ola::io::OutputStream; using ola::network::HostToNetwork; @@ -40,11 +42,13 @@ class BrokerClientEntryPDUTest: public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(BrokerClientEntryPDUTest); CPPUNIT_TEST(testSimpleBrokerClientEntryPDU); CPPUNIT_TEST(testSimpleBrokerClientEntryPDUToOutputStream); + CPPUNIT_TEST(testPrepend); CPPUNIT_TEST_SUITE_END(); public: void testSimpleBrokerClientEntryPDU(); void testSimpleBrokerClientEntryPDUToOutputStream(); + void testPrepend(); void setUp() { ola::InitLogging(ola::OLA_LOG_DEBUG, ola::OLA_LOG_STDERR); @@ -137,5 +141,27 @@ void BrokerClientEntryPDUTest::testSimpleBrokerClientEntryPDUToOutputStream() { output.Pop(output.Size()); delete[] pdu_data; } + + +void BrokerClientEntryPDUTest::testPrepend() { + const ola::acn::CID client_cid = CID::FromData(TEST_DATA); + IOStack stack; + BrokerClientEntryPDU::PrependPDU(&stack, + TEST_VECTOR, + client_cid); + + unsigned int length = stack.Size(); + uint8_t *buffer = new uint8_t[length]; + OLA_ASSERT(stack.Read(buffer, length)); + + const uint8_t expected_data[] = { + 0xf0, 0x00, 0x17, + 0, 0, 0, 39, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15 + }; + OLA_ASSERT_DATA_EQUALS(expected_data, sizeof(expected_data), buffer, length); + delete[] buffer; +} } // namespace acn } // namespace ola From b14741f4b583d3467cdebc3c2edf2f4f57154a31 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Fri, 10 Mar 2023 18:42:43 +0000 Subject: [PATCH 15/32] Allow the timeout interval of the HealthCheckedConnection to be customised (cherry picked from commit ad9ac0d49f03b6af87947bfc0ab6ab386102ed91) --- common/network/HealthCheckedConnection.cpp | 17 +++- .../network/HealthCheckedConnectionTest.cpp | 81 ++++++++++++++++++- include/ola/network/HealthCheckedConnection.h | 13 ++- 3 files changed, 100 insertions(+), 11 deletions(-) diff --git a/common/network/HealthCheckedConnection.cpp b/common/network/HealthCheckedConnection.cpp index 6f5cc741de..b39008a608 100644 --- a/common/network/HealthCheckedConnection.cpp +++ b/common/network/HealthCheckedConnection.cpp @@ -26,14 +26,25 @@ namespace network { HealthCheckedConnection::HealthCheckedConnection( ola::thread::SchedulerInterface *scheduler, + const ola::TimeInterval heartbeat_interval, const ola::TimeInterval timeout_interval) : m_scheduler(scheduler), - m_heartbeat_interval(timeout_interval), + m_heartbeat_interval(heartbeat_interval), + m_timeout_interval(timeout_interval), m_send_timeout_id(ola::thread::INVALID_TIMEOUT), m_receive_timeout_id(ola::thread::INVALID_TIMEOUT) { } +HealthCheckedConnection::HealthCheckedConnection( + ola::thread::SchedulerInterface *scheduler, + const ola::TimeInterval heartbeat_interval) + : HealthCheckedConnection(scheduler, + heartbeat_interval, + ola::TimeInterval(static_cast( + 2.5 * heartbeat_interval.AsInt()))) { +} + HealthCheckedConnection::~HealthCheckedConnection() { if (m_send_timeout_id != ola::thread::INVALID_TIMEOUT) m_scheduler->RemoveTimeout(m_send_timeout_id); @@ -101,10 +112,8 @@ bool HealthCheckedConnection::SendNextHeartbeat() { void HealthCheckedConnection::UpdateReceiveTimer() { - TimeInterval timeout_interval(static_cast( - 2.5 * m_heartbeat_interval.AsInt())); m_receive_timeout_id = m_scheduler->RegisterSingleTimeout( - timeout_interval, + m_timeout_interval, NewSingleCallback( this, &HealthCheckedConnection::InternalHeartbeatTimeout)); } diff --git a/common/network/HealthCheckedConnectionTest.cpp b/common/network/HealthCheckedConnectionTest.cpp index 4a6a09d9de..6f07f9e1d7 100644 --- a/common/network/HealthCheckedConnectionTest.cpp +++ b/common/network/HealthCheckedConnectionTest.cpp @@ -56,10 +56,26 @@ class MockHealthCheckedConnection: public HealthCheckedConnection { MockHealthCheckedConnection(ola::io::ConnectedDescriptor *descriptor, SelectServer *scheduler, + const ola::TimeInterval heartbeat_interval, const ola::TimeInterval timeout_interval, const Options &options, MockClock *clock) - : HealthCheckedConnection(scheduler, timeout_interval), + : HealthCheckedConnection(scheduler, heartbeat_interval, timeout_interval), + m_descriptor(descriptor), + m_ss(scheduler), + m_options(options), + m_next_heartbeat(0), + m_expected_heartbeat(0), + m_channel_ok(true), + m_clock(clock) { + } + + MockHealthCheckedConnection(ola::io::ConnectedDescriptor *descriptor, + SelectServer *scheduler, + const ola::TimeInterval heartbeat_interval, + const Options &options, + MockClock *clock) + : HealthCheckedConnection(scheduler, heartbeat_interval), m_descriptor(descriptor), m_ss(scheduler), m_options(options), @@ -70,8 +86,10 @@ class MockHealthCheckedConnection: public HealthCheckedConnection { } void SendHeartbeat() { + OLA_DEBUG << "Maybe send heartbeat"; if (m_options.send_every == 0 || m_next_heartbeat % m_options.send_every == 0) { + OLA_DEBUG << "Sending heartbeat"; m_descriptor->Send(&m_next_heartbeat, sizeof(m_next_heartbeat)); } m_clock->AdvanceTime(0, 180000); @@ -115,13 +133,18 @@ class HealthCheckedConnectionTest: public CppUnit::TestFixture { HealthCheckedConnectionTest() : CppUnit::TestFixture(), m_ss(NULL, &m_clock), - heartbeat_interval(0, 200000) { + heartbeat_interval(0, 200000), + // Allow a little bit of wiggle room so we don't hit timing issues + // when running the tests + timeout_interval(0, 650000) { } CPPUNIT_TEST_SUITE(HealthCheckedConnectionTest); CPPUNIT_TEST(testSimpleChannel); CPPUNIT_TEST(testChannelWithPacketLoss); CPPUNIT_TEST(testChannelWithHeavyPacketLoss); + CPPUNIT_TEST(testChannelWithHeavyPacketLossLongerTimeout); + CPPUNIT_TEST(testChannelWithVeryHeavyPacketLossLongerTimeout); CPPUNIT_TEST(testPauseAndResume); CPPUNIT_TEST_SUITE_END(); @@ -131,6 +154,8 @@ class HealthCheckedConnectionTest: public CppUnit::TestFixture { void testSimpleChannel(); void testChannelWithPacketLoss(); void testChannelWithHeavyPacketLoss(); + void testChannelWithHeavyPacketLossLongerTimeout(); + void testChannelWithVeryHeavyPacketLossLongerTimeout(); void testPauseAndResume(); void PauseReading(MockHealthCheckedConnection *connection) { @@ -148,6 +173,7 @@ class HealthCheckedConnectionTest: public CppUnit::TestFixture { SelectServer m_ss; LoopbackDescriptor socket; TimeInterval heartbeat_interval; + TimeInterval timeout_interval; MockHealthCheckedConnection::Options options; }; @@ -206,7 +232,7 @@ void HealthCheckedConnectionTest::testChannelWithPacketLoss() { /** - * Check the channel works when every 2nd heartbeat is lost + * Check the channel fails when 2 of every 3 heartbeats are lost */ void HealthCheckedConnectionTest::testChannelWithHeavyPacketLoss() { options.send_every = 3; @@ -228,6 +254,55 @@ void HealthCheckedConnectionTest::testChannelWithHeavyPacketLoss() { } +/** + * Check the channel works when 2 of every 3 heartbeats are lost but the + * timeout interval is 3 * heartbeat_interval rather than the default + */ +void HealthCheckedConnectionTest::testChannelWithHeavyPacketLossLongerTimeout() { + options.send_every = 3; + MockHealthCheckedConnection connection(&socket, + &m_ss, + heartbeat_interval, + timeout_interval, + options, + &m_clock); + + socket.SetOnData( + NewCallback(&connection, &MockHealthCheckedConnection::ReadData)); + connection.Setup(); + m_ss.AddReadDescriptor(&socket); + connection.Setup(); + + m_ss.Run(); + OLA_ASSERT_TRUE(connection.ChannelOk()); +} + + +/** + * Check the channel fails when 3 of every 4 heartbeats are lost even though + * the timeout interval is 3 * heartbeat_interval + */ +void HealthCheckedConnectionTest::testChannelWithVeryHeavyPacketLossLongerTimeout() { + options.send_every = 4; + options.abort_on_failure = false; + MockHealthCheckedConnection connection(&socket, + &m_ss, + heartbeat_interval, + timeout_interval, + options, + &m_clock); + + socket.SetOnData( + NewCallback(&connection, &MockHealthCheckedConnection::ReadData)); + connection.Setup(); + m_ss.AddReadDescriptor(&socket); + connection.Setup(); + + m_ss.Run(); + OLA_ASSERT_FALSE(connection.ChannelOk()); +} + + /** * Check pausing doesn't mark the channel as bad. */ diff --git a/include/ola/network/HealthCheckedConnection.h b/include/ola/network/HealthCheckedConnection.h index cbbe33e351..8195c7ea70 100644 --- a/include/ola/network/HealthCheckedConnection.h +++ b/include/ola/network/HealthCheckedConnection.h @@ -18,16 +18,17 @@ * * This class adds health checking to a connection, which ensures that the * connection is able to transfer data in a timely manner. The implementation - * is pretty simple: we define a heart beat interval I, which *must* be the + * is pretty simple: we define a heartbeat interval I, which *must* be the * same at both ends of the connection. Every I seconds, both ends send a - * heart beat message and if either end doesn't receive a heart beat in - * 2.5 * I, the connection is deemed dead, and the connection is closed. + * heartbeat message and if either end doesn't receive a heartbeat within the + * timeout interval (which defaults to 2.5 * I if not specified), the + * connection is deemed dead, and the connection is closed. * * This class provides the basic health check mechanism, the sub class is left * to define the format of the heartbeat message. * * To use this health checked channel, subclass HealthCheckedConnection, and - * provide the SendHeartbeat() and HeartbeatTimeout methods. + * provide the SendHeartbeat() and HeartbeatTimeout() methods. * * There are some additional features: * - Some receivers may want to stop reading from a connection under some @@ -57,7 +58,10 @@ namespace network { class HealthCheckedConnection { public: HealthCheckedConnection(ola::thread::SchedulerInterface *scheduler, + const ola::TimeInterval heartbeat_interval, const ola::TimeInterval timeout_interval); + HealthCheckedConnection(ola::thread::SchedulerInterface *scheduler, + const ola::TimeInterval heartbeat_interval); virtual ~HealthCheckedConnection(); /** @@ -106,6 +110,7 @@ class HealthCheckedConnection { private: ola::thread::SchedulerInterface *m_scheduler; ola::TimeInterval m_heartbeat_interval; + ola::TimeInterval m_timeout_interval; ola::thread::timeout_id m_send_timeout_id; ola::thread::timeout_id m_receive_timeout_id; From f70cb7d287367bef1665ac35ecbe23197a78089f Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 3 Jul 2023 17:55:57 +0100 Subject: [PATCH 16/32] Add some more new simple E1.33 inflators Tests still required for these! (cherry picked from commit 9fab74913e2d43936a4ce5aa1bb2415a79667f03) --- libs/acn/BrokerClientAddInflator.h | 55 ++++++++++++++++++++++ libs/acn/BrokerClientEntryChangeInflator.h | 55 ++++++++++++++++++++++ libs/acn/BrokerClientRemoveInflator.h | 55 ++++++++++++++++++++++ libs/acn/BrokerInflator.h | 55 ++++++++++++++++++++++ libs/acn/BrokerNullInflator.h | 55 ++++++++++++++++++++++ libs/acn/Makefile.mk | 5 ++ 6 files changed, 280 insertions(+) create mode 100644 libs/acn/BrokerClientAddInflator.h create mode 100644 libs/acn/BrokerClientEntryChangeInflator.h create mode 100644 libs/acn/BrokerClientRemoveInflator.h create mode 100644 libs/acn/BrokerInflator.h create mode 100644 libs/acn/BrokerNullInflator.h diff --git a/libs/acn/BrokerClientAddInflator.h b/libs/acn/BrokerClientAddInflator.h new file mode 100644 index 0000000000..14af53fe16 --- /dev/null +++ b/libs/acn/BrokerClientAddInflator.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerClientAddInflator.h + * Interface for the BrokerClientAddInflator class. + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERCLIENTADDINFLATOR_H_ +#define LIBS_ACN_BROKERCLIENTADDINFLATOR_H_ + +#include "ola/acn/ACNVectors.h" +#include "libs/acn/BaseInflator.h" + +namespace ola { +namespace acn { + +class BrokerClientAddInflator: public BaseInflator { + friend class BrokerClientAddInflatorTest; + + public: + BrokerClientAddInflator() + : BaseInflator() { + } + ~BrokerClientAddInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_BROKER_CLIENT_ADD; } + + protected: + // The 'header' is 0 bytes in length. + bool DecodeHeader(HeaderSet*, + const uint8_t*, + unsigned int, + unsigned int *bytes_used) { + *bytes_used = 0; + return true; + } + + void ResetHeaderField() {} // namespace noop +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERCLIENTADDINFLATOR_H_ diff --git a/libs/acn/BrokerClientEntryChangeInflator.h b/libs/acn/BrokerClientEntryChangeInflator.h new file mode 100644 index 0000000000..9827a60618 --- /dev/null +++ b/libs/acn/BrokerClientEntryChangeInflator.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerClientEntryChangeInflator.h + * Interface for the BrokerClientEntryChangeInflator class. + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERCLIENTENTRYCHANGEINFLATOR_H_ +#define LIBS_ACN_BROKERCLIENTENTRYCHANGEINFLATOR_H_ + +#include "ola/acn/ACNVectors.h" +#include "libs/acn/BaseInflator.h" + +namespace ola { +namespace acn { + +class BrokerClientEntryChangeInflator: public BaseInflator { + friend class BrokerClientEntryChangeInflatorTest; + + public: + BrokerClientEntryChangeInflator() + : BaseInflator() { + } + ~BrokerClientEntryChangeInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_BROKER_CLIENT_ENTRY_CHANGE; } + + protected: + // The 'header' is 0 bytes in length. + bool DecodeHeader(HeaderSet*, + const uint8_t*, + unsigned int, + unsigned int *bytes_used) { + *bytes_used = 0; + return true; + } + + void ResetHeaderField() {} // namespace noop +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERCLIENTENTRYCHANGEINFLATOR_H_ diff --git a/libs/acn/BrokerClientRemoveInflator.h b/libs/acn/BrokerClientRemoveInflator.h new file mode 100644 index 0000000000..4117139350 --- /dev/null +++ b/libs/acn/BrokerClientRemoveInflator.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerClientRemoveInflator.h + * Interface for the BrokerClientRemoveInflator class. + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERCLIENTREMOVEINFLATOR_H_ +#define LIBS_ACN_BROKERCLIENTREMOVEINFLATOR_H_ + +#include "ola/acn/ACNVectors.h" +#include "libs/acn/BaseInflator.h" + +namespace ola { +namespace acn { + +class BrokerClientRemoveInflator: public BaseInflator { + friend class BrokerClientRemoveInflatorTest; + + public: + BrokerClientRemoveInflator() + : BaseInflator() { + } + ~BrokerClientRemoveInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_BROKER_CLIENT_REMOVE; } + + protected: + // The 'header' is 0 bytes in length. + bool DecodeHeader(HeaderSet*, + const uint8_t*, + unsigned int, + unsigned int *bytes_used) { + *bytes_used = 0; + return true; + } + + void ResetHeaderField() {} // namespace noop +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERCLIENTREMOVEINFLATOR_H_ diff --git a/libs/acn/BrokerInflator.h b/libs/acn/BrokerInflator.h new file mode 100644 index 0000000000..58da325542 --- /dev/null +++ b/libs/acn/BrokerInflator.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerInflator.h + * Interface for the BrokerInflator class. + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERINFLATOR_H_ +#define LIBS_ACN_BROKERINFLATOR_H_ + +#include "ola/acn/ACNVectors.h" +#include "libs/acn/BaseInflator.h" + +namespace ola { +namespace acn { + +class BrokerInflator: public BaseInflator { + friend class BrokerInflatorTest; + + public: + BrokerInflator() + : BaseInflator(PDU::TWO_BYTES) { + } + ~BrokerInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_ROOT_BROKER; } + + protected: + // The 'header' is 0 bytes in length. + bool DecodeHeader(HeaderSet*, + const uint8_t*, + unsigned int, + unsigned int *bytes_used) { + *bytes_used = 0; + return true; + } + + void ResetHeaderField() {} // namespace noop +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERINFLATOR_H_ diff --git a/libs/acn/BrokerNullInflator.h b/libs/acn/BrokerNullInflator.h new file mode 100644 index 0000000000..28a641c722 --- /dev/null +++ b/libs/acn/BrokerNullInflator.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * BrokerNullInflator.h + * Interface for the BrokerNullInflator class. + * Copyright (C) 2023 Peter Newman + */ + +#ifndef LIBS_ACN_BROKERNULLINFLATOR_H_ +#define LIBS_ACN_BROKERNULLINFLATOR_H_ + +#include "ola/acn/ACNVectors.h" +#include "libs/acn/BaseInflator.h" + +namespace ola { +namespace acn { + +class BrokerNullInflator: public BaseInflator { + friend class BrokerNullInflatorTest; + + public: + BrokerNullInflator() + : BaseInflator() { + } + ~BrokerNullInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_BROKER_NULL; } + + protected: + // The 'header' is 0 bytes in length. + bool DecodeHeader(HeaderSet*, + const uint8_t*, + unsigned int, + unsigned int *bytes_used) { + *bytes_used = 0; + return true; + } + + void ResetHeaderField() {} // namespace noop +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_BROKERNULLINFLATOR_H_ diff --git a/libs/acn/Makefile.mk b/libs/acn/Makefile.mk index 4d89196233..7c02570ed9 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -31,11 +31,16 @@ noinst_LTLIBRARIES += libs/acn/libolae131core.la libs_acn_libolae131core_la_SOURCES = \ libs/acn/BaseInflator.cpp \ libs/acn/BaseInflator.h \ + libs/acn/BrokerClientAddInflator.h \ + libs/acn/BrokerClientEntryChangeInflator.h \ libs/acn/BrokerClientEntryHeader.h \ libs/acn/BrokerClientEntryPDU.cpp \ libs/acn/BrokerClientEntryPDU.h \ + libs/acn/BrokerClientRemoveInflator.h \ libs/acn/BrokerConnectPDU.cpp \ libs/acn/BrokerConnectPDU.h \ + libs/acn/BrokerInflator.h \ + libs/acn/BrokerNullInflator.h \ libs/acn/BrokerNullPDU.cpp \ libs/acn/BrokerNullPDU.h \ libs/acn/BrokerPDU.cpp \ From a44aa2c66c397ae694d0091eb3ebda43713e0c31 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 3 Jul 2023 18:01:06 +0100 Subject: [PATCH 17/32] More E1.33 vectors (cherry picked from commit 6d4d923a37dd575f2991862fb215d0a11b040c6f) --- include/ola/acn/ACNVectors.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index 712d72d628..73b9ffff60 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -235,6 +235,17 @@ enum BrokerVector { VECTOR_BROKER_NULL = 0x000F, /**< Broker Client Null */ }; +// Table A-21, Client Protocol Codes +// These aren't fully named as vectors in the standard, but are used as such so +// we put them in here +/** + * @brief Vectors used at the E1.33 Broker Client Entry layer. + */ +enum ClientProtocolCode { + CLIENT_PROTOCOL_RPT = 0x00000005, /**< Broker RPT Client Entry */ + CLIENT_PROTOCOL_EPT = 0x0000000b, /**< Broker EPT Client Entry */ +}; + /** * @} */ From f6710a4489ac6f760ea6ad5b069bcd4b5724f784 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 3 Jul 2023 18:04:15 +0100 Subject: [PATCH 18/32] Fix a minor typo (cherry picked from commit 81b8e38432d2720210156f0755b0a1979d929ddd) --- libs/acn/LLRPProbeReplyInflator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/acn/LLRPProbeReplyInflator.cpp b/libs/acn/LLRPProbeReplyInflator.cpp index 153433c166..6da01971cf 100644 --- a/libs/acn/LLRPProbeReplyInflator.cpp +++ b/libs/acn/LLRPProbeReplyInflator.cpp @@ -44,7 +44,7 @@ LLRPProbeReplyInflator::LLRPProbeReplyInflator() /** * Set an LLRPProbeReplyHandler to run when receiving an LLRP Probe Reply * message. - * @param handler the callback to invoke when there is and LLRP Probe Reply. + * @param handler the callback to invoke when there is an LLRP Probe Reply. */ void LLRPProbeReplyInflator::SetLLRPProbeReplyHandler( LLRPProbeReplyHandler *handler) { From 97c8f8136a341b5a861ac1c4648143e40d719e3d Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 3 Jul 2023 18:07:06 +0100 Subject: [PATCH 19/32] A few more E1.33 enums (cherry picked from commit b23bc6bcd54dcf152e9a4b269401712318c032ee) --- include/ola/e133/E133Enums.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/ola/e133/E133Enums.h b/include/ola/e133/E133Enums.h index 91369215a5..888ececf35 100644 --- a/include/ola/e133/E133Enums.h +++ b/include/ola/e133/E133Enums.h @@ -96,6 +96,11 @@ enum E133DisconnectStatusCode { enum { MAX_E133_STATUS_STRING_SIZE = 64 }; + +// The E1.33 version.. +enum { + E133_VERSION = 1 +}; } // namespace e133 } // namespace ola #endif // INCLUDE_OLA_E133_E133ENUMS_H_ From f64d20ff5cbb987b86efb6a74908f3bcda7f2a3d Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 3 Jul 2023 23:10:20 +0100 Subject: [PATCH 20/32] Fix a lint issue (cherry picked from commit a5775352a3d1ff32a042c3d50bdac8257eec6f5d) --- common/network/HealthCheckedConnectionTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/network/HealthCheckedConnectionTest.cpp b/common/network/HealthCheckedConnectionTest.cpp index 6f07f9e1d7..3664d7825e 100644 --- a/common/network/HealthCheckedConnectionTest.cpp +++ b/common/network/HealthCheckedConnectionTest.cpp @@ -60,7 +60,9 @@ class MockHealthCheckedConnection: public HealthCheckedConnection { const ola::TimeInterval timeout_interval, const Options &options, MockClock *clock) - : HealthCheckedConnection(scheduler, heartbeat_interval, timeout_interval), + : HealthCheckedConnection(scheduler, + heartbeat_interval, + timeout_interval), m_descriptor(descriptor), m_ss(scheduler), m_options(options), From efe0f472b6f8989502271dfc6c6f2648f81f955b Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Fri, 22 Mar 2024 00:52:06 +0000 Subject: [PATCH 21/32] Remove some duplicate enums from a broken merge --- include/ola/acn/ACNVectors.h | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index 73b9ffff60..b058beb810 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -214,38 +214,6 @@ enum ClientProtocolCode { CLIENT_PROTOCOL_EPT = 0x0000000B, /**< Broker EPT Client Entry */ }; -/** - * @brief Vectors used at the E1.33 Broker layer. - */ -enum BrokerVector { - VECTOR_BROKER_CONNECT = 0x0001, /**< Broker Client Connect */ - VECTOR_BROKER_CONNECT_REPLY = 0x0002, /**< Broker Connect Reply */ - VECTOR_BROKER_CLIENT_ENTRY_UPDATE = 0x0003, /**< Broker Client Entry Update */ - VECTOR_BROKER_REDIRECT_V4 = 0x0004, /**< Broker Client Redirect IPv4 */ - VECTOR_BROKER_REDIRECT_V6 = 0x0005, /**< Broker Client Redirect IPv6 */ - VECTOR_BROKER_FETCH_CLIENT_LIST = 0x0006, /**< Broker Fetch Client List */ - VECTOR_BROKER_CONNECTED_CLIENT_LIST = 0x0007, /**< Broker Connected Client List */ - VECTOR_BROKER_CLIENT_ADD = 0x0008, /**< Broker Client Incremental Addition */ - VECTOR_BROKER_CLIENT_REMOVE = 0x0009, /**< Broker Client Incremental Deletion */ - VECTOR_BROKER_CLIENT_ENTRY_CHANGE = 0x000A, /**< Broker Client Entry Change */ - VECTOR_BROKER_REQUEST_DYNAMIC_UIDS = 0x000B, /**< Broker Request Dynamic UID Assignment */ - VECTOR_BROKER_ASSIGNED_DYNAMIC_UIDS = 0x000C, /**< Broker Dynamic UID Assignment List */ - VECTOR_BROKER_FETCH_DYNAMIC_UID_LIST = 0x000D, /**< Broker Fetch Dynamic UID Assignment List */ - VECTOR_BROKER_DISCONNECT = 0x000E, /**< Broker Client Disconnect */ - VECTOR_BROKER_NULL = 0x000F, /**< Broker Client Null */ -}; - -// Table A-21, Client Protocol Codes -// These aren't fully named as vectors in the standard, but are used as such so -// we put them in here -/** - * @brief Vectors used at the E1.33 Broker Client Entry layer. - */ -enum ClientProtocolCode { - CLIENT_PROTOCOL_RPT = 0x00000005, /**< Broker RPT Client Entry */ - CLIENT_PROTOCOL_EPT = 0x0000000b, /**< Broker EPT Client Entry */ -}; - /** * @} */ From 6cc4d2faa3139a38b34e025df6df7f284f28f684 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Fri, 22 Mar 2024 23:33:37 +0000 Subject: [PATCH 22/32] Fix another broken merge --- libs/acn/LLRPProbeRequestPDU.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/acn/LLRPProbeRequestPDU.h b/libs/acn/LLRPProbeRequestPDU.h index 1a103eaf6e..56095c709c 100644 --- a/libs/acn/LLRPProbeRequestPDU.h +++ b/libs/acn/LLRPProbeRequestPDU.h @@ -72,7 +72,6 @@ class LLRPProbeRequestPDU : public PDU { static const uint16_t FILTER_CLIENT_TCP_CONNECTION_INACTIVE = 0x0001; static const uint16_t FILTER_BROKERS_ONLY = 0x0002; - private: PACK( struct llrp_probe_request_pdu_data_s { uint8_t lower_uid[ola::rdm::UID::LENGTH]; From fd70744ac0e2027c35e87265fa3799160af79e81 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Fri, 22 Mar 2024 23:40:01 +0000 Subject: [PATCH 23/32] Fix lint in LLRPProbeRequestPDU.cpp --- libs/acn/LLRPProbeRequestPDU.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/acn/LLRPProbeRequestPDU.cpp b/libs/acn/LLRPProbeRequestPDU.cpp index a6ad150130..2d3dfcf191 100644 --- a/libs/acn/LLRPProbeRequestPDU.cpp +++ b/libs/acn/LLRPProbeRequestPDU.cpp @@ -37,7 +37,6 @@ unsigned int LLRPProbeRequestPDU::DataSize() const { return static_cast(sizeof(llrp_probe_request_pdu_data) - sizeof(data.known_uids) + (m_known_uids.Size() * UID::LENGTH)); - } bool LLRPProbeRequestPDU::PackData(uint8_t *data, unsigned int *length) const { From a7a9d97f3f6ca5dbbcedf0926db19ff2320d638e Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Fri, 22 Mar 2024 23:42:38 +0000 Subject: [PATCH 24/32] Remove some reundant using statements --- libs/acn/BrokerNullPDU.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libs/acn/BrokerNullPDU.cpp b/libs/acn/BrokerNullPDU.cpp index 5f50bb9a8f..6a4b08741b 100644 --- a/libs/acn/BrokerNullPDU.cpp +++ b/libs/acn/BrokerNullPDU.cpp @@ -26,10 +26,7 @@ namespace ola { namespace acn { -using ola::io::OutputStream; using ola::network::HostToNetwork; -using std::min; -using std::string; void BrokerNullPDU::PrependPDU(ola::io::IOStack *stack) { uint16_t vector = HostToNetwork(static_cast(VECTOR_BROKER_NULL)); From 6f26169157c42d479881a3fd6437c78961362c02 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Fri, 22 Mar 2024 23:51:01 +0000 Subject: [PATCH 25/32] Fix lots of lint issues --- libs/acn/BrokerConnectPDU.cpp | 40 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/libs/acn/BrokerConnectPDU.cpp b/libs/acn/BrokerConnectPDU.cpp index 8bf3114ace..a93811c1cd 100644 --- a/libs/acn/BrokerConnectPDU.cpp +++ b/libs/acn/BrokerConnectPDU.cpp @@ -18,12 +18,13 @@ * Copyright (C) 2023 Peter Newman */ -#include - #include "libs/acn/BrokerConnectPDU.h" -#include -#include +#include +#include + +#include "ola/acn/ACNVectors.h" +#include "ola/network/NetworkUtils.h" namespace ola { namespace acn { @@ -34,22 +35,24 @@ using std::min; using std::string; unsigned int BrokerConnectPDU::DataSize() const { - //broker_connect_pdu_data data; return static_cast(sizeof(broker_connect_pdu_data)); } bool BrokerConnectPDU::PackData(uint8_t *data, unsigned int *length) const { broker_connect_pdu_data pdu_data; - size_t client_scope_str_len = min(m_client_scope.size(), sizeof(pdu_data.client_scope)); + size_t client_scope_str_len = min(m_client_scope.size(), + sizeof(pdu_data.client_scope)); strncpy(pdu_data.client_scope, m_client_scope.c_str(), client_scope_str_len); memset(pdu_data.client_scope + client_scope_str_len, 0, (sizeof(pdu_data.client_scope) - client_scope_str_len)); pdu_data.e133_version = HostToNetwork(m_e133_version); - size_t search_domain_str_len = min(m_search_domain.size(), sizeof(pdu_data.search_domain)); - strncpy(pdu_data.search_domain, m_search_domain.c_str(), search_domain_str_len); + size_t search_domain_str_len = min(m_search_domain.size(), + sizeof(pdu_data.search_domain)); + strncpy(pdu_data.search_domain, m_search_domain.c_str(), + search_domain_str_len); memset(pdu_data.search_domain + search_domain_str_len, 0, (sizeof(pdu_data.search_domain) - search_domain_str_len)); @@ -67,15 +70,18 @@ bool BrokerConnectPDU::PackData(uint8_t *data, unsigned int *length) const { void BrokerConnectPDU::PackData(ola::io::OutputStream *stream) const { broker_connect_pdu_data pdu_data; - size_t client_scope_str_len = min(m_client_scope.size(), sizeof(pdu_data.client_scope)); + size_t client_scope_str_len = min(m_client_scope.size(), + sizeof(pdu_data.client_scope)); strncpy(pdu_data.client_scope, m_client_scope.c_str(), client_scope_str_len); memset(pdu_data.client_scope + client_scope_str_len, 0, (sizeof(pdu_data.client_scope) - client_scope_str_len)); pdu_data.e133_version = HostToNetwork(m_e133_version); - size_t search_domain_str_len = min(m_search_domain.size(), sizeof(pdu_data.search_domain)); - strncpy(pdu_data.search_domain, m_search_domain.c_str(), search_domain_str_len); + size_t search_domain_str_len = min(m_search_domain.size(), + sizeof(pdu_data.search_domain)); + strncpy(pdu_data.search_domain, m_search_domain.c_str(), + search_domain_str_len); memset(pdu_data.search_domain + search_domain_str_len, 0, (sizeof(pdu_data.search_domain) - search_domain_str_len)); @@ -96,15 +102,18 @@ void BrokerConnectPDU::PrependPDU(ola::io::IOStack *stack, bool incremental_updates) { broker_connect_pdu_data pdu_data; - size_t client_scope_str_len = min(client_scope.size(), sizeof(pdu_data.client_scope)); + size_t client_scope_str_len = min(client_scope.size(), + sizeof(pdu_data.client_scope)); strncpy(pdu_data.client_scope, client_scope.c_str(), client_scope_str_len); memset(pdu_data.client_scope + client_scope_str_len, 0, (sizeof(pdu_data.client_scope) - client_scope_str_len)); pdu_data.e133_version = HostToNetwork(e133_version); - size_t search_domain_str_len = min(search_domain.size(), sizeof(pdu_data.search_domain)); - strncpy(pdu_data.search_domain, search_domain.c_str(), search_domain_str_len); + size_t search_domain_str_len = min(search_domain.size(), + sizeof(pdu_data.search_domain)); + strncpy(pdu_data.search_domain, search_domain.c_str(), + search_domain_str_len); memset(pdu_data.search_domain + search_domain_str_len, 0, (sizeof(pdu_data.search_domain) - search_domain_str_len)); @@ -115,7 +124,8 @@ void BrokerConnectPDU::PrependPDU(ola::io::IOStack *stack, pdu_data.connection = HostToNetwork(connection); stack->Write(reinterpret_cast(&pdu_data), static_cast(sizeof(broker_connect_pdu_data))); - uint16_t vector = HostToNetwork(static_cast(VECTOR_BROKER_CONNECT)); + uint16_t vector = HostToNetwork( + static_cast(VECTOR_BROKER_CONNECT)); stack->Write(reinterpret_cast(&vector), sizeof(vector)); PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); } From 684d7006459938d0cdd80f86556cc529f9e94984 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Fri, 22 Mar 2024 23:52:41 +0000 Subject: [PATCH 26/32] Lint RDMPDU --- libs/acn/RDMPDU.cpp | 4 ++-- libs/acn/RDMPDU.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/acn/RDMPDU.cpp b/libs/acn/RDMPDU.cpp index cab7d20a5c..f99779ad16 100644 --- a/libs/acn/RDMPDU.cpp +++ b/libs/acn/RDMPDU.cpp @@ -20,8 +20,8 @@ #include "libs/acn/RDMPDU.h" -#include -#include +#include "ola/network/NetworkUtils.h" +#include "ola/rdm/RDMPacket.h" namespace ola { namespace acn { diff --git a/libs/acn/RDMPDU.h b/libs/acn/RDMPDU.h index c51d9a140f..b81afb623a 100644 --- a/libs/acn/RDMPDU.h +++ b/libs/acn/RDMPDU.h @@ -22,11 +22,11 @@ #define LIBS_ACN_RDMPDU_H_ #include -#include -#include -#include #include "libs/acn/PDU.h" +#include "ola/io/ByteString.h" +#include "ola/io/IOStack.h" +#include "ola/rdm/RDMPacket.h" namespace ola { namespace acn { From db18da471e9969daa73a35cb2d5e8029010c5c75 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 23 Mar 2024 00:05:12 +0000 Subject: [PATCH 27/32] Fix a number of Broker lint issues --- libs/acn/BrokerClientEntryHeader.h | 31 ++++++++++++++------------- libs/acn/BrokerClientEntryPDU.cpp | 20 ++++++++++------- libs/acn/BrokerClientEntryPDUTest.cpp | 3 ++- libs/acn/BrokerConnectPDU.h | 5 +++-- libs/acn/BrokerNullPDU.h | 2 +- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/libs/acn/BrokerClientEntryHeader.h b/libs/acn/BrokerClientEntryHeader.h index d2277d9671..1a0bf86e92 100644 --- a/libs/acn/BrokerClientEntryHeader.h +++ b/libs/acn/BrokerClientEntryHeader.h @@ -36,27 +36,28 @@ namespace acn { */ class BrokerClientEntryHeader { public: - BrokerClientEntryHeader() {} + BrokerClientEntryHeader() {} - BrokerClientEntryHeader(const ola::acn::CID &client_cid) - : m_client_cid(client_cid) { - } - ~BrokerClientEntryHeader() {} + explicit BrokerClientEntryHeader(const ola::acn::CID &client_cid) + : m_client_cid(client_cid) { + } + ~BrokerClientEntryHeader() {} - const ola::acn::CID ClientCid() const { return m_client_cid; } + const ola::acn::CID ClientCid() const { return m_client_cid; } - bool operator==(const BrokerClientEntryHeader &other) const { - return m_client_cid == other.m_client_cid; - } + bool operator==(const BrokerClientEntryHeader &other) const { + return m_client_cid == other.m_client_cid; + } - PACK( - struct broker_client_entry_pdu_header_s { - uint8_t client_cid[CID::CID_LENGTH]; - }); - typedef struct broker_client_entry_pdu_header_s broker_client_entry_pdu_header; + PACK( + struct broker_client_entry_pdu_header_s { + uint8_t client_cid[CID::CID_LENGTH]; + }); + typedef struct broker_client_entry_pdu_header_s + broker_client_entry_pdu_header; private: - ola::acn::CID m_client_cid; + ola::acn::CID m_client_cid; }; } // namespace acn } // namespace ola diff --git a/libs/acn/BrokerClientEntryPDU.cpp b/libs/acn/BrokerClientEntryPDU.cpp index 521604e742..dc850e3316 100644 --- a/libs/acn/BrokerClientEntryPDU.cpp +++ b/libs/acn/BrokerClientEntryPDU.cpp @@ -49,12 +49,13 @@ unsigned int BrokerClientEntryPDU::DataSize() const { /* * Pack the header portion. */ -bool BrokerClientEntryPDU::PackHeader(uint8_t *data, unsigned int *length) const { +bool BrokerClientEntryPDU::PackHeader(uint8_t *data, + unsigned int *length) const { unsigned int header_size = HeaderSize(); if (*length < header_size) { - OLA_WARN << "BrokerClientEntryPDU::PackHeader: buffer too small, got " << *length - << " required " << header_size; + OLA_WARN << "BrokerClientEntryPDU::PackHeader: buffer too small, got " + << *length << " required " << header_size; *length = 0; return false; } @@ -70,7 +71,8 @@ bool BrokerClientEntryPDU::PackHeader(uint8_t *data, unsigned int *length) const /* * Pack the data portion. */ -bool BrokerClientEntryPDU::PackData(uint8_t *data, unsigned int *length) const { +bool BrokerClientEntryPDU::PackData(uint8_t *data, + unsigned int *length) const { if (m_pdu) return m_pdu->Pack(data, length); *length = 0; @@ -84,8 +86,9 @@ bool BrokerClientEntryPDU::PackData(uint8_t *data, unsigned int *length) const { void BrokerClientEntryPDU::PackHeader(OutputStream *stream) const { BrokerClientEntryHeader::broker_client_entry_pdu_header header; m_header.ClientCid().Pack(header.client_cid); - stream->Write(reinterpret_cast(&header), - sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header)); + stream->Write( + reinterpret_cast(&header), + sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header)); } @@ -103,8 +106,9 @@ void BrokerClientEntryPDU::PrependPDU(ola::io::IOStack *stack, const ola::acn::CID &client_cid) { BrokerClientEntryHeader::broker_client_entry_pdu_header header; client_cid.Pack(header.client_cid); - stack->Write(reinterpret_cast(&header), - sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header)); + stack->Write( + reinterpret_cast(&header), + sizeof(BrokerClientEntryHeader::broker_client_entry_pdu_header)); vector = HostToNetwork(vector); stack->Write(reinterpret_cast(&vector), sizeof(vector)); diff --git a/libs/acn/BrokerClientEntryPDUTest.cpp b/libs/acn/BrokerClientEntryPDUTest.cpp index e907d03a33..3c8a1d41ab 100644 --- a/libs/acn/BrokerClientEntryPDUTest.cpp +++ b/libs/acn/BrokerClientEntryPDUTest.cpp @@ -59,7 +59,8 @@ class BrokerClientEntryPDUTest: public CppUnit::TestFixture { static const uint8_t TEST_DATA[]; }; -const uint8_t BrokerClientEntryPDUTest::TEST_DATA[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, +const uint8_t BrokerClientEntryPDUTest::TEST_DATA[] = {0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; CPPUNIT_TEST_SUITE_REGISTRATION(BrokerClientEntryPDUTest); diff --git a/libs/acn/BrokerConnectPDU.h b/libs/acn/BrokerConnectPDU.h index 8850ed00c8..9712ce4e02 100644 --- a/libs/acn/BrokerConnectPDU.h +++ b/libs/acn/BrokerConnectPDU.h @@ -21,10 +21,11 @@ #ifndef LIBS_ACN_BROKERCONNECTPDU_H_ #define LIBS_ACN_BROKERCONNECTPDU_H_ -#include -#include +#include #include "libs/acn/PDU.h" +#include "ola/io/IOStack.h" +#include "ola/rdm/RDMEnums.h" namespace ola { namespace acn { diff --git a/libs/acn/BrokerNullPDU.h b/libs/acn/BrokerNullPDU.h index 88450f7ad0..0bd2a768a4 100644 --- a/libs/acn/BrokerNullPDU.h +++ b/libs/acn/BrokerNullPDU.h @@ -47,7 +47,7 @@ class BrokerNullPDU : public PDU { *length = 0; return true; } - void PackData(OLA_UNUSED ola::io::OutputStream *stream) const {}; + void PackData(OLA_UNUSED ola::io::OutputStream *stream) const {} static void PrependPDU(ola::io::IOStack *stack); }; From 76e6181c932902264ec06dcc91a97b3e8f699b69 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 23 Mar 2024 00:05:30 +0000 Subject: [PATCH 28/32] Fix a number of LLRP lint issues --- libs/acn/LLRPProbeReplyInflator.h | 2 +- libs/acn/LLRPProbeRequestInflator.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libs/acn/LLRPProbeReplyInflator.h b/libs/acn/LLRPProbeReplyInflator.h index 3aab45f7b1..51f77d6cae 100644 --- a/libs/acn/LLRPProbeReplyInflator.h +++ b/libs/acn/LLRPProbeReplyInflator.h @@ -36,7 +36,7 @@ class LLRPProbeReplyInflator: public BaseInflator { public: struct LLRPProbeReply { - LLRPProbeReply(const ola::rdm::UID &_uid) + explicit LLRPProbeReply(const ola::rdm::UID &_uid) : uid(_uid) { } ola::rdm::UID uid; diff --git a/libs/acn/LLRPProbeRequestInflator.cpp b/libs/acn/LLRPProbeRequestInflator.cpp index cbc2fff04d..db48c769c7 100644 --- a/libs/acn/LLRPProbeRequestInflator.cpp +++ b/libs/acn/LLRPProbeRequestInflator.cpp @@ -93,13 +93,15 @@ bool LLRPProbeRequestInflator::HandlePDUData(uint32_t vector, pdu_len - (sizeof(pdu_data) - sizeof(pdu_data.known_uids))); if (known_uids_size % UID::UID_SIZE != 0) { - OLA_WARN << "Got a partial known UID, received " << known_uids_size << " bytes"; + OLA_WARN << "Got a partial known UID, received " << known_uids_size + << " bytes"; return false; } memcpy(reinterpret_cast(&pdu_data), data, sizeof(pdu_data)); - OLA_DEBUG << "Probe from " << UID(pdu_data.lower_uid) << " to " << UID(pdu_data.upper_uid); + OLA_DEBUG << "Probe from " << UID(pdu_data.lower_uid) << " to " + << UID(pdu_data.upper_uid); // string rdm_message(reinterpret_cast(&data[0]), pdu_len); From 58e0a587887f60073dbb4e19802fa7271d7f0042 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 23 Mar 2024 00:06:06 +0000 Subject: [PATCH 29/32] Fix RDM Inflator lint issues --- libs/acn/RDMInflator.h | 56 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/libs/acn/RDMInflator.h b/libs/acn/RDMInflator.h index 4c37cf6c0c..41f29ae676 100644 --- a/libs/acn/RDMInflator.h +++ b/libs/acn/RDMInflator.h @@ -34,45 +34,45 @@ class RDMInflator: public BaseInflator { friend class RDMInflatorTest; public: - // These are pointers so the callers don't have to pull in all the headers. - typedef ola::Callback3 RDMMessageHandler; + // These are pointers so the callers don't have to pull in all the headers. + typedef ola::Callback3 RDMMessageHandler; - typedef ola::Callback2 GenericRDMMessageHandler; + typedef ola::Callback2 GenericRDMMessageHandler; - RDMInflator(unsigned int vector = ola::acn::VECTOR_FRAMING_RDMNET); - ~RDMInflator() {} + explicit RDMInflator(unsigned int vector = ola::acn::VECTOR_FRAMING_RDMNET); + ~RDMInflator() {} - uint32_t Id() const { return m_vector; } + uint32_t Id() const { return m_vector; } - void SetRDMHandler(RDMMessageHandler *handler); - void SetGenericRDMHandler(GenericRDMMessageHandler *handler); + void SetRDMHandler(RDMMessageHandler *handler); + void SetGenericRDMHandler(GenericRDMMessageHandler *handler); - static const unsigned int VECTOR_RDMNET_DATA = 0xcc; + static const unsigned int VECTOR_RDMNET_DATA = 0xcc; protected: - bool DecodeHeader(HeaderSet *headers, - const uint8_t *data, - unsigned int len, - unsigned int *bytes_used); + bool DecodeHeader(HeaderSet *headers, + const uint8_t *data, + unsigned int len, + unsigned int *bytes_used); - void ResetHeaderField() {} // namespace noop + void ResetHeaderField() {} // namespace noop - virtual bool HandlePDUData(uint32_t vector, - const HeaderSet &headers, - const uint8_t *data, - unsigned int pdu_len); + virtual bool HandlePDUData(uint32_t vector, + const HeaderSet &headers, + const uint8_t *data, + unsigned int pdu_len); private: - std::auto_ptr m_rdm_handler; - std::auto_ptr m_generic_rdm_handler; - unsigned int m_vector; + std::auto_ptr m_rdm_handler; + std::auto_ptr m_generic_rdm_handler; + unsigned int m_vector; }; } // namespace acn } // namespace ola From f0b01b359b4bfc3e24eb0a7a2aa96028638128ef Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 23 Mar 2024 10:13:59 +0000 Subject: [PATCH 30/32] Fix more lint issues --- common/network/HealthCheckedConnectionTest.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/network/HealthCheckedConnectionTest.cpp b/common/network/HealthCheckedConnectionTest.cpp index 3664d7825e..9f4a1618c7 100644 --- a/common/network/HealthCheckedConnectionTest.cpp +++ b/common/network/HealthCheckedConnectionTest.cpp @@ -260,7 +260,8 @@ void HealthCheckedConnectionTest::testChannelWithHeavyPacketLoss() { * Check the channel works when 2 of every 3 heartbeats are lost but the * timeout interval is 3 * heartbeat_interval rather than the default */ -void HealthCheckedConnectionTest::testChannelWithHeavyPacketLossLongerTimeout() { +void HealthCheckedConnectionTest:: + testChannelWithHeavyPacketLossLongerTimeout() { options.send_every = 3; MockHealthCheckedConnection connection(&socket, &m_ss, @@ -284,7 +285,8 @@ void HealthCheckedConnectionTest::testChannelWithHeavyPacketLossLongerTimeout() * Check the channel fails when 3 of every 4 heartbeats are lost even though * the timeout interval is 3 * heartbeat_interval */ -void HealthCheckedConnectionTest::testChannelWithVeryHeavyPacketLossLongerTimeout() { +void HealthCheckedConnectionTest:: + testChannelWithVeryHeavyPacketLossLongerTimeout() { options.send_every = 4; options.abort_on_failure = false; MockHealthCheckedConnection connection(&socket, From baf60c9fd43057b2f8e285588fd380012febc82b Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 25 Mar 2024 21:53:06 +0000 Subject: [PATCH 31/32] Add a todo for future callback changes --- libs/acn/LLRPProbeRequestInflator.cpp | 6 ++---- libs/acn/LLRPProbeRequestInflator.h | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libs/acn/LLRPProbeRequestInflator.cpp b/libs/acn/LLRPProbeRequestInflator.cpp index db48c769c7..3090917e97 100644 --- a/libs/acn/LLRPProbeRequestInflator.cpp +++ b/libs/acn/LLRPProbeRequestInflator.cpp @@ -103,14 +103,12 @@ bool LLRPProbeRequestInflator::HandlePDUData(uint32_t vector, OLA_DEBUG << "Probe from " << UID(pdu_data.lower_uid) << " to " << UID(pdu_data.upper_uid); -// string rdm_message(reinterpret_cast(&data[0]), pdu_len); - if (m_llrp_probe_request_handler.get()) { m_llrp_probe_request_handler->Run(&headers, UID(pdu_data.lower_uid), UID(pdu_data.upper_uid) -//, -// UIDSet() +// TODO(Peter): Should we add the filter and known UIDs to the callback too? +//, UIDSet() ); } else { OLA_WARN << "No LLRP Probe Request handler defined!"; diff --git a/libs/acn/LLRPProbeRequestInflator.h b/libs/acn/LLRPProbeRequestInflator.h index 1d63b84e9f..009ae01c81 100644 --- a/libs/acn/LLRPProbeRequestInflator.h +++ b/libs/acn/LLRPProbeRequestInflator.h @@ -39,8 +39,8 @@ class LLRPProbeRequestInflator: public BaseInflator { const HeaderSet*, // the HeaderSet const ola::rdm::UID&, // lower UID const ola::rdm::UID& // upper UID -//, -// const ola::rdm::UIDSet, // known UIDs +// TODO(Peter): Should we add the filter and known UIDs to the callback too? +//, const ola::rdm::UIDSet, // known UIDs > LLRPProbeRequestHandler; LLRPProbeRequestInflator(); From a58d5e6eea4e78650fc337d72c72421a2d5a4550 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 25 Mar 2024 22:08:12 +0000 Subject: [PATCH 32/32] Fix some minor comments --- include/ola/e133/E133Enums.h | 2 +- libs/acn/BrokerPDU.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/ola/e133/E133Enums.h b/include/ola/e133/E133Enums.h index 888ececf35..2bf81d75b0 100644 --- a/include/ola/e133/E133Enums.h +++ b/include/ola/e133/E133Enums.h @@ -97,7 +97,7 @@ enum { MAX_E133_STATUS_STRING_SIZE = 64 }; -// The E1.33 version.. +// The E1.33 version. enum { E133_VERSION = 1 }; diff --git a/libs/acn/BrokerPDU.cpp b/libs/acn/BrokerPDU.cpp index 50364833ce..b01f5d834c 100644 --- a/libs/acn/BrokerPDU.cpp +++ b/libs/acn/BrokerPDU.cpp @@ -42,8 +42,9 @@ unsigned int BrokerPDU::DataSize() const { * Pack the data portion. */ bool BrokerPDU::PackData(uint8_t *data, unsigned int *length) const { - if (m_pdu) + if (m_pdu) { return m_pdu->Pack(data, length); + } *length = 0; return true; } @@ -53,8 +54,9 @@ bool BrokerPDU::PackData(uint8_t *data, unsigned int *length) const { * Pack the data into a buffer */ void BrokerPDU::PackData(OutputStream *stream) const { - if (m_pdu) + if (m_pdu) { m_pdu->Write(stream); + } }