From 2a2ab67f5fe6160ab45c43a25d97f4b69a135a2d Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sun, 3 Dec 2023 01:10:09 +0000 Subject: [PATCH 01/86] Add support for the IPv6 data type to the RDM messaging and the additional E1.33 and E1.37-7 PIDs that enables --- common/messaging/DescriptorTest.cpp | 8 + common/messaging/MessagePrinter.cpp | 7 + common/messaging/MessagePrinterTest.cpp | 23 ++- common/messaging/SchemaPrinter.cpp | 6 + common/messaging/SchemaPrinterTest.cpp | 6 +- common/rdm/DescriptorConsistencyChecker.cpp | 5 + common/rdm/DescriptorConsistencyChecker.h | 1 + common/rdm/GroupSizeCalculator.cpp | 12 ++ common/rdm/GroupSizeCalculator.h | 2 + common/rdm/GroupSizeCalculatorTest.cpp | 12 +- common/rdm/MessageDeserializer.cpp | 31 ++- common/rdm/MessageDeserializerTest.cpp | 29 ++- common/rdm/MessageSerializer.cpp | 9 + common/rdm/MessageSerializerTest.cpp | 6 +- common/rdm/PidStoreLoader.cpp | 3 + common/rdm/Pids.proto | 1 + common/rdm/StringMessageBuilder.cpp | 40 +++- common/rdm/StringMessageBuilderTest.cpp | 12 +- common/rdm/VariableFieldSizeCalculator.cpp | 6 + common/rdm/VariableFieldSizeCalculator.h | 1 + data/rdm/pids.proto | 192 +++++++++++++++++++ include/ola/messaging/Descriptor.h | 20 ++ include/ola/messaging/DescriptorVisitor.h | 2 + include/ola/messaging/Message.h | 27 +++ include/ola/messaging/MessagePrinter.h | 2 + include/ola/messaging/MessageVisitor.h | 2 + include/ola/messaging/SchemaPrinter.h | 1 + include/ola/messaging/StringMessageBuilder.h | 1 + include/ola/rdm/MessageDeserializer.h | 1 + include/ola/rdm/MessageSerializer.h | 1 + include/ola/rdm/StringMessageBuilder.h | 1 + python/ola/PidStore.py | 24 +++ python/ola/PidStoreTest.py | 2 + 33 files changed, 461 insertions(+), 35 deletions(-) diff --git a/common/messaging/DescriptorTest.cpp b/common/messaging/DescriptorTest.cpp index 9c1bbcde44..37cce39c97 100644 --- a/common/messaging/DescriptorTest.cpp +++ b/common/messaging/DescriptorTest.cpp @@ -34,6 +34,7 @@ using ola::messaging::BoolFieldDescriptor; using ola::messaging::FieldDescriptor; using ola::messaging::FieldDescriptorGroup; using ola::messaging::IPV4FieldDescriptor; +using ola::messaging::IPV6FieldDescriptor; using ola::messaging::MACFieldDescriptor; using ola::messaging::StringFieldDescriptor; using ola::messaging::UIDFieldDescriptor; @@ -77,6 +78,13 @@ void DescriptorTest::testFieldDescriptors() { OLA_ASSERT_TRUE(ipv4_descriptor.LimitedSize()); OLA_ASSERT_EQ(4u, ipv4_descriptor.MaxSize()); + // IPv6 address + IPV6FieldDescriptor ipv6_descriptor("ipv6"); + OLA_ASSERT_EQ(string("ipv6"), ipv6_descriptor.Name()); + OLA_ASSERT_TRUE(ipv6_descriptor.FixedSize()); + OLA_ASSERT_TRUE(ipv6_descriptor.LimitedSize()); + OLA_ASSERT_EQ(16u, ipv6_descriptor.MaxSize()); + // MAC address MACFieldDescriptor mac_descriptor("mac"); OLA_ASSERT_EQ(string("mac"), mac_descriptor.Name()); diff --git a/common/messaging/MessagePrinter.cpp b/common/messaging/MessagePrinter.cpp index 07226b96fe..20e9ef1d89 100644 --- a/common/messaging/MessagePrinter.cpp +++ b/common/messaging/MessagePrinter.cpp @@ -58,6 +58,13 @@ void GenericMessagePrinter::Visit(const IPV4MessageField *message) { } +void GenericMessagePrinter::Visit(const IPV6MessageField *message) { + Stream() << string(m_indent, ' ') << + TransformLabel(message->GetDescriptor()->Name()) << ": " + << message->Value() << endl; +} + + void GenericMessagePrinter::Visit(const MACMessageField *message) { Stream() << string(m_indent, ' ') << TransformLabel(message->GetDescriptor()->Name()) << ": " diff --git a/common/messaging/MessagePrinterTest.cpp b/common/messaging/MessagePrinterTest.cpp index 0fdc2c2519..5484370aa0 100644 --- a/common/messaging/MessagePrinterTest.cpp +++ b/common/messaging/MessagePrinterTest.cpp @@ -32,8 +32,9 @@ using std::string; using std::vector; -using ola::rdm::UID; +using ola::network::IPV6Address; using ola::network::MACAddress; +using ola::rdm::UID; using ola::messaging::BoolFieldDescriptor; @@ -42,14 +43,16 @@ using ola::messaging::FieldDescriptor; using ola::messaging::FieldDescriptorGroup; using ola::messaging::GenericMessagePrinter; using ola::messaging::GroupMessageField; -using ola::messaging::Int16FieldDescriptor; -using ola::messaging::Int16MessageField; -using ola::messaging::Int8FieldDescriptor; -using ola::messaging::Int8MessageField; using ola::messaging::IPV4FieldDescriptor; using ola::messaging::IPV4MessageField; +using ola::messaging::IPV6FieldDescriptor; +using ola::messaging::IPV6MessageField; using ola::messaging::MACFieldDescriptor; using ola::messaging::MACMessageField; +using ola::messaging::Int16FieldDescriptor; +using ola::messaging::Int16MessageField; +using ola::messaging::Int8FieldDescriptor; +using ola::messaging::Int8MessageField; using ola::messaging::Message; using ola::messaging::MessageFieldInterface; using ola::messaging::StringFieldDescriptor; @@ -90,6 +93,7 @@ void GenericMessagePrinterTest::testSimplePrinter() { // setup some fields BoolFieldDescriptor bool_descriptor("On/Off"); IPV4FieldDescriptor ipv4_descriptor("ip"); + IPV6FieldDescriptor ipv6_descriptor("ipv6"); MACFieldDescriptor mac_descriptor("mac"); UIDFieldDescriptor uid_descriptor("uid"); StringFieldDescriptor string_descriptor("Name", 0, 32); @@ -104,6 +108,9 @@ void GenericMessagePrinterTest::testSimplePrinter() { fields.push_back( new IPV4MessageField(&ipv4_descriptor, ola::network::HostToNetwork(0x0a000001))); + fields.push_back( + new IPV6MessageField(&ipv6_descriptor, + IPV6Address::FromStringOrDie("::ffff:192.168.0.1"))); fields.push_back( new MACMessageField(&mac_descriptor, MACAddress::FromStringOrDie("01:23:45:67:89:ab"))); @@ -116,9 +123,9 @@ void GenericMessagePrinterTest::testSimplePrinter() { Message message(fields); string expected = ( - "On/Off: false\nip: 10.0.0.1\nmac: 01:23:45:67:89:ab\n" - "uid: 7a70:00000001\nName: foobar\nId: 42\nCount: 4 x 10 ^ -3\n" - "Delta: 10 x 10 ^ 1\nRate: 10 x 10 ^ -1\n"); + "On/Off: false\nip: 10.0.0.1\nipv6: ::ffff:192.168.0.1\n" + "mac: 01:23:45:67:89:ab\nuid: 7a70:00000001\nName: foobar\nId: 42\n" + "Count: 4 x 10 ^ -3\nDelta: 10 x 10 ^ 1\nRate: 10 x 10 ^ -1\n"); OLA_ASSERT_EQ(expected, m_printer.AsString(&message)); } diff --git a/common/messaging/SchemaPrinter.cpp b/common/messaging/SchemaPrinter.cpp index ba8258ef92..62b07146b2 100644 --- a/common/messaging/SchemaPrinter.cpp +++ b/common/messaging/SchemaPrinter.cpp @@ -43,6 +43,12 @@ void SchemaPrinter::Visit(const IPV4FieldDescriptor *descriptor) { } +void SchemaPrinter::Visit(const IPV6FieldDescriptor *descriptor) { + m_str << string(m_indent, ' ') << descriptor->Name() << ": IPv6 address" + << endl; +} + + void SchemaPrinter::Visit(const MACFieldDescriptor *descriptor) { m_str << string(m_indent, ' ') << descriptor->Name() << ": MAC" << endl; } diff --git a/common/messaging/SchemaPrinterTest.cpp b/common/messaging/SchemaPrinterTest.cpp index dbbe83be67..4b8d216804 100644 --- a/common/messaging/SchemaPrinterTest.cpp +++ b/common/messaging/SchemaPrinterTest.cpp @@ -33,6 +33,7 @@ using std::vector; using ola::messaging::BoolFieldDescriptor; using ola::messaging::IPV4FieldDescriptor; +using ola::messaging::IPV6FieldDescriptor; using ola::messaging::MACFieldDescriptor; using ola::messaging::Descriptor; using ola::messaging::FieldDescriptor; @@ -85,6 +86,8 @@ void SchemaPrinterTest::testPrinter() { "Count", false, 10); IPV4FieldDescriptor *ipv4_descriptor = new IPV4FieldDescriptor( "Address"); + IPV6FieldDescriptor *ipv6_descriptor = new IPV6FieldDescriptor( + "v6 Address"); MACFieldDescriptor *mac_descriptor = new MACFieldDescriptor( "MAC Address"); UIDFieldDescriptor *uid_descriptor = new UIDFieldDescriptor("Device"); @@ -95,6 +98,7 @@ void SchemaPrinterTest::testPrinter() { fields.push_back(string_descriptor); fields.push_back(uint8_descriptor); fields.push_back(ipv4_descriptor); + fields.push_back(ipv6_descriptor); fields.push_back(mac_descriptor); fields.push_back(uid_descriptor); @@ -104,7 +108,7 @@ void SchemaPrinterTest::testPrinter() { string expected = ( "On/Off: bool\nName: string [0, 32]\nCount: uint8\n" - "Address: IPv4 address\nMAC Address: MAC\nDevice: UID\n"); + "Address: IPv4 address\nv6 Address: IPv6 address\nMAC Address: MAC\nDevice: UID\n"); OLA_ASSERT_EQ(expected, printer.AsString()); } diff --git a/common/rdm/DescriptorConsistencyChecker.cpp b/common/rdm/DescriptorConsistencyChecker.cpp index ed224e4955..e947d6d14e 100644 --- a/common/rdm/DescriptorConsistencyChecker.cpp +++ b/common/rdm/DescriptorConsistencyChecker.cpp @@ -41,6 +41,11 @@ void DescriptorConsistencyChecker::Visit( } +void DescriptorConsistencyChecker::Visit( + const ola::messaging::IPV6FieldDescriptor*) { +} + + void DescriptorConsistencyChecker::Visit( const ola::messaging::MACFieldDescriptor*) { } diff --git a/common/rdm/DescriptorConsistencyChecker.h b/common/rdm/DescriptorConsistencyChecker.h index 294debf3f3..a1ed804841 100644 --- a/common/rdm/DescriptorConsistencyChecker.h +++ b/common/rdm/DescriptorConsistencyChecker.h @@ -52,6 +52,7 @@ class DescriptorConsistencyChecker void Visit(const ola::messaging::BoolFieldDescriptor*); void Visit(const ola::messaging::IPV4FieldDescriptor*); + void Visit(const ola::messaging::IPV6FieldDescriptor*); void Visit(const ola::messaging::MACFieldDescriptor*); void Visit(const ola::messaging::UIDFieldDescriptor*); void Visit(const ola::messaging::StringFieldDescriptor*); diff --git a/common/rdm/GroupSizeCalculator.cpp b/common/rdm/GroupSizeCalculator.cpp index d4287b5725..18eb334a0f 100644 --- a/common/rdm/GroupSizeCalculator.cpp +++ b/common/rdm/GroupSizeCalculator.cpp @@ -131,6 +131,12 @@ void GroupSizeCalculator::Visit( } +void GroupSizeCalculator::Visit( + const ola::messaging::IPV6FieldDescriptor *descriptor) { + m_non_groups.push_back(descriptor); +} + + void GroupSizeCalculator::Visit( const ola::messaging::MACFieldDescriptor *descriptor) { m_non_groups.push_back(descriptor); @@ -246,6 +252,12 @@ void StaticGroupTokenCalculator::Visit( } +void StaticGroupTokenCalculator::Visit( + OLA_UNUSED const ola::messaging::IPV6FieldDescriptor *descriptor) { + m_token_count.top()++; +} + + void StaticGroupTokenCalculator::Visit( OLA_UNUSED const ola::messaging::MACFieldDescriptor *descriptor) { m_token_count.top()++; diff --git a/common/rdm/GroupSizeCalculator.h b/common/rdm/GroupSizeCalculator.h index f2c8b4e8e4..c15ec07cda 100644 --- a/common/rdm/GroupSizeCalculator.h +++ b/common/rdm/GroupSizeCalculator.h @@ -53,6 +53,7 @@ class StaticGroupTokenCalculator void Visit(const ola::messaging::BoolFieldDescriptor*); void Visit(const ola::messaging::IPV4FieldDescriptor*); + void Visit(const ola::messaging::IPV6FieldDescriptor*); void Visit(const ola::messaging::MACFieldDescriptor*); void Visit(const ola::messaging::UIDFieldDescriptor*); void Visit(const ola::messaging::StringFieldDescriptor*); @@ -98,6 +99,7 @@ class GroupSizeCalculator: public ola::messaging::FieldDescriptorVisitor { void Visit(const ola::messaging::BoolFieldDescriptor*); void Visit(const ola::messaging::IPV4FieldDescriptor*); + void Visit(const ola::messaging::IPV6FieldDescriptor*); void Visit(const ola::messaging::MACFieldDescriptor*); void Visit(const ola::messaging::UIDFieldDescriptor*); void Visit(const ola::messaging::StringFieldDescriptor*); diff --git a/common/rdm/GroupSizeCalculatorTest.cpp b/common/rdm/GroupSizeCalculatorTest.cpp index 02559f5074..c86dd1dc18 100644 --- a/common/rdm/GroupSizeCalculatorTest.cpp +++ b/common/rdm/GroupSizeCalculatorTest.cpp @@ -34,6 +34,7 @@ using ola::messaging::Descriptor; using ola::messaging::FieldDescriptor; using ola::messaging::FieldDescriptorGroup; using ola::messaging::IPV4FieldDescriptor; +using ola::messaging::IPV6FieldDescriptor; using ola::messaging::Int16FieldDescriptor; using ola::messaging::Int32FieldDescriptor; using ola::messaging::Int8FieldDescriptor; @@ -84,16 +85,17 @@ void GroupSizeCalculatorTest::testSimpleCases() { fields.push_back(new Int8FieldDescriptor("int8")); fields.push_back(new Int16FieldDescriptor("int16")); fields.push_back(new Int32FieldDescriptor("int32")); - fields.push_back(new MACFieldDescriptor("mac")); fields.push_back(new StringFieldDescriptor("string", 0, 32)); fields.push_back(new IPV4FieldDescriptor("address")); + fields.push_back(new IPV6FieldDescriptor("addressv6")); + fields.push_back(new MACFieldDescriptor("mac")); fields.push_back(new UIDFieldDescriptor("uid")); Descriptor descriptor("Test Descriptor", fields); unsigned int token_count, group_repeat_count; OLA_ASSERT_TRUE( m_static_calculator.CalculateTokensRequired(&descriptor, &token_count)); - OLA_ASSERT_EQ(11u, token_count); // Actual token count + OLA_ASSERT_EQ(12u, token_count); // Actual token count OLA_ASSERT_EQ( @@ -106,21 +108,21 @@ void GroupSizeCalculatorTest::testSimpleCases() { OLA_ASSERT_EQ( GroupSizeCalculator::INSUFFICIENT_TOKENS, m_calculator.CalculateGroupSize( - 10, // Actual token count - 1 + 11, // Actual token count - 1 &descriptor, &group_repeat_count)); OLA_ASSERT_EQ( GroupSizeCalculator::NO_VARIABLE_GROUPS, m_calculator.CalculateGroupSize( - 11, // Actual token count + 12, // Actual token count &descriptor, &group_repeat_count)); OLA_ASSERT_EQ( GroupSizeCalculator::EXTRA_TOKENS, m_calculator.CalculateGroupSize( - 12, // Actual token count + 1 + 13, // Actual token count + 1 &descriptor, &group_repeat_count)); } diff --git a/common/rdm/MessageDeserializer.cpp b/common/rdm/MessageDeserializer.cpp index 28480da6e5..a3e6ec3360 100644 --- a/common/rdm/MessageDeserializer.cpp +++ b/common/rdm/MessageDeserializer.cpp @@ -114,7 +114,7 @@ void MessageDeserializer::Visit( } m_message_stack.top().push_back( - new ola::messaging::BoolMessageField(descriptor, m_data[m_offset++])); + new ola::messaging::BoolMessageField(descriptor, m_data[m_offset++])); } @@ -128,9 +128,22 @@ void MessageDeserializer::Visit( memcpy(&data, m_data + m_offset, sizeof(data)); m_offset += sizeof(data); m_message_stack.top().push_back( - new ola::messaging::IPV4MessageField( - descriptor, - ola::network::IPV4Address(data))); + new ola::messaging::IPV4MessageField( + descriptor, + ola::network::IPV4Address(data))); +} + + +void MessageDeserializer::Visit( + const ola::messaging::IPV6FieldDescriptor *descriptor) { + if (!CheckForData(descriptor->MaxSize())) { + return; + } + + ola::network::IPV6Address ipv6_address(m_data + m_offset); + m_offset += descriptor->MaxSize(); + m_message_stack.top().push_back( + new ola::messaging::IPV6MessageField(descriptor, ipv6_address)); } @@ -143,7 +156,7 @@ void MessageDeserializer::Visit( ola::network::MACAddress mac_address(m_data + m_offset); m_offset += descriptor->MaxSize(); m_message_stack.top().push_back( - new ola::messaging::MACMessageField(descriptor, mac_address)); + new ola::messaging::MACMessageField(descriptor, mac_address)); } @@ -156,7 +169,7 @@ void MessageDeserializer::Visit( ola::rdm::UID uid(m_data + m_offset); m_offset += descriptor->MaxSize(); m_message_stack.top().push_back( - new ola::messaging::UIDMessageField(descriptor, uid)); + new ola::messaging::UIDMessageField(descriptor, uid)); } @@ -179,7 +192,7 @@ void MessageDeserializer::Visit( ShortenString(&value); m_offset += string_size; m_message_stack.top().push_back( - new ola::messaging::StringMessageField(descriptor, value)); + new ola::messaging::StringMessageField(descriptor, value)); } @@ -226,7 +239,7 @@ void MessageDeserializer::Visit( const ola::messaging::FieldDescriptorGroup *descriptor) { unsigned int iterations = descriptor->FixedSize() ? descriptor->MinBlocks() : - m_variable_field_size; + m_variable_field_size; for (unsigned int i = 0; i < iterations; ++i) { vector fields; @@ -298,7 +311,7 @@ void MessageDeserializer::IntVisit( } m_message_stack.top().push_back( - new ola::messaging::BasicMessageField(descriptor, value)); + new ola::messaging::BasicMessageField(descriptor, value)); } } // namespace rdm } // namespace ola diff --git a/common/rdm/MessageDeserializerTest.cpp b/common/rdm/MessageDeserializerTest.cpp index b1660e5178..ec9e429425 100644 --- a/common/rdm/MessageDeserializerTest.cpp +++ b/common/rdm/MessageDeserializerTest.cpp @@ -34,7 +34,6 @@ using ola::messaging::BoolFieldDescriptor; -using ola::messaging::IPV4FieldDescriptor; using ola::messaging::Descriptor; using ola::messaging::FieldDescriptor; using ola::messaging::FieldDescriptorGroup; @@ -42,6 +41,7 @@ using ola::messaging::Int16FieldDescriptor; using ola::messaging::Int32FieldDescriptor; using ola::messaging::Int8FieldDescriptor; using ola::messaging::IPV4FieldDescriptor; +using ola::messaging::IPV6FieldDescriptor; using ola::messaging::MACFieldDescriptor; using ola::messaging::Message; using ola::messaging::GenericMessagePrinter; @@ -62,6 +62,7 @@ class MessageDeserializerTest: public CppUnit::TestFixture { CPPUNIT_TEST(testSimpleBigEndian); CPPUNIT_TEST(testSimpleLittleEndian); CPPUNIT_TEST(testIPV4); + CPPUNIT_TEST(testIPV6); CPPUNIT_TEST(testMAC); CPPUNIT_TEST(testString); CPPUNIT_TEST(testUID); @@ -75,6 +76,7 @@ class MessageDeserializerTest: public CppUnit::TestFixture { void testSimpleBigEndian(); void testSimpleLittleEndian(); void testIPV4(); + void testIPV6(); void testMAC(); void testString(); void testUID(); @@ -246,6 +248,31 @@ void MessageDeserializerTest::testIPV4() { } +/** + * Test IPV6 inflation. + */ +void MessageDeserializerTest::testIPV6() { + // build the descriptor + vector fields; + fields.push_back(new IPV6FieldDescriptor("Addressv6")); + Descriptor descriptor("Test Descriptor", fields); + + // now setup the data + const uint8_t big_endian_data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 10, 0, 0, 1}; + + // now the correct amount & verify + auto_ptr message(m_deserializer.InflateMessage( + &descriptor, + big_endian_data, + sizeof(big_endian_data))); + OLA_ASSERT_NOT_NULL(message.get()); + OLA_ASSERT_EQ(1u, message->FieldCount()); + + const string expected = "Addressv6: ::ffff:10.0.0.1\n"; + OLA_ASSERT_EQ(expected, m_printer.AsString(message.get())); +} + + /** * Test MAC inflation. */ diff --git a/common/rdm/MessageSerializer.cpp b/common/rdm/MessageSerializer.cpp index 8fe5198d2f..8181157642 100644 --- a/common/rdm/MessageSerializer.cpp +++ b/common/rdm/MessageSerializer.cpp @@ -77,6 +77,15 @@ void MessageSerializer::Visit( } +void MessageSerializer::Visit( + const ola::messaging::IPV6MessageField *message) { + unsigned int size = message->GetDescriptor()->MaxSize(); + CheckForFreeSpace(size); + message->Value().Pack(m_data + m_offset, size); + m_offset += size; +} + + void MessageSerializer::Visit( const ola::messaging::MACMessageField *message) { unsigned int size = message->GetDescriptor()->MaxSize(); diff --git a/common/rdm/MessageSerializerTest.cpp b/common/rdm/MessageSerializerTest.cpp index 9d6163fa7d..2eca076471 100644 --- a/common/rdm/MessageSerializerTest.cpp +++ b/common/rdm/MessageSerializerTest.cpp @@ -41,6 +41,7 @@ using ola::messaging::Int16FieldDescriptor; using ola::messaging::Int32FieldDescriptor; using ola::messaging::Int8FieldDescriptor; using ola::messaging::IPV4FieldDescriptor; +using ola::messaging::IPV6FieldDescriptor; using ola::messaging::MACFieldDescriptor; using ola::messaging::Message; using ola::messaging::StringFieldDescriptor; @@ -111,6 +112,7 @@ void MessageSerializerTest::testSimple() { fields.push_back(new UInt32FieldDescriptor("uint32")); fields.push_back(new Int32FieldDescriptor("int32")); fields.push_back(new IPV4FieldDescriptor("ip")); + fields.push_back(new IPV6FieldDescriptor("ipv6")); fields.push_back(new MACFieldDescriptor("mac")); fields.push_back(new StringFieldDescriptor("string", 0, 32)); Descriptor descriptor("Test Descriptor", fields); @@ -125,6 +127,7 @@ void MessageSerializerTest::testSimple() { inputs.push_back("66000"); inputs.push_back("-66000"); inputs.push_back("10.0.0.1"); + inputs.push_back("::ffff:192.168.0.1"); inputs.push_back("01:23:45:67:89:ab"); inputs.push_back("foo"); @@ -137,12 +140,13 @@ void MessageSerializerTest::testSimple() { const uint8_t *data = serializer.SerializeMessage(message.get(), &packed_length); OLA_ASSERT_NOT_NULL(data); - OLA_ASSERT_EQ(28u, packed_length); + OLA_ASSERT_EQ(44u, packed_length); uint8_t expected[] = { 1, 1, 253, 1, 44, 254, 112, 0, 1, 1, 208, 255, 254, 254, 48, 10, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 192, 168, 0, 1, 1, 35, 69, 103, 137, 171, 'f', 'o', 'o'}; diff --git a/common/rdm/PidStoreLoader.cpp b/common/rdm/PidStoreLoader.cpp index 70665f2852..adf5594e6b 100644 --- a/common/rdm/PidStoreLoader.cpp +++ b/common/rdm/PidStoreLoader.cpp @@ -478,6 +478,9 @@ const FieldDescriptor *PidStoreLoader::FieldToFieldDescriptor( case ola::rdm::pid::UID: descriptor = new ola::messaging::UIDFieldDescriptor(field.name()); break; + case ola::rdm::pid::IPV6: + descriptor = new ola::messaging::IPV6FieldDescriptor(field.name()); + break; default: OLA_WARN << "Unknown field type: " << field.type(); } diff --git a/common/rdm/Pids.proto b/common/rdm/Pids.proto index 841e1d7931..19010f7ad8 100644 --- a/common/rdm/Pids.proto +++ b/common/rdm/Pids.proto @@ -42,6 +42,7 @@ enum FieldType { IPV4 = 10; UID = 11; MAC = 12; + IPV6 = 13; } // A value which has a label applied diff --git a/common/rdm/StringMessageBuilder.cpp b/common/rdm/StringMessageBuilder.cpp index 63840d3198..da6fad314e 100644 --- a/common/rdm/StringMessageBuilder.cpp +++ b/common/rdm/StringMessageBuilder.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -127,8 +128,9 @@ const ola::messaging::Message *StringMessageBuilder::GetMessage( */ void StringMessageBuilder::Visit( const ola::messaging::BoolFieldDescriptor *descriptor) { - if (StopParsing()) + if (StopParsing()) { return; + } bool value = false; bool valid = false; @@ -170,8 +172,9 @@ void StringMessageBuilder::Visit( */ void StringMessageBuilder::Visit( const ola::messaging::IPV4FieldDescriptor *descriptor) { - if (StopParsing()) + if (StopParsing()) { return; + } string token = m_inputs[m_offset++]; ola::network::IPV4Address ip_address; @@ -185,13 +188,35 @@ void StringMessageBuilder::Visit( } +/** + * IPV6 Addresses + */ +void StringMessageBuilder::Visit( + const ola::messaging::IPV6FieldDescriptor *descriptor) { + if (StopParsing()) { + return; + } + + string token = m_inputs[m_offset++]; + ola::network::IPV6Address ipv6_address; + if (!ola::network::IPV6Address::FromString(token, &ipv6_address)) { + SetError(descriptor->Name()); + return; + } + + m_groups.top().push_back( + new ola::messaging::IPV6MessageField(descriptor, ipv6_address)); +} + + /** * MAC Addresses */ void StringMessageBuilder::Visit( const ola::messaging::MACFieldDescriptor *descriptor) { - if (StopParsing()) + if (StopParsing()) { return; + } string token = m_inputs[m_offset++]; ola::network::MACAddress mac_address; @@ -210,8 +235,9 @@ void StringMessageBuilder::Visit( */ void StringMessageBuilder::Visit( const ola::messaging::UIDFieldDescriptor *descriptor) { - if (StopParsing()) + if (StopParsing()) { return; + } string token = m_inputs[m_offset++]; auto_ptr uid(UID::FromString(token)); @@ -231,8 +257,9 @@ void StringMessageBuilder::Visit( */ void StringMessageBuilder::Visit( const ola::messaging::StringFieldDescriptor *descriptor) { - if (StopParsing()) + if (StopParsing()) { return; + } const string &token = m_inputs[m_offset++]; if (descriptor->MaxSize() != 0 && @@ -335,8 +362,9 @@ void StringMessageBuilder::SetError(const string &error) { template void StringMessageBuilder::VisitInt( const ola::messaging::IntegerFieldDescriptor *descriptor) { - if (StopParsing()) + if (StopParsing()) { return; + } type int_value; string input = m_inputs[m_offset++]; diff --git a/common/rdm/StringMessageBuilderTest.cpp b/common/rdm/StringMessageBuilderTest.cpp index de09265147..6ee21f16e8 100644 --- a/common/rdm/StringMessageBuilderTest.cpp +++ b/common/rdm/StringMessageBuilderTest.cpp @@ -38,6 +38,7 @@ using ola::messaging::Descriptor; using ola::messaging::FieldDescriptor; using ola::messaging::FieldDescriptorGroup; using ola::messaging::IPV4FieldDescriptor; +using ola::messaging::IPV6FieldDescriptor; using ola::messaging::Int16FieldDescriptor; using ola::messaging::Int32FieldDescriptor; using ola::messaging::Int8FieldDescriptor; @@ -136,6 +137,7 @@ void StringBuilderTest::testSimpleBuilder() { fields.push_back(new BoolFieldDescriptor("bool5")); fields.push_back(new BoolFieldDescriptor("bool6")); fields.push_back(new IPV4FieldDescriptor("ip1")); + fields.push_back(new IPV6FieldDescriptor("ipv61")); fields.push_back(new MACFieldDescriptor("mac1")); fields.push_back(new UInt8FieldDescriptor("uint8")); fields.push_back(new UInt16FieldDescriptor("uint16")); @@ -156,6 +158,7 @@ void StringBuilderTest::testSimpleBuilder() { inputs.push_back("TRUE"); inputs.push_back("FALSE"); inputs.push_back("10.0.0.1"); + inputs.push_back("::ffff:192.168.0.1"); inputs.push_back("01:23:45:67:89:ab"); inputs.push_back("255"); inputs.push_back("300"); @@ -171,13 +174,14 @@ void StringBuilderTest::testSimpleBuilder() { // verify OLA_ASSERT_TRUE(message.get()); OLA_ASSERT_EQ(static_cast(fields.size()), - message->FieldCount()); + message->FieldCount()); string expected = ( "bool1: true\nbool2: false\nbool3: true\nbool4: false\nbool5: true\n" - "bool6: false\nip1: 10.0.0.1\nmac1: 01:23:45:67:89:ab\nuint8: 255\n" - "uint16: 300\nuint32: 66000\nint8: -128\nint16: -300\nint32: -66000\n" - "string: foo\nhex uint16: 1024\n"); + "bool6: false\nip1: 10.0.0.1\nipv61: ::ffff:192.168.0.1\n" + "mac1: 01:23:45:67:89:ab\nuint8: 255\nuint16: 300\nuint32: 66000\n" + "int8: -128\nint16: -300\nint32: -66000\nstring: foo\n" + "hex uint16: 1024\n"); OLA_ASSERT_EQ(expected, m_printer.AsString(message.get())); } diff --git a/common/rdm/VariableFieldSizeCalculator.cpp b/common/rdm/VariableFieldSizeCalculator.cpp index b054a38589..4ef46ba2d0 100644 --- a/common/rdm/VariableFieldSizeCalculator.cpp +++ b/common/rdm/VariableFieldSizeCalculator.cpp @@ -124,6 +124,12 @@ void VariableFieldSizeCalculator::Visit( } +void VariableFieldSizeCalculator::Visit( + const ola::messaging::IPV6FieldDescriptor *descriptor) { + m_fixed_size_sum += descriptor->MaxSize(); +} + + void VariableFieldSizeCalculator::Visit( const ola::messaging::MACFieldDescriptor *descriptor) { m_fixed_size_sum += descriptor->MaxSize(); diff --git a/common/rdm/VariableFieldSizeCalculator.h b/common/rdm/VariableFieldSizeCalculator.h index d6208b323c..4e224b0afa 100644 --- a/common/rdm/VariableFieldSizeCalculator.h +++ b/common/rdm/VariableFieldSizeCalculator.h @@ -63,6 +63,7 @@ class VariableFieldSizeCalculator void Visit(const ola::messaging::BoolFieldDescriptor*); void Visit(const ola::messaging::IPV4FieldDescriptor*); + void Visit(const ola::messaging::IPV6FieldDescriptor*); void Visit(const ola::messaging::MACFieldDescriptor*); void Visit(const ola::messaging::UIDFieldDescriptor*); void Visit(const ola::messaging::StringFieldDescriptor*); diff --git a/data/rdm/pids.proto b/data/rdm/pids.proto index cebb8ef20e..50548ae6a0 100644 --- a/data/rdm/pids.proto +++ b/data/rdm/pids.proto @@ -4010,6 +4010,144 @@ pid { } set_sub_device_range: ROOT_OR_ALL_SUBDEVICE } +pid { + name: "COMPONENT_SCOPE" + value: 2048 + get_request { + field { + type: UINT16 + name: "scope_slot" + range { + min: 1 + max: 65535 + } + } + } + get_response { + field { + type: UINT16 + name: "scope_slot" + range { + min: 1 + max: 65535 + } + } + field { + type: STRING + name: "scope_string" + min_size: 63 + max_size: 63 + } + field { + type: UINT8 + name: "static_config_type" + label { + value: 0 + label: "No static config" + } + label { + value: 1 + label: "Static config IPv4" + } + label { + value: 1 + label: "Static config IPv6" + } + range { + min: 0 + max: 2 + } + } + field { + type: IPV4 + name: "static_broker_ipv4_address" + label { + value: 0 + label: "No static broker IPv4 address" + } + } + field { + type: IPV6 + name: "static_broker_ipv6_address" + label { + value: 0 + label: "No static broker IPv6 address" + } + } + field { + type: UINT16 + name: "static_broker_port" + label { + value: 0 + label: "No static broker port" + } + } + } + get_sub_device_range: ROOT_DEVICE + set_request { + field { + type: UINT16 + name: "scope_slot" + range { + min: 1 + max: 65535 + } + } + field { + type: STRING + name: "scope_string" + min_size: 63 + max_size: 63 + } + field { + type: UINT8 + name: "static_config_type" + label { + value: 0 + label: "No static config" + } + label { + value: 1 + label: "Static config IPv4" + } + label { + value: 1 + label: "Static config IPv6" + } + range { + min: 0 + max: 2 + } + } + field { + type: IPV4 + name: "static_broker_ipv4_address" + label { + value: 0 + label: "No static broker IPv4 address" + } + } + field { + type: IPV6 + name: "static_broker_ipv6_address" + label { + value: 0 + label: "No static broker IPv6 address" + } + } + field { + type: UINT16 + name: "static_broker_port" + label { + value: 0 + label: "No static broker port" + } + } + } + set_response { + } + set_sub_device_range: ROOT_DEVICE +} pid { name: "SEARCH_DOMAIN" value: 2049 @@ -4036,6 +4174,60 @@ pid { } set_sub_device_range: ROOT_DEVICE } +pid { + name: "TCP_COMMS_STATUS" + value: 2050 + get_request { + } + get_response { + field { + type: GROUP + name: "comms_statuses" + field { + type: STRING + name: "scope_string" + min_size: 63 + max_size: 63 + } + field { + type: IPV4 + name: "broker_ipv4_address" + label { + value: 0 + label: "No IPv4 Connection" + } + } + field { + type: IPV6 + name: "broker_ipv6_address" + label { + value: 0 + label: "No IPv6 Connection" + } + } + field { + type: UINT16 + name: "broker_port" + } + field { + type: UINT16 + name: "unhealthy_tcp_events" + } + } + } + get_sub_device_range: ROOT_DEVICE + set_request { + field { + type: STRING + name: "scope_string" + min_size: 63 + max_size: 63 + } + } + set_response { + } + set_sub_device_range: ROOT_DEVICE +} pid { name: "BROKER_STATUS" value: 2051 diff --git a/include/ola/messaging/Descriptor.h b/include/ola/messaging/Descriptor.h index 3f287141ea..f997a9a00d 100644 --- a/include/ola/messaging/Descriptor.h +++ b/include/ola/messaging/Descriptor.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -116,6 +117,25 @@ class IPV4FieldDescriptor: public FieldDescriptor { }; +/** + * A FieldDescriptor that represents a IPv6 Address + */ +class IPV6FieldDescriptor: public FieldDescriptor { + public: + explicit IPV6FieldDescriptor(const std::string &name) + : FieldDescriptor(name) { + } + + bool FixedSize() const { return true; } + bool LimitedSize() const { return true; } + unsigned int MaxSize() const { return ola::network::IPV6Address::LENGTH; } + + void Accept(FieldDescriptorVisitor *visitor) const { + visitor->Visit(this); + } +}; + + /** * A FieldDescriptor that represents a MAC Address */ diff --git a/include/ola/messaging/DescriptorVisitor.h b/include/ola/messaging/DescriptorVisitor.h index 43a64f572a..5b5820d588 100644 --- a/include/ola/messaging/DescriptorVisitor.h +++ b/include/ola/messaging/DescriptorVisitor.h @@ -30,6 +30,7 @@ namespace messaging { class BoolFieldDescriptor; class FieldDescriptorGroup; class IPV4FieldDescriptor; +class IPV6FieldDescriptor; class MACFieldDescriptor; class StringFieldDescriptor; class UIDFieldDescriptor; @@ -49,6 +50,7 @@ class FieldDescriptorVisitor { virtual void Visit(const BoolFieldDescriptor*) = 0; virtual void Visit(const IPV4FieldDescriptor*) = 0; + virtual void Visit(const IPV6FieldDescriptor*) = 0; virtual void Visit(const MACFieldDescriptor*) = 0; virtual void Visit(const UIDFieldDescriptor*) = 0; virtual void Visit(const StringFieldDescriptor*) = 0; diff --git a/include/ola/messaging/Message.h b/include/ola/messaging/Message.h index b8062f57c1..ecc56bd2a2 100644 --- a/include/ola/messaging/Message.h +++ b/include/ola/messaging/Message.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -125,6 +126,32 @@ class IPV4MessageField: public MessageFieldInterface { }; +/** + * A MessageField that represents a IPv6 Address + */ +class IPV6MessageField: public MessageFieldInterface { + public: + IPV6MessageField(const IPV6FieldDescriptor *descriptor, + const ola::network::IPV6Address &value) + : m_descriptor(descriptor), + m_value(value) { + } + + const IPV6FieldDescriptor *GetDescriptor() const { + return m_descriptor; + } + const ola::network::IPV6Address& Value() const { return m_value; } + + void Accept(MessageVisitor *visitor) const { + visitor->Visit(this); + } + + private: + const IPV6FieldDescriptor *m_descriptor; + ola::network::IPV6Address m_value; +}; + + /** * A MessageField that represents a MAC Address */ diff --git a/include/ola/messaging/MessagePrinter.h b/include/ola/messaging/MessagePrinter.h index 0053d16618..2f2f363664 100644 --- a/include/ola/messaging/MessagePrinter.h +++ b/include/ola/messaging/MessagePrinter.h @@ -40,6 +40,7 @@ class MessagePrinter: public MessageVisitor { virtual void Visit(const BoolMessageField*) {} virtual void Visit(const IPV4MessageField*) {} + virtual void Visit(const IPV6MessageField*) {} virtual void Visit(const MACMessageField*) {} virtual void Visit(const UIDMessageField*) {} virtual void Visit(const StringMessageField*) {} @@ -78,6 +79,7 @@ class GenericMessagePrinter: public MessagePrinter { virtual void Visit(const BoolMessageField*); virtual void Visit(const IPV4MessageField*); + virtual void Visit(const IPV6MessageField*); virtual void Visit(const MACMessageField*); virtual void Visit(const UIDMessageField*); virtual void Visit(const StringMessageField*); diff --git a/include/ola/messaging/MessageVisitor.h b/include/ola/messaging/MessageVisitor.h index 00812f8e56..81b55ed965 100644 --- a/include/ola/messaging/MessageVisitor.h +++ b/include/ola/messaging/MessageVisitor.h @@ -30,6 +30,7 @@ namespace messaging { class BoolMessageField; class GroupMessageField; class IPV4MessageField; +class IPV6MessageField; class MACMessageField; class StringMessageField; class UIDMessageField; @@ -46,6 +47,7 @@ class MessageVisitor { virtual void Visit(const BoolMessageField*) = 0; virtual void Visit(const IPV4MessageField*) = 0; + virtual void Visit(const IPV6MessageField*) = 0; virtual void Visit(const MACMessageField*) = 0; virtual void Visit(const UIDMessageField*) = 0; virtual void Visit(const StringMessageField*) = 0; diff --git a/include/ola/messaging/SchemaPrinter.h b/include/ola/messaging/SchemaPrinter.h index 21feb46090..95aa7c9e6b 100644 --- a/include/ola/messaging/SchemaPrinter.h +++ b/include/ola/messaging/SchemaPrinter.h @@ -50,6 +50,7 @@ class SchemaPrinter: public FieldDescriptorVisitor { void Visit(const BoolFieldDescriptor*); void Visit(const IPV4FieldDescriptor*); + void Visit(const IPV6FieldDescriptor*); void Visit(const MACFieldDescriptor*); void Visit(const UIDFieldDescriptor*); void Visit(const StringFieldDescriptor*); diff --git a/include/ola/messaging/StringMessageBuilder.h b/include/ola/messaging/StringMessageBuilder.h index 4bb9011c4b..12b7273fd3 100644 --- a/include/ola/messaging/StringMessageBuilder.h +++ b/include/ola/messaging/StringMessageBuilder.h @@ -42,6 +42,7 @@ class StringMessageBuilder: public FieldDescriptorVisitor { void Visit(const BoolFieldDescriptor*); void Visit(const IPV4FieldDescriptor*); + void Visit(const IPV6FieldDescriptor*); void Visit(const MACFieldDescriptor*); void Visit(const UIDFieldDescriptor*); void Visit(const StringFieldDescriptor*); diff --git a/include/ola/rdm/MessageDeserializer.h b/include/ola/rdm/MessageDeserializer.h index 4d228125e2..5e320653af 100644 --- a/include/ola/rdm/MessageDeserializer.h +++ b/include/ola/rdm/MessageDeserializer.h @@ -57,6 +57,7 @@ class MessageDeserializer: public ola::messaging::FieldDescriptorVisitor { void Visit(const ola::messaging::BoolFieldDescriptor*); void Visit(const ola::messaging::IPV4FieldDescriptor*); + void Visit(const ola::messaging::IPV6FieldDescriptor*); void Visit(const ola::messaging::MACFieldDescriptor*); void Visit(const ola::messaging::UIDFieldDescriptor*); void Visit(const ola::messaging::StringFieldDescriptor*); diff --git a/include/ola/rdm/MessageSerializer.h b/include/ola/rdm/MessageSerializer.h index 821f2097ea..cf6f51f86e 100644 --- a/include/ola/rdm/MessageSerializer.h +++ b/include/ola/rdm/MessageSerializer.h @@ -48,6 +48,7 @@ class MessageSerializer: public ola::messaging::MessageVisitor { void Visit(const ola::messaging::BoolMessageField*); void Visit(const ola::messaging::IPV4MessageField*); + void Visit(const ola::messaging::IPV6MessageField*); void Visit(const ola::messaging::MACMessageField*); void Visit(const ola::messaging::UIDMessageField*); void Visit(const ola::messaging::StringMessageField*); diff --git a/include/ola/rdm/StringMessageBuilder.h b/include/ola/rdm/StringMessageBuilder.h index f66187e682..ed2bfbdc49 100644 --- a/include/ola/rdm/StringMessageBuilder.h +++ b/include/ola/rdm/StringMessageBuilder.h @@ -62,6 +62,7 @@ class StringMessageBuilder: public ola::messaging::FieldDescriptorVisitor { void Visit(const ola::messaging::BoolFieldDescriptor*); void Visit(const ola::messaging::IPV4FieldDescriptor*); + void Visit(const ola::messaging::IPV6FieldDescriptor*); void Visit(const ola::messaging::MACFieldDescriptor*); void Visit(const ola::messaging::UIDFieldDescriptor*); void Visit(const ola::messaging::StringFieldDescriptor*); diff --git a/python/ola/PidStore.py b/python/ola/PidStore.py index 38fb200562..f9f62121c1 100644 --- a/python/ola/PidStore.py +++ b/python/ola/PidStore.py @@ -549,6 +549,28 @@ def Pack(self, args): return super(IntAtom, self).Pack(value) +class IPV6Atom(FixedSizeAtom): + """A sixteen-byte IPV6 address.""" + def __init__(self, name, **kwargs): + super(IPV6Atom, self).__init__(name, 'BBBBBBBBBBBBBBBB') + + def Unpack(self, data): + try: + return socket.inet_ntop(AF_INET6, data) + except socket.error as e: + raise ArgsValidationError("Can't unpack data: %s" % e) + + def Pack(self, args): + # TODO(Peter): This currently allows some rather quirky values as per + # inet_pton, we may want to restrict that in future + format_string = self._FormatString() + try: + data = struct.pack(format_string, socket.inet_pton(AF_INET6, args[0])) + except socket.error as e: + raise ArgsValidationError("Can't pack data: %s" % e) + return data, 1 + + class MACAtom(FixedSizeAtom): """A MAC address.""" def __init__(self, name, **kwargs): @@ -1271,6 +1293,8 @@ def _FieldToAtom(self, field): return UInt32(field_name, **args) elif field.type == Pids_pb2.IPV4: return IPV4(field_name, **args) + elif field.type == Pids_pb2.IPV6: + return IPV6Atom(field_name, **args) elif field.type == Pids_pb2.MAC: return MACAtom(field_name, **args) elif field.type == Pids_pb2.UID: diff --git a/python/ola/PidStoreTest.py b/python/ola/PidStoreTest.py index 600f1dd389..e09226f1fd 100755 --- a/python/ola/PidStoreTest.py +++ b/python/ola/PidStoreTest.py @@ -174,6 +174,8 @@ def testCmp(self): g1getreq = PidStore.Group("grg", [PidStore.UInt16("ui16"), PidStore.Int32("i32")]) g1setreq = PidStore.Group("srg", [PidStore.MACAtom("mac"), + PidStore.IPV4("ipv4"), + PidStore.IPV6Atom("ipv6"), PidStore.Int8("i32")]) p1b = PidStore.Pid("base", 42, None, None, g1getreq, g1setreq) From 92760e5aabc165a9e7d15d59838af0ccaade4322 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sun, 3 Dec 2023 01:20:25 +0000 Subject: [PATCH 02/86] Minor formatting tweaks to match the rest of the codebase --- common/messaging/MessagePrinter.cpp | 43 +++++++++++++++-------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/common/messaging/MessagePrinter.cpp b/common/messaging/MessagePrinter.cpp index 20e9ef1d89..7123c15782 100644 --- a/common/messaging/MessagePrinter.cpp +++ b/common/messaging/MessagePrinter.cpp @@ -45,44 +45,44 @@ string MessagePrinter::AsString(const Message *message) { void GenericMessagePrinter::Visit(const BoolMessageField *message) { - Stream() << string(m_indent, ' ') << - TransformLabel(message->GetDescriptor()->Name()) << ": " - << (message->Value() ? "true" : "false") << endl; + Stream() << string(m_indent, ' ') + << TransformLabel(message->GetDescriptor()->Name()) << ": " + << (message->Value() ? "true" : "false") << endl; } void GenericMessagePrinter::Visit(const IPV4MessageField *message) { - Stream() << string(m_indent, ' ') << - TransformLabel(message->GetDescriptor()->Name()) << ": " - << message->Value() << endl; + Stream() << string(m_indent, ' ') + << TransformLabel(message->GetDescriptor()->Name()) << ": " + << message->Value() << endl; } void GenericMessagePrinter::Visit(const IPV6MessageField *message) { - Stream() << string(m_indent, ' ') << - TransformLabel(message->GetDescriptor()->Name()) << ": " - << message->Value() << endl; + Stream() << string(m_indent, ' ') + << TransformLabel(message->GetDescriptor()->Name()) << ": " + << message->Value() << endl; } void GenericMessagePrinter::Visit(const MACMessageField *message) { - Stream() << string(m_indent, ' ') << - TransformLabel(message->GetDescriptor()->Name()) << ": " - << message->Value().ToString() << endl; + Stream() << string(m_indent, ' ') + << TransformLabel(message->GetDescriptor()->Name()) << ": " + << message->Value().ToString() << endl; } void GenericMessagePrinter::Visit(const UIDMessageField *message) { - Stream() << string(m_indent, ' ') << - TransformLabel(message->GetDescriptor()->Name()) << ": " - << message->Value().ToString() << endl; + Stream() << string(m_indent, ' ') + << TransformLabel(message->GetDescriptor()->Name()) << ": " + << message->Value().ToString() << endl; } void GenericMessagePrinter::Visit(const StringMessageField *message) { - Stream() << string(m_indent, ' ') << - TransformLabel(message->GetDescriptor()->Name()) << ": " - << EncodeString(message->Value()) << endl; + Stream() << string(m_indent, ' ') + << TransformLabel(message->GetDescriptor()->Name()) << ": " + << EncodeString(message->Value()) << endl; } @@ -141,8 +141,8 @@ void GenericMessagePrinter::Visit(const BasicMessageField *message) { void GenericMessagePrinter::Visit(const GroupMessageField *message) { - Stream() << string(m_indent, ' ') << - TransformLabel(message->GetDescriptor()->Name()) << " {" << endl; + Stream() << string(m_indent, ' ') + << TransformLabel(message->GetDescriptor()->Name()) << " {" << endl; m_indent += m_indent_size; } @@ -185,8 +185,9 @@ void GenericMessagePrinter::AppendInt(const string &name, void GenericMessagePrinter::AppendMultiplier(int8_t multiplier) { - if (multiplier) + if (multiplier) { Stream() << " x 10 ^ " << static_cast(multiplier); + } } } // namespace messaging } // namespace ola From ad9aea5e8186b97adacd4e6df710e1d2561d7a09 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sun, 3 Dec 2023 01:32:22 +0000 Subject: [PATCH 03/86] Fix some cpplint errors --- common/messaging/SchemaPrinterTest.cpp | 3 ++- common/rdm/MessageDeserializerTest.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/common/messaging/SchemaPrinterTest.cpp b/common/messaging/SchemaPrinterTest.cpp index 4b8d216804..0eda1f5a36 100644 --- a/common/messaging/SchemaPrinterTest.cpp +++ b/common/messaging/SchemaPrinterTest.cpp @@ -108,7 +108,8 @@ void SchemaPrinterTest::testPrinter() { string expected = ( "On/Off: bool\nName: string [0, 32]\nCount: uint8\n" - "Address: IPv4 address\nv6 Address: IPv6 address\nMAC Address: MAC\nDevice: UID\n"); + "Address: IPv4 address\nv6 Address: IPv6 address\nMAC Address: MAC\n" + "Device: UID\n"); OLA_ASSERT_EQ(expected, printer.AsString()); } diff --git a/common/rdm/MessageDeserializerTest.cpp b/common/rdm/MessageDeserializerTest.cpp index ec9e429425..d674b2c2f8 100644 --- a/common/rdm/MessageDeserializerTest.cpp +++ b/common/rdm/MessageDeserializerTest.cpp @@ -258,7 +258,8 @@ void MessageDeserializerTest::testIPV6() { Descriptor descriptor("Test Descriptor", fields); // now setup the data - const uint8_t big_endian_data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 10, 0, 0, 1}; + const uint8_t big_endian_data[] = {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 10, 0, 0, 1}; // now the correct amount & verify auto_ptr message(m_deserializer.InflateMessage( From 14c5d1921c14b8aaced71e7747852c6149a18819 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sun, 10 Dec 2023 11:47:46 +0000 Subject: [PATCH 04/86] Fix some socket constant usage --- python/ola/PidStore.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/ola/PidStore.py b/python/ola/PidStore.py index f9f62121c1..f48db9656b 100644 --- a/python/ola/PidStore.py +++ b/python/ola/PidStore.py @@ -556,7 +556,7 @@ def __init__(self, name, **kwargs): def Unpack(self, data): try: - return socket.inet_ntop(AF_INET6, data) + return socket.inet_ntop(socket.AF_INET6, data) except socket.error as e: raise ArgsValidationError("Can't unpack data: %s" % e) @@ -565,7 +565,8 @@ def Pack(self, args): # inet_pton, we may want to restrict that in future format_string = self._FormatString() try: - data = struct.pack(format_string, socket.inet_pton(AF_INET6, args[0])) + data = struct.pack(format_string, + socket.inet_pton(socket.AF_INET6, args[0])) except socket.error as e: raise ArgsValidationError("Can't pack data: %s" % e) return data, 1 From 8b5485fe85bc3a5d32ddb11dc0dae8e9a1b1abfd Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 3 Feb 2024 15:50:33 +0000 Subject: [PATCH 05/86] Update some copyright years --- NEWS | 2 +- olad/www/mobile.html | 2 +- olad/www/ola.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 2356125e35..5bbe639770 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -x/y/2023 ola-0.10.10 +x/y/2024 ola-0.10.10 Features: * diff --git a/olad/www/mobile.html b/olad/www/mobile.html index 10659b63ca..96b919d0c1 100644 --- a/olad/www/mobile.html +++ b/olad/www/mobile.html @@ -459,7 +459,7 @@ diff --git a/olad/www/ola.html b/olad/www/ola.html index 1dee8a1dfa..28aff7d51b 100644 --- a/olad/www/ola.html +++ b/olad/www/ola.html @@ -1026,7 +1026,7 @@

From 40fc444d4a578f89bf56e6b676c278bf2702759d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 21:56:38 +0000 Subject: [PATCH 06/86] Bump actions/setup-node from 3 to 4 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 0c49e768a0..4d0ae08182 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -262,7 +262,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Node.js v18 - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18 # LTS cache: 'npm' From 2df204c5d5eaba6983fa3e9e6002aab26a98c002 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:34:03 +0000 Subject: [PATCH 07/86] Bump actions/download-artifact from 3 to 4 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yaml | 2 +- .github/workflows/debian.yml | 2 +- .github/workflows/lint.yaml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8408df474e..a22a593886 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -165,7 +165,7 @@ jobs: - id: "distcheck-debian-stable-amd64-clang" steps: - name: Download built source tree archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-${{ matrix.id }}-source-tree path: . diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 0ae5317ba0..c06f7195c5 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -72,7 +72,7 @@ jobs: steps: - uses: actions/checkout@master - name: Download build artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-built-debian-${{ matrix.image_tag }}-${{ matrix.architecture }} path: built diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 0c49e768a0..d07b310836 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -67,7 +67,7 @@ jobs: needs: build steps: - name: Download built source tree archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-debian-stable-built-source-tree path: . @@ -97,7 +97,7 @@ jobs: needs: build steps: - name: Download built source tree archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-debian-stable-built-source-tree path: . @@ -123,7 +123,7 @@ jobs: needs: build steps: - name: Download built source tree archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-debian-stable-built-source-tree path: . @@ -160,7 +160,7 @@ jobs: needs: build steps: - name: Download built source tree archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-debian-stable-built-source-tree path: . @@ -197,7 +197,7 @@ jobs: needs: build steps: - name: Download built source tree archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-debian-stable-built-source-tree path: . @@ -226,7 +226,7 @@ jobs: needs: build steps: - name: Download built source tree archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ola-debian-stable-built-source-tree path: . From f6c735616a616f5ea54a802fcb2b69cf515a2bd0 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 26 Feb 2024 22:08:05 +0000 Subject: [PATCH 08/86] Ignore more minified files that might contain spelling false positives --- scripts/spelling.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/spelling.sh b/scripts/spelling.sh index bcc82af8ac..c20c9c2c30 100755 --- a/scripts/spelling.sh +++ b/scripts/spelling.sh @@ -70,11 +70,14 @@ SPELLINGBLACKLIST=$(cat <<-BLACKLIST -wholename "./olad/www/new/js/app.min.js" -or \ -wholename "./olad/www/new/js/app.min.js.map" -or \ -wholename "./olad/www/new/libs/angular/js/angular.min.js" -or \ + -wholename "./olad/www/new/libs/bootstrap/js/bootstrap.min.js" -or \ + -wholename "./olad/www/new/libs/jquery/js/jquery.min.js" -or \ -wholename "./olad/www/new/libs/marked/js/marked.min.js" -or \ -wholename "./olad/www/ola.js" -or \ -wholename "./plugins/artnet/messages/ArtNetConfigMessages.pb.*" -or \ -wholename "./tools/ola_trigger/config.tab.*" -or \ - -wholename "./tools/ola_trigger/lex.yy.cpp" + -wholename "./tools/ola_trigger/lex.yy.cpp" -or \ + -wholename "./tools/rdm/static/jquery-1.7.2.min.js" BLACKLIST ) From 5880cc2a0f182ab8dd50eee02bbbe7d3dbc42b29 Mon Sep 17 00:00:00 2001 From: Perry Naseck Date: Mon, 26 Feb 2024 19:59:51 -0500 Subject: [PATCH 09/86] coverage workaround gcovr race parse bug --- Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 25d13bada7..f3efd1ec00 100644 --- a/Makefile.am +++ b/Makefile.am @@ -271,6 +271,8 @@ COVERAGE_OUTPUTS = --txt coverage/coverage.txt \ --cobertura coverage/coverage.cobertura.xml \ --html-details coverage/details.html/coverage.details.html \ --coveralls coverage/coverage.coveralls.json +# See https://gcovr.com/en/stable/guide/gcov_parser.html#negative-hit-counts +COVERAGE_FLAGS=--gcov-ignore-parse-errors=negative_hits.warn_once_per_file COVERAGE_GCOV_EXE=--gcov-executable /usr/bin/gcov COVERAGE_FILTERS=-e '.*Test\.cpp$$' \ -e '.*\.pb\.cc$$' \ @@ -287,7 +289,7 @@ if !BUILD_GCOV else if FOUND_GCOVR mkdir -p coverage/details.html/ - gcovr --print-summary $(COVERAGE_OUTPUTS) $(COVERAGE_GCOV_EXE) --root . $(COVERAGE_FILTERS) + gcovr $(COVERAGE_FLAGS) --print-summary $(COVERAGE_OUTPUTS) $(COVERAGE_GCOV_EXE) --root . $(COVERAGE_FILTERS) else $(error gcovr not found. Install gcovr (e.g. via pip for the latest version) and re-run configure.) endif From 8c78dbd7f0c160ca91ca49744b53953e1ba0e4d6 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 27 Feb 2024 23:11:32 +0000 Subject: [PATCH 10/86] Switch to actions/upload-artifact@v4 --- .github/workflows/lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d07b310836..12d892fb4c 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -56,7 +56,7 @@ jobs: tar --exclude=ola-debian-stable-built-source-tree.tar.gz -cvzf ola-debian-stable-built-source-tree.tar.gz . - name: SHA256 artifact archive run: sha256sum ola-debian-stable-built-source-tree.tar.gz - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ola-debian-stable-built-source-tree path: ola-debian-stable-built-source-tree.tar.gz From 5e704b131fdc0038f64b7150a0b2b1cec6b44598 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 27 Feb 2024 23:12:06 +0000 Subject: [PATCH 11/86] Switch to actions/upload-artifact@v4 --- .github/workflows/build.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a22a593886..296da8211b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -119,14 +119,14 @@ jobs: if: always() run: sha256sum ola-*.tar.gz - name: Upload source tree artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: always() with: name: ola-${{ matrix.id }}-source-tree path: ola-${{ matrix.id }}-source-tree.tar.gz - name: Upload built artifact if: matrix.task == 'distcheck' || matrix.task == 'dist' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ola-${{ matrix.id }}-dist path: | @@ -147,7 +147,7 @@ jobs: flag-name: ${{ matrix.id }} - name: Upload coverage artifacts if: always() && matrix.task == 'coverage' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ola-${{ matrix.id }}-coverage path: coverage/ From 2313c93e52cb22bca8a162a2c3ff6e0f6d6b2016 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 27 Feb 2024 23:12:39 +0000 Subject: [PATCH 12/86] Switch to actions/upload-artifact@v4 --- .github/workflows/debian.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index c06f7195c5..7fff3d801f 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -53,7 +53,7 @@ jobs: shell: bash run: find . -type f -exec sha256sum {} \; working-directory: built - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: always() with: name: ola-built-debian-${{ matrix.image_tag }}-${{ matrix.architecture }} @@ -85,7 +85,7 @@ jobs: run: apt-get -y install autopkgtest - name: Test run: autopkgtest --output-dir=test-output built/*ges -- null - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: always() # Always upload the test output, even on failed tests with: name: ola-test-output-debian-${{ matrix.image_tag }}-${{ matrix.architecture }} From 69565aa18d576880b429ba28a0a3301334f7e002 Mon Sep 17 00:00:00 2001 From: Perry Naseck <4472083+DaAwesomeP@users.noreply.github.com> Date: Tue, 27 Feb 2024 20:26:37 -0500 Subject: [PATCH 13/86] Update Makefile.am Co-authored-by: Peter Newman --- Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index f3efd1ec00..1da6851cb2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -272,9 +272,9 @@ COVERAGE_OUTPUTS = --txt coverage/coverage.txt \ --html-details coverage/details.html/coverage.details.html \ --coveralls coverage/coverage.coveralls.json # See https://gcovr.com/en/stable/guide/gcov_parser.html#negative-hit-counts -COVERAGE_FLAGS=--gcov-ignore-parse-errors=negative_hits.warn_once_per_file -COVERAGE_GCOV_EXE=--gcov-executable /usr/bin/gcov -COVERAGE_FILTERS=-e '.*Test\.cpp$$' \ +COVERAGE_FLAGS = --gcov-ignore-parse-errors=negative_hits.warn_once_per_file +COVERAGE_GCOV_EXE = --gcov-executable /usr/bin/gcov +COVERAGE_FILTERS = -e '.*Test\.cpp$$' \ -e '.*\.pb\.cc$$' \ -e '.*\.pb\.cpp$$' \ -e '.*\.pb\.h$$' \ From 3599bb0f1e0b93d30d9c87d6800bc88067a39cf8 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 29 Jan 2020 18:58:52 +0000 Subject: [PATCH 14/86] First attempt at LLRP header and PDU All there apart from flags should always be 0xF0 rather than 0x70 (cherry picked from commit 23a00bbc5ce89055c08bda9c342449fcfbade2fd) --- include/ola/acn/ACNVectors.h | 3 + libs/acn/HeaderSet.h | 8 +- libs/acn/LLRPHeader.h | 69 ++++++++++++++++ libs/acn/LLRPInflator.cpp | 70 ++++++++++++++++ libs/acn/LLRPInflator.h | 58 ++++++++++++++ libs/acn/LLRPInflatorTest.cpp | 126 +++++++++++++++++++++++++++++ libs/acn/LLRPPDU.cpp | 117 +++++++++++++++++++++++++++ libs/acn/LLRPPDU.h | 62 ++++++++++++++ libs/acn/LLRPPDUTest.cpp | 147 ++++++++++++++++++++++++++++++++++ libs/acn/Makefile.mk | 14 ++++ 10 files changed, 673 insertions(+), 1 deletion(-) create mode 100644 libs/acn/LLRPHeader.h create mode 100644 libs/acn/LLRPInflator.cpp create mode 100644 libs/acn/LLRPInflator.h create mode 100644 libs/acn/LLRPInflatorTest.cpp create mode 100644 libs/acn/LLRPPDU.cpp create mode 100644 libs/acn/LLRPPDU.h create mode 100644 libs/acn/LLRPPDUTest.cpp diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index b45e1c0e76..9e8211ff13 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -47,6 +47,9 @@ enum RootVector { VECTOR_ROOT_E131 = 4, /**< E1.31 (sACN) */ VECTOR_ROOT_E133 = 5, /**< E1.33 (RDNNet) */ VECTOR_ROOT_NULL = 6, /**< NULL (empty) root */ + VECTOR_ROOT_BROKER = 9, /**< E1.33 (Broker) */ + VECTOR_ROOT_LLRP = 0x0A, /**< E1.33 (LLRP) */ + VECTOR_ROOT_EPT = 0x0B, /**< E1.33 (EPT) */ }; /** diff --git a/libs/acn/HeaderSet.h b/libs/acn/HeaderSet.h index c3e9a44f98..06a56c26aa 100644 --- a/libs/acn/HeaderSet.h +++ b/libs/acn/HeaderSet.h @@ -26,6 +26,7 @@ #include "libs/acn/DMPHeader.h" #include "libs/acn/E131Header.h" #include "libs/acn/E133Header.h" +#include "libs/acn/LLRPHeader.h" #include "libs/acn/RootHeader.h" #include "libs/acn/TransportHeader.h" @@ -56,13 +57,17 @@ class HeaderSet { const DMPHeader &GetDMPHeader() const { return m_dmp_header; } void SetDMPHeader(const DMPHeader &header) { m_dmp_header = header; } + const LLRPHeader &GetLLRPHeader() const { return m_llrp_header; } + void SetLLRPHeader(const LLRPHeader &header) { m_llrp_header = header; } + bool operator==(const HeaderSet &other) const { return ( m_transport_header == other.m_transport_header && m_root_header == other.m_root_header && m_e131_header == other.m_e131_header && m_e133_header == other.m_e133_header && - m_dmp_header == other.m_dmp_header); + m_dmp_header == other.m_dmp_header && + m_llrp_header == other.m_llrp_header); } private: @@ -71,6 +76,7 @@ class HeaderSet { E131Header m_e131_header; E133Header m_e133_header; DMPHeader m_dmp_header; + LLRPHeader m_llrp_header; }; } // namespace acn } // namespace ola diff --git a/libs/acn/LLRPHeader.h b/libs/acn/LLRPHeader.h new file mode 100644 index 0000000000..1d964268fd --- /dev/null +++ b/libs/acn/LLRPHeader.h @@ -0,0 +1,69 @@ +/* + * 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. + * + * LLRPHeader.h + * The E1.33 LLRP Header + * Copyright (C) 2020 Peter Newman + */ + +#ifndef LIBS_ACN_LLRPHEADER_H_ +#define LIBS_ACN_LLRPHEADER_H_ + +#include +#include + +#include + +namespace ola { +namespace acn { + +/* + * Header for the LLRP layer + */ +class LLRPHeader { + public: + LLRPHeader() + : m_transaction_number(0) { + } + + LLRPHeader(const ola::acn::CID &destination_cid, + uint32_t transaction_number) + : m_destination_cid(destination_cid), + m_transaction_number(transaction_number) { + } + ~LLRPHeader() {} + + const ola::acn::CID DestinationCid() const { return m_destination_cid; } + uint32_t TransactionNumber() const { return m_transaction_number; } + + bool operator==(const LLRPHeader &other) const { + return m_destination_cid == other.m_destination_cid && + m_transaction_number == other.m_transaction_number; + } + + PACK( + struct llrp_pdu_header_s { + uint8_t destination_cid[CID::CID_LENGTH]; + uint32_t transaction_number; + }); + typedef struct llrp_pdu_header_s llrp_pdu_header; + + private: + ola::acn::CID m_destination_cid; + uint32_t m_transaction_number; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_LLRPHEADER_H_ diff --git a/libs/acn/LLRPInflator.cpp b/libs/acn/LLRPInflator.cpp new file mode 100644 index 0000000000..e629df8d50 --- /dev/null +++ b/libs/acn/LLRPInflator.cpp @@ -0,0 +1,70 @@ +/* + * 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. + * + * LLRPInflator.cpp + * The Inflator for E1.33 LLRP + * Copyright (C) 2020 Peter Newman + */ + +#include "ola/Logging.h" +#include "ola/network/NetworkUtils.h" +#include "libs/acn/LLRPInflator.h" + +namespace ola { +namespace acn { + +using ola::network::NetworkToHost; + +/* + * Decode the E1.33 LLRP headers. If data is null we're expected to use the + * last header we got. + * @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 LLRPInflator::DecodeHeader(HeaderSet *headers, + const uint8_t *data, + unsigned int length, + unsigned int *bytes_used) { + if (data) { + // the header bit was set, decode it + if (length >= sizeof(LLRPHeader::llrp_pdu_header)) { + LLRPHeader::llrp_pdu_header raw_header; + memcpy(&raw_header, data, sizeof(LLRPHeader::llrp_pdu_header)); + LLRPHeader header( + ola::acn::CID::FromData(raw_header.destination_cid), + NetworkToHost(raw_header.transaction_number)); + m_last_header = header; + m_last_header_valid = true; + headers->SetLLRPHeader(header); + *bytes_used = sizeof(LLRPHeader::llrp_pdu_header); + return true; + } + *bytes_used = 0; + return false; + } + + // use the last header if it exists + *bytes_used = 0; + if (!m_last_header_valid) { + OLA_WARN << "Missing E1.33 LLRP Header data"; + return false; + } + headers->SetLLRPHeader(m_last_header); + return true; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/LLRPInflator.h b/libs/acn/LLRPInflator.h new file mode 100644 index 0000000000..34a5aa023d --- /dev/null +++ b/libs/acn/LLRPInflator.h @@ -0,0 +1,58 @@ +/* + * 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. + * + * LLRPInflator.h + * Interface for the LLRPInflator class. + * Copyright (C) 2020 Peter Newman + */ + +#ifndef LIBS_ACN_LLRPINFLATOR_H_ +#define LIBS_ACN_LLRPINFLATOR_H_ + +#include "ola/acn/ACNVectors.h" +#include "libs/acn/BaseInflator.h" +#include "libs/acn/LLRPHeader.h" + +namespace ola { +namespace acn { + +class LLRPInflator: public BaseInflator { + friend class LLRPInflatorTest; + + public: + LLRPInflator() + : BaseInflator(), + m_last_header_valid(false) { + } + ~LLRPInflator() {} + + uint32_t Id() const { return ola::acn::VECTOR_ROOT_LLRP; } + + protected: + bool DecodeHeader(HeaderSet *headers, + const uint8_t *data, + unsigned int len, + unsigned int *bytes_used); + + void ResetHeaderField() { + m_last_header_valid = false; + } + private: + LLRPHeader m_last_header; + bool m_last_header_valid; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_LLRPINFLATOR_H_ diff --git a/libs/acn/LLRPInflatorTest.cpp b/libs/acn/LLRPInflatorTest.cpp new file mode 100644 index 0000000000..b36c5cdc05 --- /dev/null +++ b/libs/acn/LLRPInflatorTest.cpp @@ -0,0 +1,126 @@ +/* + * 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. + * + * LLRPInflatorTest.cpp + * Test fixture for the LLRPInflator class + * Copyright (C) 2020 Peter Newman + */ + +#include + +#include "ola/Logging.h" +#include "ola/network/NetworkUtils.h" +#include "libs/acn/HeaderSet.h" +#include "libs/acn/PDUTestCommon.h" +#include "libs/acn/LLRPInflator.h" +#include "libs/acn/LLRPPDU.h" +#include "ola/testing/TestUtils.h" + + +namespace ola { +namespace acn { + +using ola::network::HostToNetwork; + +class LLRPInflatorTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LLRPInflatorTest); + CPPUNIT_TEST(testDecodeHeader); + CPPUNIT_TEST(testInflatePDU); + CPPUNIT_TEST_SUITE_END(); + + public: + void testDecodeHeader(); + void testInflatePDU(); + private: + static const uint8_t TEST_DATA[]; + static const uint8_t TEST_DATA2[]; +}; + +const uint8_t LLRPInflatorTest::TEST_DATA[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15}; +const uint8_t LLRPInflatorTest::TEST_DATA2[] = {10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, + 25}; +CPPUNIT_TEST_SUITE_REGISTRATION(LLRPInflatorTest); + + +/* + * Check that we can decode headers properly + */ +void LLRPInflatorTest::testDecodeHeader() { + LLRPHeader::llrp_pdu_header header; + memset(&header, 0, sizeof(header)); + LLRPInflator inflator; + HeaderSet header_set, header_set2; + unsigned int bytes_used; + const ola::acn::CID destination_cid = CID::FromData(TEST_DATA); + + destination_cid.Pack(header.destination_cid); + header.transaction_number = HostToNetwork(72650u); + + OLA_ASSERT(inflator.DecodeHeader(&header_set, + reinterpret_cast(&header), + sizeof(header), + &bytes_used)); + OLA_ASSERT_EQ((unsigned int) sizeof(header), bytes_used); + LLRPHeader decoded_header = header_set.GetLLRPHeader(); + OLA_ASSERT(destination_cid == decoded_header.DestinationCid()); + OLA_ASSERT_EQ((uint32_t) 72650, decoded_header.TransactionNumber()); + + // try an undersized header + OLA_ASSERT_FALSE(inflator.DecodeHeader( + &header_set, + reinterpret_cast(&header), + static_cast(sizeof(header) - 1), + &bytes_used)); + OLA_ASSERT_EQ((unsigned int) 0, bytes_used); + + // test inheriting the header from the prev call + OLA_ASSERT(inflator.DecodeHeader(&header_set2, NULL, 0, &bytes_used)); + OLA_ASSERT_EQ((unsigned int) 0, bytes_used); + decoded_header = header_set2.GetLLRPHeader(); + OLA_ASSERT(destination_cid == decoded_header.DestinationCid()); + OLA_ASSERT_EQ((uint32_t) 72650, decoded_header.TransactionNumber()); + + inflator.ResetHeaderField(); + OLA_ASSERT_FALSE(inflator.DecodeHeader(&header_set2, NULL, 0, &bytes_used)); + OLA_ASSERT_EQ((unsigned int) 0, bytes_used); +} + + +/* + * Check that we can inflate a LLRP PDU that contains other PDUs + */ +void LLRPInflatorTest::testInflatePDU() { + const ola::acn::CID destination_cid = CID::FromData(TEST_DATA2); + LLRPHeader header(destination_cid, 2370); + // TODO(Peter): pass a different type of msg here as well + LLRPPDU pdu(3, header, NULL); + OLA_ASSERT_EQ((unsigned int) 26, 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((unsigned int) size, bytes_used); + + LLRPInflator inflator; + HeaderSet header_set; + OLA_ASSERT(inflator.InflatePDUBlock(&header_set, data, size)); + OLA_ASSERT(header == header_set.GetLLRPHeader()); + delete[] data; +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/LLRPPDU.cpp b/libs/acn/LLRPPDU.cpp new file mode 100644 index 0000000000..5d8eba531d --- /dev/null +++ b/libs/acn/LLRPPDU.cpp @@ -0,0 +1,117 @@ +/* + * 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. + * + * LLRPPDU.cpp + * The LLRPPDU + * Copyright (C) 2020 Peter Newman + */ + + +#include "ola/Logging.h" +#include "ola/base/Array.h" +#include "ola/network/NetworkUtils.h" +#include "libs/acn/LLRPPDU.h" + +namespace ola { +namespace acn { + +using ola::io::OutputStream; +using ola::network::HostToNetwork; + +/* + * Size of the header portion. + */ +unsigned int LLRPPDU::HeaderSize() const { + return sizeof(LLRPHeader::llrp_pdu_header); +} + + +/* + * Size of the data portion + */ +unsigned int LLRPPDU::DataSize() const { + return m_pdu ? m_pdu->Size() : 0; +} + + +/* + * Pack the header portion. + */ +bool LLRPPDU::PackHeader(uint8_t *data, unsigned int *length) const { + unsigned int header_size = HeaderSize(); + + if (*length < header_size) { + OLA_WARN << "LLRPPDU::PackHeader: buffer too small, got " << *length + << " required " << header_size; + *length = 0; + return false; + } + + LLRPHeader::llrp_pdu_header header; + m_header.DestinationCid().Pack(header.destination_cid); + header.transaction_number = HostToNetwork(m_header.TransactionNumber()); + *length = sizeof(LLRPHeader::llrp_pdu_header); + memcpy(data, &header, *length); + return true; +} + + +/* + * Pack the data portion. + */ +bool LLRPPDU::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 LLRPPDU::PackHeader(OutputStream *stream) const { + LLRPHeader::llrp_pdu_header header; + m_header.DestinationCid().Pack(header.destination_cid); + header.transaction_number = HostToNetwork(m_header.TransactionNumber()); + stream->Write(reinterpret_cast(&header), + sizeof(LLRPHeader::llrp_pdu_header)); +} + + +/* + * Pack the data into a buffer + */ +void LLRPPDU::PackData(OutputStream *stream) const { + if (m_pdu) + m_pdu->Write(stream); +} + + +void LLRPPDU::PrependPDU(ola::io::IOStack *stack, uint32_t vector, + const ola::acn::CID &destination_cid, uint32_t transaction_number) { + LLRPHeader::llrp_pdu_header header; + destination_cid.Pack(header.destination_cid); + header.transaction_number = HostToNetwork(transaction_number); + stack->Write(reinterpret_cast(&header), + sizeof(LLRPHeader::llrp_pdu_header)); + + vector = HostToNetwork(vector); + stack->Write(reinterpret_cast(&vector), sizeof(vector)); + // Flags for LLRP should always be 0xF0 + PrependFlagsAndLength(stack, 0xf0); +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/LLRPPDU.h b/libs/acn/LLRPPDU.h new file mode 100644 index 0000000000..76ccdc7d65 --- /dev/null +++ b/libs/acn/LLRPPDU.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. + * + * LLRPPDU.h + * Interface for the LLRPPDU class + * Copyright (C) 2020 Peter Newman + */ + +#ifndef LIBS_ACN_LLRPPDU_H_ +#define LIBS_ACN_LLRPPDU_H_ + +#include +#include + +#include "libs/acn/PDU.h" +#include "libs/acn/LLRPHeader.h" + +namespace ola { +namespace acn { + +class RDMPDU; + +class LLRPPDU: public PDU { + public: + LLRPPDU(unsigned int vector, + const LLRPHeader &header, + const PDU *pdu): + PDU(vector), + m_header(header), + m_pdu(pdu) {} + ~LLRPPDU() {} + + 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 &destination_cid, uint32_t transaction_number); + + private: + LLRPHeader m_header; + const PDU *m_pdu; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_LLRPPDU_H_ diff --git a/libs/acn/LLRPPDUTest.cpp b/libs/acn/LLRPPDUTest.cpp new file mode 100644 index 0000000000..b924d8a422 --- /dev/null +++ b/libs/acn/LLRPPDUTest.cpp @@ -0,0 +1,147 @@ +/* + * 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. + * + * LLRPPDUTest.cpp + * Test fixture for the LLRPPDU class + * Copyright (C) 2020 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/LLRPPDU.h" +#include "libs/acn/PDUTestCommon.h" + + +namespace ola { +namespace acn { + +using ola::io::IOQueue; +using ola::io::OutputStream; +using ola::network::HostToNetwork; +using std::string; + +class LLRPPDUTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LLRPPDUTest); + CPPUNIT_TEST(testSimpleLLRPPDU); + CPPUNIT_TEST(testSimpleLLRPPDUToOutputStream); + CPPUNIT_TEST_SUITE_END(); + + public: + void testSimpleLLRPPDU(); + void testSimpleLLRPPDUToOutputStream(); + + 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 LLRPPDUTest::TEST_DATA[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15}; + +CPPUNIT_TEST_SUITE_REGISTRATION(LLRPPDUTest); + +const unsigned int LLRPPDUTest::TEST_VECTOR = 39; + + +/* + * Test that packing a LLRPPDU without data works. + */ +void LLRPPDUTest::testSimpleLLRPPDU() { + const CID destination_cid = CID::FromData(TEST_DATA); + LLRPHeader header(destination_cid, 101); + LLRPPDU pdu(TEST_VECTOR, header, NULL); + + OLA_ASSERT_EQ(20u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(26u, 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) 0x70, data[0]); + OLA_ASSERT_EQ((uint8_t) bytes_used, data[1]); + unsigned int actual_value; + memcpy(&actual_value, data + 2, sizeof(actual_value)); + OLA_ASSERT_EQ(HostToNetwork(TEST_VECTOR), actual_value); + + uint8_t buffer[CID::CID_LENGTH]; + destination_cid.Pack(buffer); + OLA_ASSERT_FALSE(memcmp(&data[6], buffer, CID::CID_LENGTH)); + // transaction number + OLA_ASSERT_EQ((uint8_t) 0, data[6 + CID::CID_LENGTH]); + OLA_ASSERT_EQ((uint8_t) 0, data[6 + CID::CID_LENGTH + 1]); + OLA_ASSERT_EQ((uint8_t) 0, data[6 + CID::CID_LENGTH + 2]); + OLA_ASSERT_EQ((uint8_t) 101, data[6 + CID::CID_LENGTH + 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 LLRPPDUTest::testSimpleLLRPPDUToOutputStream() { + const ola::acn::CID destination_cid = CID::FromData(TEST_DATA); + LLRPHeader header(destination_cid, 101); + LLRPPDU pdu(TEST_VECTOR, header, NULL); + + OLA_ASSERT_EQ(20u, pdu.HeaderSize()); + OLA_ASSERT_EQ(0u, pdu.DataSize()); + OLA_ASSERT_EQ(26u, pdu.Size()); + + IOQueue output; + OutputStream stream(&output); + pdu.Write(&stream); + OLA_ASSERT_EQ(26u, 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, 0x1a, + 0, 0, 0, 39, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 101, // transaction number + }; + 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 57bcf5276e..42d91ea17d 100644 --- a/libs/acn/Makefile.mk +++ b/libs/acn/Makefile.mk @@ -61,6 +61,11 @@ libs_acn_libolae131core_la_SOURCES = \ libs/acn/E133StatusPDU.cpp \ libs/acn/E133StatusPDU.h \ libs/acn/HeaderSet.h \ + libs/acn/LLRPHeader.h \ + libs/acn/LLRPInflator.cpp \ + libs/acn/LLRPInflator.h \ + libs/acn/LLRPPDU.cpp \ + libs/acn/LLRPPDU.h \ libs/acn/PDU.cpp \ libs/acn/PDU.h \ libs/acn/PDUTestCommon.h \ @@ -108,6 +113,7 @@ libs_acn_e131_loadtest_LDADD = libs/acn/libolae131core.la test_programs += \ libs/acn/E131Tester \ libs/acn/E133Tester \ + libs/acn/LLRPTester \ libs/acn/TransportTester libs_acn_E131Tester_SOURCES = \ @@ -140,6 +146,14 @@ libs_acn_E133Tester_LDADD = \ libs/acn/libolae131core.la \ $(COMMON_TESTING_LIBS) +libs_acn_LLRPTester_SOURCES = \ + libs/acn/LLRPInflatorTest.cpp \ + libs/acn/LLRPPDUTest.cpp +libs_acn_LLRPTester_CPPFLAGS = $(COMMON_TESTING_FLAGS) +libs_acn_LLRPTester_LDADD = \ + libs/acn/libolae131core.la \ + $(COMMON_TESTING_LIBS) + libs_acn_TransportTester_SOURCES = \ libs/acn/TCPTransportTest.cpp \ libs/acn/UDPTransportTest.cpp From bd89fea38e8547f2f71cc5f8f452acfbdabd2b30 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Mon, 3 Feb 2020 14:30:00 +0000 Subject: [PATCH 15/86] Update some E1.33 Vectors (cherry picked from commit 674ea511416bb3a8d955a1755d5251db6c53deeb) --- include/ola/acn/ACNVectors.h | 10 +++++++++- libs/acn/E133Inflator.h | 2 +- tools/e133/MessageBuilder.cpp | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index 9e8211ff13..4e5a2bf520 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -45,7 +45,7 @@ namespace acn { enum RootVector { VECTOR_ROOT_E131_REV2 = 3, /**< Draft E1.31, used by some old gear. */ VECTOR_ROOT_E131 = 4, /**< E1.31 (sACN) */ - VECTOR_ROOT_E133 = 5, /**< E1.33 (RDNNet) */ + VECTOR_ROOT_RPT = 5, /**< E1.33 (RPT) */ VECTOR_ROOT_NULL = 6, /**< NULL (empty) root */ VECTOR_ROOT_BROKER = 9, /**< E1.33 (Broker) */ VECTOR_ROOT_LLRP = 0x0A, /**< E1.33 (LLRP) */ @@ -90,6 +90,14 @@ enum E133ControllerVector { VECTOR_CONTROLLER_EXPECT_MASTER = 5, /**< Expect master message */ }; +/** + * @brief Vectors used at the E1.33 LLRP layer. + */ +enum LLRPVector { + VECTOR_LLRP_PROBE_REQUEST = 1, /**< LLRP Probe Request */ + VECTOR_LLRP_PROBE_REPLY = 1, /**< LLRP Probe Reply */ + VECTOR_LLRP_RDM_CMD = 1, /**< LLRP RDM Command */ +}; /** * @} */ diff --git a/libs/acn/E133Inflator.h b/libs/acn/E133Inflator.h index ee7c968f66..d2f57daf66 100644 --- a/libs/acn/E133Inflator.h +++ b/libs/acn/E133Inflator.h @@ -38,7 +38,7 @@ class E133Inflator: public BaseInflator { } ~E133Inflator() {} - uint32_t Id() const { return ola::acn::VECTOR_ROOT_E133; } + uint32_t Id() const { return ola::acn::VECTOR_ROOT_RPT; } protected: bool DecodeHeader(HeaderSet *headers, diff --git a/tools/e133/MessageBuilder.cpp b/tools/e133/MessageBuilder.cpp index d2c6a5143a..a192b45bf0 100644 --- a/tools/e133/MessageBuilder.cpp +++ b/tools/e133/MessageBuilder.cpp @@ -109,7 +109,7 @@ void MessageBuilder::BuildTCPRootE133(IOStack *packet, uint16_t endpoint_id) { E133PDU::PrependPDU(packet, vector, m_source_name, sequence_number, endpoint_id); - RootPDU::PrependPDU(packet, ola::acn::VECTOR_ROOT_E133, m_cid); + RootPDU::PrependPDU(packet, ola::acn::VECTOR_ROOT_RPT, m_cid); PreamblePacker::AddTCPPreamble(packet); } @@ -123,7 +123,7 @@ void MessageBuilder::BuildUDPRootE133(IOStack *packet, uint16_t endpoint_id) { E133PDU::PrependPDU(packet, vector, m_source_name, sequence_number, endpoint_id); - RootPDU::PrependPDU(packet, ola::acn::VECTOR_ROOT_E133, m_cid); + RootPDU::PrependPDU(packet, ola::acn::VECTOR_ROOT_RPT, m_cid); PreamblePacker::AddUDPPreamble(packet); } } // namespace e133 From 8e7b75199ee0a2f70e01f3b96b350a901e5a1f72 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 4 Feb 2020 13:39:23 +0000 Subject: [PATCH 16/86] Tidy some Doxygen (cherry picked from commit f1cc481d6d900de8db5a64334fe7419b41bfffa4) --- include/ola/acn/ACNVectors.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index 4e5a2bf520..fc08d266ff 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -98,6 +98,7 @@ enum LLRPVector { VECTOR_LLRP_PROBE_REPLY = 1, /**< LLRP Probe Reply */ VECTOR_LLRP_RDM_CMD = 1, /**< LLRP RDM Command */ }; + /** * @} */ From d9ef9fda716d0965db6e3dd865b975ba6cd198b6 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 4 Feb 2020 16:46:09 +0000 Subject: [PATCH 17/86] Fix the lint issues (cherry picked from commit 2d0ed43d1d351c696a8c5122c6c469d79bd2ee9f) --- libs/acn/LLRPPDU.cpp | 6 ++++-- libs/acn/LLRPPDUTest.cpp | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/acn/LLRPPDU.cpp b/libs/acn/LLRPPDU.cpp index 5d8eba531d..e13fcce225 100644 --- a/libs/acn/LLRPPDU.cpp +++ b/libs/acn/LLRPPDU.cpp @@ -100,8 +100,10 @@ void LLRPPDU::PackData(OutputStream *stream) const { } -void LLRPPDU::PrependPDU(ola::io::IOStack *stack, uint32_t vector, - const ola::acn::CID &destination_cid, uint32_t transaction_number) { +void LLRPPDU::PrependPDU(ola::io::IOStack *stack, + uint32_t vector, + const ola::acn::CID &destination_cid, + uint32_t transaction_number) { LLRPHeader::llrp_pdu_header header; destination_cid.Pack(header.destination_cid); header.transaction_number = HostToNetwork(transaction_number); diff --git a/libs/acn/LLRPPDUTest.cpp b/libs/acn/LLRPPDUTest.cpp index b924d8a422..af85b283e5 100644 --- a/libs/acn/LLRPPDUTest.cpp +++ b/libs/acn/LLRPPDUTest.cpp @@ -35,7 +35,6 @@ namespace acn { using ola::io::IOQueue; using ola::io::OutputStream; using ola::network::HostToNetwork; -using std::string; class LLRPPDUTest: public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(LLRPPDUTest); From ee0a5ab90f3dd6b3128a578dafd35072e4a73725 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 4 Feb 2020 15:35:15 +0000 Subject: [PATCH 18/86] Add LLRP Probe Request PDU, fix the length flags bug (cherry picked from commit e9dd3742f9310c0a72bccacfc45cfb9bacf115aa) --- include/ola/acn/ACNFlags.h | 70 +++++++++++++++++++++++++++++++++++ include/ola/acn/Makefile.mk | 1 + libs/acn/BaseInflator.cpp | 4 +- libs/acn/BaseInflator.h | 7 +++- libs/acn/BaseInflatorTest.cpp | 18 ++++----- libs/acn/LLRPInflatorTest.cpp | 2 +- libs/acn/LLRPPDU.cpp | 3 +- libs/acn/LLRPPDU.h | 8 ++-- libs/acn/LLRPPDUTest.cpp | 25 +++++++------ libs/acn/PDU.cpp | 32 ++++++++++++---- libs/acn/PDU.h | 37 +++++++++++++----- 11 files changed, 159 insertions(+), 48 deletions(-) create mode 100644 include/ola/acn/ACNFlags.h diff --git a/include/ola/acn/ACNFlags.h b/include/ola/acn/ACNFlags.h new file mode 100644 index 0000000000..a055a429b0 --- /dev/null +++ b/include/ola/acn/ACNFlags.h @@ -0,0 +1,70 @@ +/* + * 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. + * + * ACNFlags.h + * Flags used in ACN PDUs + * Copyright (C) 2020 Peter Newman + */ + +#ifndef INCLUDE_OLA_ACN_ACNFLAGS_H_ +#define INCLUDE_OLA_ACN_ACNFLAGS_H_ + +/** + * @addtogroup acn + * @{ + * @file ACNFlags.h + * @brief ACN flag values. + * @} + */ + +#include + +namespace ola { +namespace acn { + +/** + * @addtogroup acn + * @{ + */ + +// masks for the flag fields +/** + * @brief This indicates a 20 bit length field (default is 12 bits) + */ +static const uint8_t LFLAG_MASK = 0x80; + +/** + * @brief This indicates a vector is present + */ +static const uint8_t VFLAG_MASK = 0x40; + +/** + * @brief This indicates a header field is present + */ +static const uint8_t HFLAG_MASK = 0x20; + +/** + * @brief This indicates a data field is present + */ +static const uint8_t DFLAG_MASK = 0x10; + +/** + * @} + */ + +} // namespace acn +} // namespace ola + +#endif // INCLUDE_OLA_ACN_ACNFLAGS_H_ diff --git a/include/ola/acn/Makefile.mk b/include/ola/acn/Makefile.mk index 56bc647eb5..afd628d812 100644 --- a/include/ola/acn/Makefile.mk +++ b/include/ola/acn/Makefile.mk @@ -3,6 +3,7 @@ olaacninclude_HEADERS = if INSTALL_ACN olaacninclude_HEADERS += \ + include/ola/acn/ACNFlags.h \ include/ola/acn/ACNPort.h \ include/ola/acn/ACNVectors.h \ include/ola/acn/CID.h diff --git a/libs/acn/BaseInflator.cpp b/libs/acn/BaseInflator.cpp index e3917967ad..a41dca370c 100644 --- a/libs/acn/BaseInflator.cpp +++ b/libs/acn/BaseInflator.cpp @@ -163,7 +163,7 @@ bool BaseInflator::DecodeLength(const uint8_t *data, bool BaseInflator::DecodeVector(uint8_t flags, const uint8_t *data, unsigned int length, uint32_t *vector, unsigned int *bytes_used) { - if (flags & PDU::VFLAG_MASK) { + if (flags & ola::acn::VFLAG_MASK) { if ((unsigned int) m_vector_size > length) { *vector = 0; *bytes_used = 0; @@ -223,7 +223,7 @@ bool BaseInflator::InflatePDU(HeaderSet *headers, return false; } - if (flags & PDU::HFLAG_MASK) { + if (flags & ola::acn::HFLAG_MASK) { result = DecodeHeader(headers, data + data_offset, pdu_len - data_offset, &header_bytes_used); diff --git a/libs/acn/BaseInflator.h b/libs/acn/BaseInflator.h index 384351bc28..07b7c6b88b 100644 --- a/libs/acn/BaseInflator.h +++ b/libs/acn/BaseInflator.h @@ -87,8 +87,11 @@ class BaseInflator : public InflatorInterface { unsigned int len); // masks for the flag fields - // This indicates a 20 bit length field (default is 12 bits) - static const uint8_t LFLAG_MASK = 0x80; + /** + * @brief This indicates a 20 bit length field (default is 12 bits) + * @deprecated Use ola::acn::LFLAG_MASK instead (4 Feb 2020). + */ + static const uint8_t LFLAG_MASK = ola::acn::LFLAG_MASK; // This masks the first 4 bits of the length field static const uint8_t LENGTH_MASK = 0x0F; diff --git a/libs/acn/BaseInflatorTest.cpp b/libs/acn/BaseInflatorTest.cpp index 17e86121b8..a4e0a0dd81 100644 --- a/libs/acn/BaseInflatorTest.cpp +++ b/libs/acn/BaseInflatorTest.cpp @@ -204,7 +204,7 @@ void BaseInflatorTest::testDecodeVector() { uint8_t data[] = {1, 2, 3, 4, 5, 6}; // the test data unsigned int vector = 1; unsigned int bytes_used = 0; - uint8_t flags = PDU::VFLAG_MASK; + uint8_t flags = VFLAG_MASK; OLA_ASSERT_FALSE(inflator.DecodeVector(flags, data, 0, &vector, &bytes_used)); OLA_ASSERT_EQ((unsigned int) 0, vector); @@ -235,7 +235,7 @@ void BaseInflatorTest::testDecodeVector() { } // now try with a vector size of 2 - flags = PDU::VFLAG_MASK; + flags = VFLAG_MASK; TestInflator inflator2(0, PDU::TWO_BYTES); for (unsigned int i = 0; i < 2; i++) { OLA_ASSERT_FALSE( @@ -270,7 +270,7 @@ void BaseInflatorTest::testDecodeVector() { } // now try with a vector size of 4 - flags = PDU::VFLAG_MASK; + flags = VFLAG_MASK; TestInflator inflator4(0, PDU::FOUR_BYTES); for (unsigned int i = 0; i < 4; i++) { OLA_ASSERT_FALSE( @@ -297,7 +297,7 @@ void BaseInflatorTest::testDecodeVector() { void BaseInflatorTest::testInflatePDU() { TestInflator inflator; // test with a vector size of 2 HeaderSet header_set; - uint8_t flags = PDU::VFLAG_MASK; + uint8_t flags = VFLAG_MASK; unsigned int data_size = static_cast(PDU::TWO_BYTES + sizeof(PDU_DATA)); uint8_t *data = new uint8_t[data_size]; @@ -324,7 +324,7 @@ void BaseInflatorTest::testInflatePDUBlock() { length_size + PDU::TWO_BYTES + sizeof(PDU_DATA)); uint8_t *data = new uint8_t[data_size]; // setup the vector - data[0] = PDU::VFLAG_MASK; + data[0] = VFLAG_MASK; data[1] = static_cast(data_size); data[2] = 0x01; data[3] = 0x21; @@ -337,14 +337,14 @@ void BaseInflatorTest::testInflatePDUBlock() { // inflate a multi-pdu block data = new uint8_t[2 * data_size]; - data[0] = PDU::VFLAG_MASK; + data[0] = VFLAG_MASK; data[1] = static_cast(data_size); data[2] = 0x01; data[3] = 0x21; memcpy(data + length_size + PDU::TWO_BYTES, PDU_DATA, sizeof(PDU_DATA)); - data[data_size] = PDU::VFLAG_MASK; + data[data_size] = VFLAG_MASK; data[data_size + 1] = static_cast(data_size); data[data_size + 2] = 0x01; data[data_size + 3] = 0x21; @@ -362,11 +362,11 @@ void BaseInflatorTest::testInflatePDUBlock() { unsigned int pdu_size = data_size + length_size + PDU::TWO_BYTES; data = new uint8_t[pdu_size]; - data[0] = PDU::VFLAG_MASK; + data[0] = VFLAG_MASK; data[1] = static_cast(pdu_size); data[2] = 0x01; data[3] = 0x21; - data[4] = PDU::VFLAG_MASK; + data[4] = VFLAG_MASK; data[5] = static_cast(data_size); data[6] = 0x01; data[7] = 0x21; diff --git a/libs/acn/LLRPInflatorTest.cpp b/libs/acn/LLRPInflatorTest.cpp index b36c5cdc05..16bcd96431 100644 --- a/libs/acn/LLRPInflatorTest.cpp +++ b/libs/acn/LLRPInflatorTest.cpp @@ -108,7 +108,7 @@ void LLRPInflatorTest::testInflatePDU() { LLRPHeader header(destination_cid, 2370); // TODO(Peter): pass a different type of msg here as well LLRPPDU pdu(3, header, NULL); - OLA_ASSERT_EQ((unsigned int) 26, pdu.Size()); + OLA_ASSERT_EQ((unsigned int) 27, pdu.Size()); unsigned int size = pdu.Size(); uint8_t *data = new uint8_t[size]; diff --git a/libs/acn/LLRPPDU.cpp b/libs/acn/LLRPPDU.cpp index e13fcce225..4fb3b3644f 100644 --- a/libs/acn/LLRPPDU.cpp +++ b/libs/acn/LLRPPDU.cpp @@ -112,8 +112,7 @@ void LLRPPDU::PrependPDU(ola::io::IOStack *stack, vector = HostToNetwork(vector); stack->Write(reinterpret_cast(&vector), sizeof(vector)); - // Flags for LLRP should always be 0xF0 - PrependFlagsAndLength(stack, 0xf0); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); } } // namespace acn } // namespace ola diff --git a/libs/acn/LLRPPDU.h b/libs/acn/LLRPPDU.h index 76ccdc7d65..a2636c1a9c 100644 --- a/libs/acn/LLRPPDU.h +++ b/libs/acn/LLRPPDU.h @@ -37,7 +37,7 @@ class LLRPPDU: public PDU { LLRPPDU(unsigned int vector, const LLRPHeader &header, const PDU *pdu): - PDU(vector), + PDU(vector, FOUR_BYTES, true), m_header(header), m_pdu(pdu) {} ~LLRPPDU() {} @@ -50,8 +50,10 @@ class LLRPPDU: public PDU { 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 &destination_cid, uint32_t transaction_number); + static void PrependPDU(ola::io::IOStack *stack, + uint32_t vector, + const ola::acn::CID &destination_cid, + uint32_t transaction_number); private: LLRPHeader m_header; diff --git a/libs/acn/LLRPPDUTest.cpp b/libs/acn/LLRPPDUTest.cpp index af85b283e5..01c30db22a 100644 --- a/libs/acn/LLRPPDUTest.cpp +++ b/libs/acn/LLRPPDUTest.cpp @@ -73,7 +73,7 @@ void LLRPPDUTest::testSimpleLLRPPDU() { OLA_ASSERT_EQ(20u, pdu.HeaderSize()); OLA_ASSERT_EQ(0u, pdu.DataSize()); - OLA_ASSERT_EQ(26u, pdu.Size()); + OLA_ASSERT_EQ(27u, pdu.Size()); unsigned int size = pdu.Size(); uint8_t *data = new uint8_t[size]; @@ -82,20 +82,21 @@ void LLRPPDUTest::testSimpleLLRPPDU() { OLA_ASSERT_EQ(size, bytes_used); // spot check the data - OLA_ASSERT_EQ((uint8_t) 0x70, data[0]); - OLA_ASSERT_EQ((uint8_t) bytes_used, data[1]); + 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 + 2, sizeof(actual_value)); + memcpy(&actual_value, data + 3, sizeof(actual_value)); OLA_ASSERT_EQ(HostToNetwork(TEST_VECTOR), actual_value); uint8_t buffer[CID::CID_LENGTH]; destination_cid.Pack(buffer); - OLA_ASSERT_FALSE(memcmp(&data[6], buffer, CID::CID_LENGTH)); + OLA_ASSERT_DATA_EQUALS(&data[7], CID::CID_LENGTH, buffer, sizeof(buffer)); // transaction number - OLA_ASSERT_EQ((uint8_t) 0, data[6 + CID::CID_LENGTH]); - OLA_ASSERT_EQ((uint8_t) 0, data[6 + CID::CID_LENGTH + 1]); - OLA_ASSERT_EQ((uint8_t) 0, data[6 + CID::CID_LENGTH + 2]); - OLA_ASSERT_EQ((uint8_t) 101, data[6 + CID::CID_LENGTH + 3]); + OLA_ASSERT_EQ((uint8_t) 0, data[7 + CID::CID_LENGTH]); + OLA_ASSERT_EQ((uint8_t) 0, data[7 + CID::CID_LENGTH + 1]); + OLA_ASSERT_EQ((uint8_t) 0, data[7 + CID::CID_LENGTH + 2]); + OLA_ASSERT_EQ((uint8_t) 101, data[7 + CID::CID_LENGTH + 3]); // test undersized buffer bytes_used = size - 1; @@ -120,19 +121,19 @@ void LLRPPDUTest::testSimpleLLRPPDUToOutputStream() { OLA_ASSERT_EQ(20u, pdu.HeaderSize()); OLA_ASSERT_EQ(0u, pdu.DataSize()); - OLA_ASSERT_EQ(26u, pdu.Size()); + OLA_ASSERT_EQ(27u, pdu.Size()); IOQueue output; OutputStream stream(&output); pdu.Write(&stream); - OLA_ASSERT_EQ(26u, output.Size()); + OLA_ASSERT_EQ(27u, 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, 0x1a, + 0xf0, 0x00, 0x1b, 0, 0, 0, 39, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, diff --git a/libs/acn/PDU.cpp b/libs/acn/PDU.cpp index c9166db6cb..0f256eca13 100644 --- a/libs/acn/PDU.cpp +++ b/libs/acn/PDU.cpp @@ -35,8 +35,9 @@ using ola::network::HostToNetwork; unsigned int PDU::Size() const { unsigned int length = m_vector_size + HeaderSize() + DataSize(); - if (length > TWOB_LENGTH_LIMIT - 2) + if ((length > TWOB_LENGTH_LIMIT - 2) || m_force_length_flag) { length += 1; + } length += 2; return length; } @@ -59,7 +60,7 @@ bool PDU::Pack(uint8_t *buffer, unsigned int *length) const { return false; } - if (size <= TWOB_LENGTH_LIMIT) { + if (size <= TWOB_LENGTH_LIMIT && !m_force_length_flag) { buffer[0] = (uint8_t) ((size & 0x0f00) >> 8); buffer[1] = (uint8_t) (size & 0xff); } else { @@ -69,6 +70,11 @@ bool PDU::Pack(uint8_t *buffer, unsigned int *length) const { offset += 1; } + if (m_force_length_flag) { + // TODO(Peter): Should this happen regardless of the force when we're + // writing 20 bits of length? + buffer[0] |= LFLAG_MASK; + } buffer[0] |= VFLAG_MASK; buffer[0] |= HFLAG_MASK; buffer[0] |= DFLAG_MASK; @@ -117,13 +123,18 @@ bool PDU::Pack(uint8_t *buffer, unsigned int *length) const { void PDU::Write(OutputStream *stream) const { unsigned int size = Size(); - if (size <= TWOB_LENGTH_LIMIT) { + if (size <= TWOB_LENGTH_LIMIT && !m_force_length_flag) { uint16_t flags_and_length = static_cast(size); flags_and_length |= (VFLAG_MASK | HFLAG_MASK | DFLAG_MASK) << 8u; *stream << HostToNetwork(flags_and_length); } else { uint8_t vhl_flags = static_cast((size & 0x0f0000) >> 16); vhl_flags |= VFLAG_MASK | HFLAG_MASK | DFLAG_MASK; + if (m_force_length_flag) { + // TODO(Peter): Should this happen regardless of the force as we're + // writing 20 bits of length? + vhl_flags |= LFLAG_MASK; + } *stream << vhl_flags; *stream << (uint8_t) ((size & 0xff00) >> 8); *stream << (uint8_t) (size & 0xff); @@ -150,8 +161,9 @@ void PDU::Write(OutputStream *stream) const { * Prepend the flags and length to an OutputBufferInterface. */ void PDU::PrependFlagsAndLength(ola::io::OutputBufferInterface *output, - uint8_t flags) { - PrependFlagsAndLength(output, output->Size(), flags); + uint8_t flags, + bool force_length_flag) { + PrependFlagsAndLength(output, output->Size(), flags, force_length_flag); } @@ -160,8 +172,9 @@ void PDU::PrependFlagsAndLength(ola::io::OutputBufferInterface *output, */ void PDU::PrependFlagsAndLength(ola::io::OutputBufferInterface *output, unsigned int size, - uint8_t flags) { - if (size + 2 <= TWOB_LENGTH_LIMIT) { + uint8_t flags, + bool force_length_flag) { + if (size + 2 <= TWOB_LENGTH_LIMIT && !force_length_flag) { size += 2; uint16_t flags_and_length = static_cast(size); flags_and_length |= static_cast(flags << 8u); @@ -173,6 +186,11 @@ void PDU::PrependFlagsAndLength(ola::io::OutputBufferInterface *output, uint8_t flags_and_length[3]; flags_and_length[0] = static_cast((size & 0x0f0000) >> 16); flags_and_length[0] |= flags; + if (force_length_flag) { + // TODO(Peter): Should this happen regardless of the force as we're + // writing 20 bits of length? + flags_and_length[0] |= LFLAG_MASK; + } flags_and_length[1] = static_cast((size & 0xff00) >> 8); flags_and_length[2] = static_cast(size & 0xff); output->Write(flags_and_length, sizeof(flags_and_length)); diff --git a/libs/acn/PDU.h b/libs/acn/PDU.h index 64c1e82adb..2be285dead 100644 --- a/libs/acn/PDU.h +++ b/libs/acn/PDU.h @@ -22,6 +22,7 @@ #define LIBS_ACN_PDU_H_ #include +#include #include #include #include @@ -41,9 +42,12 @@ class PDU { FOUR_BYTES = 4, } vector_size; - explicit PDU(unsigned int vector, vector_size size = FOUR_BYTES): + explicit PDU(unsigned int vector, + vector_size size = FOUR_BYTES, + bool force_length_flag = false): m_vector(vector), - m_vector_size(size) {} + m_vector_size(size), + m_force_length_flag(force_length_flag) {} virtual ~PDU() {} // Returns the size of this PDU @@ -72,23 +76,36 @@ class PDU { static void PrependFlagsAndLength( ola::io::OutputBufferInterface *output, - uint8_t flags = VFLAG_MASK | HFLAG_MASK | DFLAG_MASK); + uint8_t flags = VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, + bool force_length_flag = false); static void PrependFlagsAndLength( ola::io::OutputBufferInterface *output, unsigned int length, - uint8_t flags); + uint8_t flags, + bool force_length_flag = false); + + /** + * @brief This indicates a vector is present. + * @deprecated Use ola::acn::VFLAG_MASK instead (4 Feb 2020). + */ + static const uint8_t VFLAG_MASK = ola::acn::VFLAG_MASK; + /** + * @brief This indicates a header field is present. + * @deprecated Use ola::acn::HFLAG_MASK instead (4 Feb 2020). + */ + static const uint8_t HFLAG_MASK = ola::acn::HFLAG_MASK; + /** + * @brief This indicates a data field is present. + * @deprecated Use ola::acn::DFLAG_MASK instead (4 Feb 2020). + */ + static const uint8_t DFLAG_MASK = ola::acn::DFLAG_MASK; - // This indicates a vector is present - static const uint8_t VFLAG_MASK = 0x40; - // This indicates a header field is present - static const uint8_t HFLAG_MASK = 0x20; - // This indicates a data field is present - static const uint8_t DFLAG_MASK = 0x10; private: unsigned int m_vector; unsigned int m_vector_size; + bool m_force_length_flag; // The max PDU length that can be represented with the 2 byte format for // the length field. From bb597ce1891ec1d315d5ec77e826393d5b0d3bc5 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 2 Mar 2024 22:03:00 +0000 Subject: [PATCH 19/86] Correct the documentation about the SPI sync port option --- plugins/spi/SPIPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/spi/SPIPlugin.cpp b/plugins/spi/SPIPlugin.cpp index 57954a1a00..fda2963c86 100644 --- a/plugins/spi/SPIPlugin.cpp +++ b/plugins/spi/SPIPlugin.cpp @@ -159,7 +159,7 @@ string SPIPlugin::Description() const { "If the software backend is used, this defines the number of ports which\n" "will be created.\n" "\n" -"-sync-ports = \n" +"-sync-port = \n" "Controls which port triggers a flush (write) of the SPI data. If set to -1\n" "the SPI data is written when any port changes. This can result in a lot of\n" "data writes (slow) and partial frames. If set to -2, the last port is used.\n" From 3fff0809800eb54600105e011789b0da02323a08 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 13 Mar 2024 16:23:52 +0000 Subject: [PATCH 20/86] Fix a typo in a private constant --- plugins/usbpro/DmxterWidget.cpp | 4 ++-- plugins/usbpro/DmxterWidget.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/usbpro/DmxterWidget.cpp b/plugins/usbpro/DmxterWidget.cpp index 4b061aa3b9..5158bd0288 100644 --- a/plugins/usbpro/DmxterWidget.cpp +++ b/plugins/usbpro/DmxterWidget.cpp @@ -50,7 +50,7 @@ const uint8_t DmxterWidgetImpl::TOD_LABEL = 0x82; const uint8_t DmxterWidgetImpl::DISCOVERY_BRANCH_LABEL = 0x83; const uint8_t DmxterWidgetImpl::FULL_DISCOVERY_LABEL = 0x84; const uint8_t DmxterWidgetImpl::INCREMENTAL_DISCOVERY_LABEL = 0x85; -const uint8_t DmxterWidgetImpl::SHUTDOWN_LABAEL = 0xf0; +const uint8_t DmxterWidgetImpl::SHUTDOWN_LABEL = 0xf0; /* @@ -195,7 +195,7 @@ void DmxterWidgetImpl::HandleMessage(uint8_t label, case RDM_BCAST_REQUEST_LABEL: HandleBroadcastRDMResponse(data, length); break; - case SHUTDOWN_LABAEL: + case SHUTDOWN_LABEL: HandleShutdown(data, length); break; default: diff --git a/plugins/usbpro/DmxterWidget.h b/plugins/usbpro/DmxterWidget.h index 3e48ef1763..8a2355f4d9 100644 --- a/plugins/usbpro/DmxterWidget.h +++ b/plugins/usbpro/DmxterWidget.h @@ -77,7 +77,7 @@ class DmxterWidgetImpl: public BaseUsbProWidget, static const uint8_t DISCOVERY_BRANCH_LABEL; static const uint8_t FULL_DISCOVERY_LABEL; static const uint8_t INCREMENTAL_DISCOVERY_LABEL; - static const uint8_t SHUTDOWN_LABAEL; + static const uint8_t SHUTDOWN_LABEL; typedef enum { RC_CHECKSUM_ERROR = 1, From 2e0a388a767dcc9dbb1a70d86efc22e4966bf514 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 13 Mar 2024 16:27:21 +0000 Subject: [PATCH 21/86] Fix some minor comments --- common/rdm/QueueingRDMController.cpp | 2 +- common/rdm/QueueingRDMControllerTest.cpp | 2 +- include/ola/rdm/QueueingRDMController.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/rdm/QueueingRDMController.cpp b/common/rdm/QueueingRDMController.cpp index c8c4a8b332..22b5814267 100644 --- a/common/rdm/QueueingRDMController.cpp +++ b/common/rdm/QueueingRDMController.cpp @@ -14,7 +14,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * QueueingRDMController.cpp - * The Jese DMX TRI device. + * An RDM Controller that sends a single message at a time. * Copyright (C) 2010 Simon Newton */ diff --git a/common/rdm/QueueingRDMControllerTest.cpp b/common/rdm/QueueingRDMControllerTest.cpp index 28a22ee0ba..fbdd09a16a 100644 --- a/common/rdm/QueueingRDMControllerTest.cpp +++ b/common/rdm/QueueingRDMControllerTest.cpp @@ -14,7 +14,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * QueueingRDMControllerTest.cpp - * Test fixture for the UID classes + * Test fixture for the QueueingRDMController * Copyright (C) 2005 Simon Newton */ diff --git a/include/ola/rdm/QueueingRDMController.h b/include/ola/rdm/QueueingRDMController.h index acb6527eca..8311b7122a 100644 --- a/include/ola/rdm/QueueingRDMController.h +++ b/include/ola/rdm/QueueingRDMController.h @@ -14,7 +14,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * QueueingRDMController.h - * A RDM Controller that sends a single message at a time. + * An RDM Controller that sends a single message at a time. * Copyright (C) 2010 Simon Newton */ From cb1d8f769dc61a645ea231886a6a1ef760af43bb Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 12:38:09 +0000 Subject: [PATCH 22/86] Improve clarity with more braces --- libs/acn/LLRPHeader.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/acn/LLRPHeader.h b/libs/acn/LLRPHeader.h index 1d964268fd..c0761cd5c0 100644 --- a/libs/acn/LLRPHeader.h +++ b/libs/acn/LLRPHeader.h @@ -49,8 +49,8 @@ class LLRPHeader { uint32_t TransactionNumber() const { return m_transaction_number; } bool operator==(const LLRPHeader &other) const { - return m_destination_cid == other.m_destination_cid && - m_transaction_number == other.m_transaction_number; + return ((m_destination_cid == other.m_destination_cid) && + (m_transaction_number == other.m_transaction_number)); } PACK( From 30dd9133a9488546e441e813871bd0d46bb90125 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 4 Feb 2020 00:14:24 +0000 Subject: [PATCH 23/86] Add the initial LLRPProbeRequestPDU (cherry picked from commit 0204d595c8f2753e0581d8bb88020a12dddc9ea1) --- include/ola/acn/ACNPort.h | 5 ++ libs/acn/LLRPHeader.h | 2 + libs/acn/LLRPPDU.h | 2 - libs/acn/LLRPProbeRequestPDU.cpp | 62 ++++++++++++++++++++ libs/acn/LLRPProbeRequestPDU.h | 62 ++++++++++++++++++++ libs/acn/LLRPProbeRequestPDUTest.cpp | 85 ++++++++++++++++++++++++++++ libs/acn/Makefile.mk | 5 +- 7 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 libs/acn/LLRPProbeRequestPDU.cpp create mode 100644 libs/acn/LLRPProbeRequestPDU.h create mode 100644 libs/acn/LLRPProbeRequestPDUTest.cpp diff --git a/include/ola/acn/ACNPort.h b/include/ola/acn/ACNPort.h index bef7619c38..97f98a1ab2 100644 --- a/include/ola/acn/ACNPort.h +++ b/include/ola/acn/ACNPort.h @@ -61,6 +61,11 @@ const uint16_t ACN_PORT = 5568; */ const uint16_t E133_PORT = 5569; +/** + * @brief The port used for E1.33 LLRP communication. + */ +const uint16_t LLRP_PORT = 5569; + /** * @} */ diff --git a/libs/acn/LLRPHeader.h b/libs/acn/LLRPHeader.h index c0761cd5c0..8b51c0d749 100644 --- a/libs/acn/LLRPHeader.h +++ b/libs/acn/LLRPHeader.h @@ -29,6 +29,8 @@ 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 LLRP layer */ diff --git a/libs/acn/LLRPPDU.h b/libs/acn/LLRPPDU.h index a2636c1a9c..669f5b5c06 100644 --- a/libs/acn/LLRPPDU.h +++ b/libs/acn/LLRPPDU.h @@ -30,8 +30,6 @@ namespace ola { namespace acn { -class RDMPDU; - class LLRPPDU: public PDU { public: LLRPPDU(unsigned int vector, diff --git a/libs/acn/LLRPProbeRequestPDU.cpp b/libs/acn/LLRPProbeRequestPDU.cpp new file mode 100644 index 0000000000..6fe5378081 --- /dev/null +++ b/libs/acn/LLRPProbeRequestPDU.cpp @@ -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. + * + * LLRPProbeRequestPDU.cpp + * The LLRPProbeRequestPDU + * Copyright (C) 2020 Peter Newman + */ + +#include "libs/acn/LLRPProbeRequestPDU.h" + +#include +#include +#include + +namespace ola { +namespace acn { + +using ola::io::OutputStream; +using ola::network::HostToNetwork; +using ola::rdm::UID; +using std::vector; + +void LLRPProbeRequestPDU::PrependPDU(ola::io::IOStack *stack, + const UID &lower_uid, + const UID &upper_uid, + bool client_tcp_connection_inactive, + bool brokers_only, + const ola::rdm::UIDSet &known_uids) { + llrp_probe_request_pdu_data data; + lower_uid.Pack(data.lower_uid, sizeof(data.lower_uid)); + upper_uid.Pack(data.upper_uid, sizeof(data.upper_uid)); + uint16_t filter = 0; + if (client_tcp_connection_inactive) { + filter |= FILTER_CLIENT_TCP_CONNECTION_INACTIVE; + } + if (brokers_only) { + filter |= FILTER_BROKERS_ONLY; + } + data.filter = HostToNetwork(filter); + known_uids.Pack(data.known_uids, sizeof(data.known_uids)); + stack->Write(reinterpret_cast(&data), + static_cast(sizeof(llrp_probe_request_pdu_data) - + sizeof(data.known_uids) + + (known_uids.Size() * UID::LENGTH))); + uint8_t vector = HostToNetwork(VECTOR_PROBE_REQUEST_DATA); + stack->Write(reinterpret_cast(&vector), sizeof(vector)); + PrependFlagsAndLength(stack); +} +} // namespace acn +} // namespace ola diff --git a/libs/acn/LLRPProbeRequestPDU.h b/libs/acn/LLRPProbeRequestPDU.h new file mode 100644 index 0000000000..34e5ac79e0 --- /dev/null +++ b/libs/acn/LLRPProbeRequestPDU.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. + * + * LLRPProbeRequestPDU.h + * The LLRPProbeRequestPDU class + * Copyright (C) 2020 Peter Newman + */ + +#ifndef LIBS_ACN_LLRPPROBEREQUESTPDU_H_ +#define LIBS_ACN_LLRPPROBEREQUESTPDU_H_ + +#include +#include +#include + +#include "libs/acn/PDU.h" + +namespace ola { +namespace acn { + +class LLRPProbeRequestPDU : private PDU { + public: + static void PrependPDU(ola::io::IOStack *stack, + 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); + + static const uint8_t VECTOR_PROBE_REQUEST_DATA = 0x01; + + static const unsigned int LLRP_KNOWN_UID_SIZE = 200; + + // bit masks for filter + 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]; + uint8_t upper_uid[ola::rdm::UID::LENGTH]; + uint16_t filter; + 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; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_LLRPProbeRequestPDU_H_ diff --git a/libs/acn/LLRPProbeRequestPDUTest.cpp b/libs/acn/LLRPProbeRequestPDUTest.cpp new file mode 100644 index 0000000000..ca6596991c --- /dev/null +++ b/libs/acn/LLRPProbeRequestPDUTest.cpp @@ -0,0 +1,85 @@ +/* + * 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. + * + * LLRPProbeRequestPDUTest.cpp + * Test fixture for the LLRPProbeRequestPDU class + * Copyright (C) 2020 Peter Newman + */ + +#include +#include +#include + +#include "ola/Logging.h" +#include "ola/io/IOStack.h" +#include "ola/network/NetworkUtils.h" +#include "ola/rdm/UID.h" +#include "ola/rdm/UIDSet.h" +#include "ola/testing/TestUtils.h" +#include "libs/acn/PDUTestCommon.h" +#include "libs/acn/LLRPProbeRequestPDU.h" + +namespace ola { +namespace acn { + +using ola::io::IOStack; +using ola::rdm::UID; +using ola::rdm::UIDSet; + +class LLRPProbeRequestPDUTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LLRPProbeRequestPDUTest); + CPPUNIT_TEST(testPrepend); + CPPUNIT_TEST_SUITE_END(); + + public: + void testPrepend(); + + private: + static const unsigned int TEST_VECTOR; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(LLRPProbeRequestPDUTest); + +void LLRPProbeRequestPDUTest::testPrepend() { + IOStack stack; + UIDSet known_uids; + known_uids.AddUID(UID(0x1234, 0x00000001)); + known_uids.AddUID(UID(0x5678, 0x00000002)); + known_uids.AddUID(UID(0x4321, 0x12345678)); + LLRPProbeRequestPDU::PrependPDU(&stack, + UID(0x0000, 0x00000000), + UID(0xffff, 0xffffffff), + false, + false, + known_uids); + + unsigned int length = stack.Size(); + uint8_t *buffer = new uint8_t[length]; + OLA_ASSERT(stack.Read(buffer, length)); + + const uint8_t expected_data[] = { + 0xf0, 0x23, 1, + 0, 0, 0, 0, 0, 0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, + 0x12, 0x34, 0, 0, 0, 1, + 0x43, 0x21, 0x12, 0x34, 0x56, 0x78, + 0x56, 0x78, 0, 0, 0, 2, + }; + 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 42d91ea17d..3402e80be6 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/LLRPProbeRequestPDU.cpp \ + libs/acn/LLRPProbeRequestPDU.h \ libs/acn/LLRPPDU.cpp \ libs/acn/LLRPPDU.h \ libs/acn/PDU.cpp \ @@ -148,7 +150,8 @@ libs_acn_E133Tester_LDADD = \ libs_acn_LLRPTester_SOURCES = \ libs/acn/LLRPInflatorTest.cpp \ - libs/acn/LLRPPDUTest.cpp + libs/acn/LLRPPDUTest.cpp \ + libs/acn/LLRPProbeRequestPDUTest.cpp libs_acn_LLRPTester_CPPFLAGS = $(COMMON_TESTING_FLAGS) libs_acn_LLRPTester_LDADD = \ libs/acn/libolae131core.la \ From 3c5d1694ee4b35a03287686a4547914a6a9176e9 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 4 Feb 2020 14:03:25 +0000 Subject: [PATCH 24/86] Add the ability to easily write a CID to an ostream (cherry picked from commit 27c1cb51d84857b4e4da352e11f8af703ad4857e) --- include/ola/acn/CID.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/ola/acn/CID.h b/include/ola/acn/CID.h index 91c403a5f4..3b98d127d7 100644 --- a/include/ola/acn/CID.h +++ b/include/ola/acn/CID.h @@ -89,6 +89,15 @@ class CID { */ std::string ToString() const; + /** + * @brief A helper function to write a CID to an ostream. + * @param out the ostream + * @param cid the CID to write. + */ + friend std::ostream& operator<< (std::ostream &out, const CID &cid) { + return out << cid.ToString(); + } + /** * @brief Write the CID to an OutputBufferInterface */ From 5fde8e95bfb4aa81583a3424d417c8cc95604357 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 4 Feb 2020 16:46:09 +0000 Subject: [PATCH 25/86] Fix the lint issues (cherry picked from commit 2d0ed43d1d351c696a8c5122c6c469d79bd2ee9f) --- libs/acn/LLRPProbeRequestPDU.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/acn/LLRPProbeRequestPDU.h b/libs/acn/LLRPProbeRequestPDU.h index 34e5ac79e0..b39b768cf9 100644 --- a/libs/acn/LLRPProbeRequestPDU.h +++ b/libs/acn/LLRPProbeRequestPDU.h @@ -59,4 +59,4 @@ class LLRPProbeRequestPDU : private PDU { }; } // namespace acn } // namespace ola -#endif // LIBS_ACN_LLRPProbeRequestPDU_H_ +#endif // LIBS_ACN_LLRPPROBEREQUESTPDU_H_ From 3f586969fc3d1e230a03d93d1601aad7493b619e Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 6 Feb 2020 00:30:59 +0000 Subject: [PATCH 26/86] Add the LLRPProbeReplyPDU (cherry picked from commit 38d893db6b6bb1a8c0256fc7fc9320cd7ff65965) --- libs/acn/LLRPProbeReplyPDU.cpp | 50 ++++++++++++++++++ libs/acn/LLRPProbeReplyPDU.h | 59 ++++++++++++++++++++++ libs/acn/LLRPProbeReplyPDUTest.cpp | 81 ++++++++++++++++++++++++++++++ libs/acn/Makefile.mk | 3 ++ 4 files changed, 193 insertions(+) create mode 100644 libs/acn/LLRPProbeReplyPDU.cpp create mode 100644 libs/acn/LLRPProbeReplyPDU.h create mode 100644 libs/acn/LLRPProbeReplyPDUTest.cpp diff --git a/libs/acn/LLRPProbeReplyPDU.cpp b/libs/acn/LLRPProbeReplyPDU.cpp new file mode 100644 index 0000000000..830766fd85 --- /dev/null +++ b/libs/acn/LLRPProbeReplyPDU.cpp @@ -0,0 +1,50 @@ +/* + * 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. + * + * LLRPProbeReplyPDU.cpp + * The LLRPProbeReplyPDU + * Copyright (C) 2020 Peter Newman + */ + +#include "libs/acn/LLRPProbeReplyPDU.h" + +#include +#include +#include + +namespace ola { +namespace acn { + +using ola::io::OutputStream; +using ola::network::HostToNetwork; +using ola::network::MACAddress; +using ola::rdm::UID; + +void LLRPProbeReplyPDU::PrependPDU(ola::io::IOStack *stack, + const UID &target_uid, + const MACAddress &hardware_address, + const LLRPComponentType type) { + llrp_probe_reply_pdu_data data; + target_uid.Pack(data.target_uid, sizeof(data.target_uid)); + hardware_address.Pack(data.hardware_address, sizeof(data.hardware_address)); + data.type = HostToNetwork(static_cast(type)); + stack->Write(reinterpret_cast(&data), + static_cast(sizeof(llrp_probe_reply_pdu_data))); + uint8_t vector = HostToNetwork(VECTOR_PROBE_REPLY_DATA); + 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/LLRPProbeReplyPDU.h b/libs/acn/LLRPProbeReplyPDU.h new file mode 100644 index 0000000000..08bbc55835 --- /dev/null +++ b/libs/acn/LLRPProbeReplyPDU.h @@ -0,0 +1,59 @@ +/* + * 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. + * + * LLRPProbeReplyPDU.h + * The LLRPProbeReplyPDU class + * Copyright (C) 2020 Peter Newman + */ + +#ifndef LIBS_ACN_LLRPPROBEREPLYPDU_H_ +#define LIBS_ACN_LLRPPROBEREPLYPDU_H_ + +#include +#include +#include + +#include "libs/acn/PDU.h" + +namespace ola { +namespace acn { + +class LLRPProbeReplyPDU : private PDU { + public: + typedef enum { + LLRP_COMPONENT_TYPE_RPT_DEVICE = 0, /**< Device */ + LLRP_COMPONENT_TYPE_RPT_CONTROLLER = 1, /**< Controller */ + LLRP_COMPONENT_TYPE_BROKER = 2, /**< Broker */ + LLRP_COMPONENT_TYPE_NON_RDMNET = 0xff, /**< Non-RDMnet */ + } LLRPComponentType; + + static void PrependPDU(ola::io::IOStack *stack, + const ola::rdm::UID &target_uid, + const ola::network::MACAddress &hardware_address, + const LLRPComponentType type); + + static const uint8_t VECTOR_PROBE_REPLY_DATA = 0x01; + + PACK( + struct llrp_probe_reply_pdu_data_s { + uint8_t target_uid[ola::rdm::UID::LENGTH]; + uint8_t hardware_address[ola::network::MACAddress::LENGTH]; + uint8_t type; + }); + typedef struct llrp_probe_reply_pdu_data_s llrp_probe_reply_pdu_data; +}; +} // namespace acn +} // namespace ola +#endif // LIBS_ACN_LLRPPROBEREPLYPDU_H_ diff --git a/libs/acn/LLRPProbeReplyPDUTest.cpp b/libs/acn/LLRPProbeReplyPDUTest.cpp new file mode 100644 index 0000000000..2ae354c47d --- /dev/null +++ b/libs/acn/LLRPProbeReplyPDUTest.cpp @@ -0,0 +1,81 @@ +/* + * 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. + * + * LLRPProbeReplyPDUTest.cpp + * Test fixture for the LLRPProbeReplyPDU class + * Copyright (C) 2020 Peter Newman + */ + +#include +#include +#include + +#include "ola/Logging.h" +#include "ola/io/IOStack.h" +#include "ola/network/NetworkUtils.h" +#include "ola/rdm/UID.h" +#include "ola/rdm/UIDSet.h" +#include "ola/testing/TestUtils.h" +#include "libs/acn/PDUTestCommon.h" +#include "libs/acn/LLRPProbeReplyPDU.h" + +namespace ola { +namespace acn { + +using ola::acn::LLRPProbeReplyPDU; +using ola::io::IOStack; +using ola::network::MACAddress; +using ola::rdm::UID; + +class LLRPProbeReplyPDUTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LLRPProbeReplyPDUTest); + CPPUNIT_TEST(testPrepend); + CPPUNIT_TEST_SUITE_END(); + + public: + void testPrepend(); + + private: + static const unsigned int TEST_VECTOR; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(LLRPProbeReplyPDUTest); + +void LLRPProbeReplyPDUTest::testPrepend() { + IOStack stack; + UID target_uid = UID(0x4321, 0x12345678); + MACAddress hardware_address; + MACAddress::FromString("01:23:45:67:89:ab", &hardware_address); + LLRPProbeReplyPDU::PrependPDU( + &stack, + target_uid, + hardware_address, + LLRPProbeReplyPDU::LLRP_COMPONENT_TYPE_NON_RDMNET); + + 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, 0x11, 1, + 0x43, 0x21, 0x12, 0x34, 0x56, 0x78, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, + 0xff + }; + 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 3402e80be6..b203c5b258 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/LLRPProbeReplyPDU.cpp \ + libs/acn/LLRPProbeReplyPDU.h \ libs/acn/LLRPProbeRequestPDU.cpp \ libs/acn/LLRPProbeRequestPDU.h \ libs/acn/LLRPPDU.cpp \ @@ -151,6 +153,7 @@ libs_acn_E133Tester_LDADD = \ libs_acn_LLRPTester_SOURCES = \ libs/acn/LLRPInflatorTest.cpp \ libs/acn/LLRPPDUTest.cpp \ + libs/acn/LLRPProbeReplyPDUTest.cpp \ libs/acn/LLRPProbeRequestPDUTest.cpp libs_acn_LLRPTester_CPPFLAGS = $(COMMON_TESTING_FLAGS) libs_acn_LLRPTester_LDADD = \ From 82615166bf15fd0dae69a5ddf1e79b1d90808ded Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 6 Feb 2020 01:21:41 +0000 Subject: [PATCH 27/86] Fix the LLRP vector values (cherry picked from commit 956c0fb0eaedb81a303d22cbcbe60239eebe0c1a) --- include/ola/acn/ACNVectors.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index fc08d266ff..72c050ea91 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -95,8 +95,8 @@ enum E133ControllerVector { */ enum LLRPVector { VECTOR_LLRP_PROBE_REQUEST = 1, /**< LLRP Probe Request */ - VECTOR_LLRP_PROBE_REPLY = 1, /**< LLRP Probe Reply */ - VECTOR_LLRP_RDM_CMD = 1, /**< LLRP RDM Command */ + VECTOR_LLRP_PROBE_REPLY = 2, /**< LLRP Probe Reply */ + VECTOR_LLRP_RDM_CMD = 3, /**< LLRP RDM Command */ }; /** From e0e51d7bbaa0abb4eca882b36a3f75ca80250b60 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 6 Feb 2020 14:58:13 +0000 Subject: [PATCH 28/86] Add the ability to force the length flag on a Root PDU (cherry picked from commit d72c6aaf162bf2c1c7c409589f70c392353dcdb8) --- libs/acn/RootPDU.cpp | 4 ++-- libs/acn/RootPDU.h | 6 +++--- libs/acn/RootSender.cpp | 4 ++-- libs/acn/RootSender.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/acn/RootPDU.cpp b/libs/acn/RootPDU.cpp index 227406124f..cec65ed7bb 100644 --- a/libs/acn/RootPDU.cpp +++ b/libs/acn/RootPDU.cpp @@ -86,12 +86,12 @@ void RootPDU::SetBlock(const PDUBlock *block) { /* * Prepend a Root Layer flags, length, vector & header */ -void RootPDU::PrependPDU(IOStack *stack, uint32_t vector, const CID &cid) { +void RootPDU::PrependPDU(IOStack *stack, uint32_t vector, const CID &cid, bool force_length_flag) { cid.Write(stack); vector = HostToNetwork(vector); stack->Write(reinterpret_cast(&vector), sizeof(vector)); - PrependFlagsAndLength(stack); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, force_length_flag); } } // namespace acn } // namespace ola diff --git a/libs/acn/RootPDU.h b/libs/acn/RootPDU.h index cc10ff8bcc..6d66ebc178 100644 --- a/libs/acn/RootPDU.h +++ b/libs/acn/RootPDU.h @@ -33,8 +33,8 @@ namespace acn { class RootPDU: public PDU { public: - explicit RootPDU(unsigned int vector): - PDU(vector), + explicit RootPDU(unsigned int vector, bool force_length_flag = false): + PDU(vector, FOUR_BYTES, force_length_flag), m_block(NULL), m_block_size(0) {} RootPDU(unsigned int vector, @@ -60,7 +60,7 @@ class RootPDU: public PDU { void SetBlock(const PDUBlock *block); static void PrependPDU(ola::io::IOStack *stack, uint32_t vector, - const ola::acn::CID &cid); + const ola::acn::CID &cid, bool force_length_flag = false); private: ola::acn::CID m_cid; diff --git a/libs/acn/RootSender.cpp b/libs/acn/RootSender.cpp index 009bb30f7e..767c8844c1 100644 --- a/libs/acn/RootSender.cpp +++ b/libs/acn/RootSender.cpp @@ -31,8 +31,8 @@ using ola::acn::CID; * Create a new RootSender * @param cid The CID to send in the Root PDU. */ -RootSender::RootSender(const CID &cid) - : m_root_pdu(0) { +RootSender::RootSender(const CID &cid, bool force_length_flag) + : m_root_pdu(0, force_length_flag) { m_root_pdu.Cid(cid); } diff --git a/libs/acn/RootSender.h b/libs/acn/RootSender.h index 31926ef8f0..a09bbf6199 100644 --- a/libs/acn/RootSender.h +++ b/libs/acn/RootSender.h @@ -32,7 +32,7 @@ namespace acn { class RootSender { public: - explicit RootSender(const ola::acn::CID &cid); + explicit RootSender(const ola::acn::CID &cid, bool force_length_flag = false); ~RootSender() {} // Convenience method to encapsulate & send a single PDU From e57fe51df07cba24e15153bbfabf97026bec094b Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 11 Feb 2020 16:57:48 +0000 Subject: [PATCH 29/86] Add the LLRP Broadcast CID (cherry picked from commit a150d7e263d3e55c3403af9325e37b6ef04644ad) --- include/ola/acn/CID.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/ola/acn/CID.h b/include/ola/acn/CID.h index 3b98d127d7..295b0786c2 100644 --- a/include/ola/acn/CID.h +++ b/include/ola/acn/CID.h @@ -141,6 +141,10 @@ class CID { */ static CID FromString(const std::string &cid); + static CID LLRPBroadcastCID() { + return FromString("FBAD822C-BD0C-4D4C-BDC8-7EABEBC85AFF"); + } + private: class CIDImpl *m_impl; From 4e8eb6de3bc9ee831d74099be1700edd69357634 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 4 Mar 2023 07:37:00 +0000 Subject: [PATCH 30/86] Add some detail on how DMX-TRI error codes are done from its developer (cherry picked from commit fd26efa54d1476fb45a01363ab45dc0bf7ae51ce) --- plugins/usbpro/DmxTriWidget.cpp | 3 +++ plugins/usbpro/DmxTriWidget.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/plugins/usbpro/DmxTriWidget.cpp b/plugins/usbpro/DmxTriWidget.cpp index e6fdefc6a3..d8b98461df 100644 --- a/plugins/usbpro/DmxTriWidget.cpp +++ b/plugins/usbpro/DmxTriWidget.cpp @@ -950,6 +950,9 @@ bool DmxTriWidgetImpl::TriToOlaReturnCode( /** * Convert a DMX-TRI return code to Nack reason code if appropriate + * + * On the widget, the RDM NACK code is currently bitwise or-ed with 0x20 to + * generate the error code */ bool DmxTriWidgetImpl::ReturnCodeToNackReason( uint8_t return_code, diff --git a/plugins/usbpro/DmxTriWidget.h b/plugins/usbpro/DmxTriWidget.h index 6ec0addb9d..1b9f28a346 100644 --- a/plugins/usbpro/DmxTriWidget.h +++ b/plugins/usbpro/DmxTriWidget.h @@ -201,6 +201,8 @@ class DmxTriWidgetImpl: public BaseUsbProWidget, EC_INVALID_IPV6_ADDRESS = 0x32, // this is a guess EC_INVALID_PORT = 0x33 // this is a guess } dmx_tri_error_codes; + // The RDM NACK code is currently bitwise or-ed with 0x20 to generate the + // error code // TODO(Peter): try and test the guessed values static const unsigned int DATA_OFFSET = 2; // first two bytes are CI & RC From af129a6a7bd63a10f0f5c918ca7668971d86392f Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sun, 3 Mar 2024 19:20:15 +0000 Subject: [PATCH 31/86] Update the TCP header for ACN to match the released standards (cherry picked from commit b176ba12607490fc8724cee7e337520dba05566b) --- libs/acn/PreamblePacker.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/acn/PreamblePacker.cpp b/libs/acn/PreamblePacker.cpp index 1803b38e69..520b064f3c 100644 --- a/libs/acn/PreamblePacker.cpp +++ b/libs/acn/PreamblePacker.cpp @@ -47,8 +47,7 @@ const uint8_t PreamblePacker::ACN_HEADER[] = { const unsigned int PreamblePacker::ACN_HEADER_SIZE = sizeof(ACN_HEADER); const uint8_t PreamblePacker::TCP_ACN_HEADER[] = { - 0x00, 0x14, // preamble size - 0x00, 0x00, // post amble size + // No pre or post amble size for TCP 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 From a6badf36f92ba1e9a7511ff240784a25f6d6fb9f Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 8 Jul 2023 21:43:54 +0100 Subject: [PATCH 32/86] Add some more enums (cherry picked from commit 1a027aced39d813eb8c0531ff3040ad3d23ab364) --- include/ola/acn/ACNVectors.h | 81 ++++++++++++++++++++++++++++++++++++ include/ola/e133/E133Enums.h | 39 +++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index 72c050ea91..8734583e81 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -99,6 +99,87 @@ enum LLRPVector { VECTOR_LLRP_RDM_CMD = 3, /**< LLRP RDM Command */ }; +/** + * @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-8, RPT PDU Vector +/** + * @brief Vectors used at the E1.33 RPT layer. + */ +enum RPTVector { + VECTOR_RPT_REQUEST = 1, /**< RPT Request */ + VECTOR_RPT_STATUS = 2, /**< RPT Status */ + VECTOR_RPT_NOTIFICATION = 3, /**< RPT Notification */ +}; + +// Table A-9, RPT Request PDU Vector +/** + * @brief Vectors used at the E1.33 RPT Request layer. + */ +enum RPTRequestVector { + VECTOR_REQUEST_RDM_CMD = 1, /**< RPT Request RDM Command */ +}; + +// Table A-10, RPT Status PDU Vector +/** + * @brief Vectors used at the E1.33 RPT Status layer. + */ +enum RPTStatusVector { + VECTOR_RPT_STATUS_UNKNOWN_RPT_UID = 0x0001, /**< RPT Status Unknown RPT UID */ + VECTOR_RPT_STATUS_RDM_TIMEOUT = 0x0002, /**< RPT Status RDM Timeout */ + VECTOR_RPT_STATUS_RDM_INVALID_RESPONSE = 0x0003, /**< RPT Status RDM Invalid Response */ + VECTOR_RPT_STATUS_UNKNOWN_RDM_UID = 0x0004, /**< RPT Status Unknown RDM UID */ + VECTOR_RPT_STATUS_UNKNOWN_ENDPOINT = 0x0005, /**< RPT Status Unknown Endpoint */ + VECTOR_RPT_STATUS_BROADCAST_COMPLETE = 0x0006, /**< RPT Status Broadcast Complete */ + VECTOR_RPT_STATUS_UNKNOWN_VECTOR = 0x0007, /**< RPT Status Unknown Vector */ + VECTOR_RPT_STATUS_INVALID_MESSAGE = 0x0008, /**< RPT Status Invalid Message */ + VECTOR_RPT_STATUS_INVALID_COMMAND_CLASS = 0x0009, /**< RPT Status Invalid Command Class */ +}; + +// Table A-11, RPT Notification PDU Vector +/** + * @brief Vectors used at the E1.33 RPT Notification layer. + */ +enum RPTNotificationVector { + VECTOR_NOTIFICATION_RDM_CMD = 1, /**< RPT Notification RDM Command */ +}; + +/** + * @brief Vectors used at the E1.33 RDM Command layer. + */ +enum RDMCommandVector { + VECTOR_RDM_CMD_RDM_DATA = 0xCC, /**< E1.33 RDM Command */ +}; + +// 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 */ +}; + /** * @} */ diff --git a/include/ola/e133/E133Enums.h b/include/ola/e133/E133Enums.h index f4c2b4ac06..91369215a5 100644 --- a/include/ola/e133/E133Enums.h +++ b/include/ola/e133/E133Enums.h @@ -39,6 +39,7 @@ enum EndpointMode { ENDPOINT_MODE_OUTPUT = 2, }; +// TODO(Peter): Check that this no longer exists // Table A-9 E1.33 Status Codes enum E133StatusCode { SC_E133_ACK = 0x0000, @@ -53,6 +54,44 @@ enum E133StatusCode { SC_E133_BROADCAST_COMPLETE = 0x0009, }; +// Table A-19 E1.33 Connection Status Codes for Broker Connect +enum E133ConnectStatusCode { + CONNECT_OK = 0x0000, + CONNECT_SCOPE_MISMATCH = 0x0001, + CONNECT_CAPACITY_EXCEEDED = 0x0002, + CONNECT_DUPLICATE_UID = 0x0003, + CONNECT_INVALID_CLIENT_ENTRY = 0x0004, + CONNECT_INVALID_UID = 0x0005, +}; + +// Table A-20 E1.33 Status Codes for Dynamic UID Mapping +enum E133DynamicUIDStatusCode { + DYNAMIC_UID_STATUS_OK = 0x0000, + DYNAMIC_UID_STATUS_INVALID_REQUEST = 0x0001, + DYNAMIC_UID_STATUS_UID_NOT_FOUND = 0x0002, + DYNAMIC_UID_STATUS_DUPLICATE_RID = 0x0003, + DYNAMIC_UID_STATUS_CAPACITY_EXHAUSTED = 0x0004, +}; + +// Table A-22 E1.33 RPT Client Type Codes +enum E133RPTClientTypeCode { + RPT_CLIENT_TYPE_DEVICE = 0x00, + RPT_CLIENT_TYPE_CONTROLLER = 0x01, +}; + +// Table A-24 E1.33 Client Disconnect Reason Codes +enum E133DisconnectStatusCode { + DISCONNECT_SHUTDOWN = 0x0000, + DISCONNECT_CAPACITY_EXHAUSTED = 0x0001, + DISCONNECT_HARDWARE_FAULT = 0x0002, + DISCONNECT_SOFTWARE_FAULT = 0x0003, + DISCONNECT_SOFTWARE_RESET = 0x0004, + DISCONNECT_INCORRECT_SCOPE = 0x0005, + DISCONNECT_RPT_RECONFIGURE = 0x0006, + DISCONNECT_LLRP_RECONFIGURE = 0x0007, + DISCONNECT_USER_RECONFIGURE = 0x0008, +}; + // The max size of an E1.33 Status string. enum { MAX_E133_STATUS_STRING_SIZE = 64 From 45e89f743425c15163fb5995a92e14e43880f486 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 25 Feb 2020 17:36:17 +0000 Subject: [PATCH 33/86] Update some RDM comments (cherry picked from commit 9845e378fd0569c95206368f04af528bc269b412) --- tools/rdm/TestDefinitions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/rdm/TestDefinitions.py b/tools/rdm/TestDefinitions.py index e9adf278b5..a59caf9b30 100644 --- a/tools/rdm/TestDefinitions.py +++ b/tools/rdm/TestDefinitions.py @@ -915,7 +915,7 @@ class GetSubDeviceSupportedParameters(ResponderTestFixture): REQUIRES = ['sub_device_addresses'] PROVIDES = ['sub_device_supported_parameters'] - # E1.37, 2.1 Sub devices are required to support these. + # E1.37-1, 2.1 Sub devices are required to support these. MANDATORY_PIDS = ['SUPPORTED_PARAMETERS', 'DEVICE_INFO', 'SOFTWARE_VERSION_LABEL', @@ -4611,7 +4611,7 @@ class AllSubDevicesGetPresetPlayback(TestMixins.AllSubDevicesGetMixin, PID = 'PRESET_PLAYBACK' -# E1.37 PIDS +# E1.37-1 PIDS # ============================================================================= # IDENTIFY_MODE From 2350a05d2e3280edbf977743c127cb6cc22c120d Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 27 Dec 2023 00:14:27 +0000 Subject: [PATCH 34/86] Add some ConnectStatusCode helpers (cherry picked from commit 7c44c8b9dd58cb99885082f1a15e5e751310b5aa) --- include/ola/e133/E133StatusHelper.h | 5 ++++ tools/e133/E133StatusHelper.cpp | 46 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/include/ola/e133/E133StatusHelper.h b/include/ola/e133/E133StatusHelper.h index cd9680b029..7ca19412df 100644 --- a/include/ola/e133/E133StatusHelper.h +++ b/include/ola/e133/E133StatusHelper.h @@ -30,9 +30,14 @@ namespace e133 { using std::string; using ola::e133::E133StatusCode; +using ola::e133::E133ConnectStatusCode; bool IntToStatusCode(uint16_t input, E133StatusCode *status_code); string StatusCodeToString(E133StatusCode status_code); + +bool IntToConnectStatusCode(uint16_t input, + E133ConnectStatusCode *connect_status_code); +string ConnectStatusCodeToString(E133ConnectStatusCode connect_status_code); } // namespace e133 } // namespace ola #endif // INCLUDE_OLA_E133_E133STATUSHELPER_H_ diff --git a/tools/e133/E133StatusHelper.cpp b/tools/e133/E133StatusHelper.cpp index a87376425a..a1ec71627c 100644 --- a/tools/e133/E133StatusHelper.cpp +++ b/tools/e133/E133StatusHelper.cpp @@ -96,5 +96,51 @@ string StatusCodeToString(E133StatusCode status_code) { } return "Unknown E1.33 Status Code"; } + + +bool IntToConnectStatusCode(uint16_t input, + E133ConnectStatusCode *connect_status_code) { + switch (input) { + case ola::e133::CONNECT_OK: + *connect_status_code = ola::e133::CONNECT_OK; + return true; + case ola::e133::CONNECT_SCOPE_MISMATCH: + *connect_status_code = ola::e133::CONNECT_SCOPE_MISMATCH; + return true; + case ola::e133::CONNECT_CAPACITY_EXCEEDED: + *connect_status_code = ola::e133::CONNECT_CAPACITY_EXCEEDED; + return true; + case ola::e133::CONNECT_DUPLICATE_UID: + *connect_status_code = ola::e133::CONNECT_DUPLICATE_UID; + return true; + case ola::e133::CONNECT_INVALID_CLIENT_ENTRY: + *connect_status_code = ola::e133::CONNECT_INVALID_CLIENT_ENTRY; + return true; + case ola::e133::CONNECT_INVALID_UID: + *connect_status_code = ola::e133::CONNECT_INVALID_UID; + return true; + default: + return false; + } +} + + +string ConnectStatusCodeToString(E133ConnectStatusCode connect_status_code) { + switch (connect_status_code) { + case ola::e133::CONNECT_OK: + return "Ok"; + case ola::e133::CONNECT_SCOPE_MISMATCH: + return "Scope mismatch"; + case ola::e133::CONNECT_CAPACITY_EXCEEDED: + return "Capacity exceeded"; + case ola::e133::CONNECT_DUPLICATE_UID: + return "Duplicate UID"; + case ola::e133::CONNECT_INVALID_CLIENT_ENTRY: + return "Invalid client entry"; + case ola::e133::CONNECT_INVALID_UID: + return "Invalid UID"; + } + return "Unknown E1.33 Connect Status Code"; +} } // namespace e133 } // namespace ola From bcde6b81e9bcf04a147a5dc1c3888ce3b0584e0a Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 8 Mar 2023 13:29:57 +0000 Subject: [PATCH 35/86] Fix a typo in the DeviceManager stuff (cherry picked from commit d01494b9c3ff3bdec37b072a9029cdb36126cc61) --- include/ola/e133/DeviceManager.h | 4 ++-- tools/e133/DeviceManager.cpp | 4 ++-- tools/e133/DeviceManagerImpl.cpp | 4 ++-- tools/e133/DeviceManagerImpl.h | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/ola/e133/DeviceManager.h b/include/ola/e133/DeviceManager.h index 9fada52606..023e8d9f1b 100644 --- a/include/ola/e133/DeviceManager.h +++ b/include/ola/e133/DeviceManager.h @@ -53,7 +53,7 @@ class DeviceManager { * @returns true if the data should be acknowledged, false otherwise. */ typedef ola::Callback3 RDMMesssageCallback; + const string&> RDMMessageCallback; // Run when we acquire designated controller status for a device. typedef ola::Callback1 AcquireDeviceCallback; @@ -66,7 +66,7 @@ class DeviceManager { ~DeviceManager(); // Ownership of the callbacks is transferred. - void SetRDMMessageCallback(RDMMesssageCallback *callback); + void SetRDMMessageCallback(RDMMessageCallback *callback); void SetAcquireDeviceCallback(AcquireDeviceCallback *callback); void SetReleaseDeviceCallback(ReleaseDeviceCallback *callback); diff --git a/tools/e133/DeviceManager.cpp b/tools/e133/DeviceManager.cpp index b91879eddd..3fe1f38874 100644 --- a/tools/e133/DeviceManager.cpp +++ b/tools/e133/DeviceManager.cpp @@ -54,9 +54,9 @@ DeviceManager::~DeviceManager() {} /** * Set the callback to be run when RDMNet data is received from a device. - * @param callback the RDMMesssageCallback to run when data is received. + * @param callback the RDMMessageCallback to run when data is received. */ -void DeviceManager::SetRDMMessageCallback(RDMMesssageCallback *callback) { +void DeviceManager::SetRDMMessageCallback(RDMMessageCallback *callback) { m_impl->SetRDMMessageCallback(callback); } diff --git a/tools/e133/DeviceManagerImpl.cpp b/tools/e133/DeviceManagerImpl.cpp index 86ace1d99c..2e16aa4a94 100644 --- a/tools/e133/DeviceManagerImpl.cpp +++ b/tools/e133/DeviceManagerImpl.cpp @@ -132,9 +132,9 @@ DeviceManagerImpl::~DeviceManagerImpl() { /** * Set the callback to be run when RDMNet data is received from a device. - * @param callback the RDMMesssageCallback to run when data is received. + * @param callback the RDMMessageCallback to run when data is received. */ -void DeviceManagerImpl::SetRDMMessageCallback(RDMMesssageCallback *callback) { +void DeviceManagerImpl::SetRDMMessageCallback(RDMMessageCallback *callback) { m_rdm_callback.reset(callback); } diff --git a/tools/e133/DeviceManagerImpl.h b/tools/e133/DeviceManagerImpl.h index 90bee905ef..5f0c7ad1c4 100644 --- a/tools/e133/DeviceManagerImpl.h +++ b/tools/e133/DeviceManagerImpl.h @@ -70,7 +70,7 @@ class DeviceManagerImpl { * @returns true if the data should be acknowledged, false otherwise. */ typedef ola::Callback3 RDMMesssageCallback; + const string&> RDMMessageCallback; // Run when we acquire designated controller status for a device. typedef ola::Callback1 AcquireDeviceCallback; @@ -83,7 +83,7 @@ class DeviceManagerImpl { ~DeviceManagerImpl(); // Ownership of the callbacks is transferred. - void SetRDMMessageCallback(RDMMesssageCallback *callback); + void SetRDMMessageCallback(RDMMessageCallback *callback); void SetAcquireDeviceCallback(AcquireDeviceCallback *callback); void SetReleaseDeviceCallback(ReleaseDeviceCallback *callback); @@ -98,7 +98,7 @@ class DeviceManagerImpl { DeviceMap; DeviceMap m_device_map; - auto_ptr m_rdm_callback; + auto_ptr m_rdm_callback; auto_ptr m_acquire_device_cb_; auto_ptr m_release_device_cb_; From 505668deb24a91b1cb4ae5cc7205accbe7121158 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 2 Jan 2024 23:12:52 +0000 Subject: [PATCH 36/86] Add some E1.33 helpers (cherry picked from commit eb97fb49c6059622a6da6f152b28ac44d5925832) --- include/ola/e133/E133Helper.h | 36 +++++++++++++++++ include/ola/e133/Makefile.mk | 1 + tools/e133/E133Helper.cpp | 73 +++++++++++++++++++++++++++++++++++ tools/e133/Makefile.mk | 1 + 4 files changed, 111 insertions(+) create mode 100644 include/ola/e133/E133Helper.h create mode 100644 tools/e133/E133Helper.cpp diff --git a/include/ola/e133/E133Helper.h b/include/ola/e133/E133Helper.h new file mode 100644 index 0000000000..325f3aa920 --- /dev/null +++ b/include/ola/e133/E133Helper.h @@ -0,0 +1,36 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * E133Helper.h + * Various misc E1.33 functions. + * Copyright (C) 2024 Peter Newman + */ + +#ifndef INCLUDE_OLA_E133_E133HELPER_H_ +#define INCLUDE_OLA_E133_E133HELPER_H_ + +#include +#include +#include + +namespace ola { +namespace e133 { + +bool IntToRPTClientType(uint8_t input, + ola::e133::E133RPTClientTypeCode *client_type); +std::string RPTClientTypeToString(uint8_t type); +} // namespace e133 +} // namespace ola +#endif // INCLUDE_OLA_E133_E133HELPER_H_ diff --git a/include/ola/e133/Makefile.mk b/include/ola/e133/Makefile.mk index d9f7c11c2f..d8f72c9728 100644 --- a/include/ola/e133/Makefile.mk +++ b/include/ola/e133/Makefile.mk @@ -4,6 +4,7 @@ if INSTALL_E133 olae133include_HEADERS = \ include/ola/e133/DeviceManager.h \ include/ola/e133/E133Enums.h \ + include/ola/e133/E133Helper.h \ include/ola/e133/E133Receiver.h \ include/ola/e133/E133StatusHelper.h \ include/ola/e133/E133URLParser.h \ diff --git a/tools/e133/E133Helper.cpp b/tools/e133/E133Helper.cpp new file mode 100644 index 0000000000..1905a16bce --- /dev/null +++ b/tools/e133/E133Helper.cpp @@ -0,0 +1,73 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * E133Helper.cpp + * Various misc E1.33 functions. + * Copyright (C) 2024 Peter Newman + * + * At some point we may want to localize this file. + */ + +#include +#include +#include +#include "ola/e133/E133Enums.h" +#include "ola/e133/E133Helper.h" +#include "ola/StringUtils.h" + +namespace ola { +namespace e133 { + +using std::ostringstream; +using std::string; +using std::vector; + + +/** + * Verify that the int is a valid E1.33 RPT Client Type. + */ +bool IntToRPTClientType(uint8_t input, + ola::e133::E133RPTClientTypeCode *client_type) { + switch (input) { + case ola::e133::RPT_CLIENT_TYPE_DEVICE: + *client_type = ola::e133::RPT_CLIENT_TYPE_DEVICE; + return true; + case ola::e133::RPT_CLIENT_TYPE_CONTROLLER: + *client_type = ola::e133::RPT_CLIENT_TYPE_CONTROLLER; + return true; + default: + return false; + } +} + + +/** + * Convert a uint8_t representing an RPT client type to a human-readable string. + * @param type the RPT client type value + */ +string RPTClientTypeToString(uint8_t type) { + switch (type) { + case RPT_CLIENT_TYPE_DEVICE: + return "Device"; + case RPT_CLIENT_TYPE_CONTROLLER: + return "Controller"; + default: + ostringstream str; + str << "Unknown, was " << static_cast(type); + return str.str(); + } +} +} // namespace e133 +} // namespace ola diff --git a/tools/e133/Makefile.mk b/tools/e133/Makefile.mk index 6b77f499d3..6b30762779 100644 --- a/tools/e133/Makefile.mk +++ b/tools/e133/Makefile.mk @@ -24,6 +24,7 @@ endif tools_e133_libolae133common_la_SOURCES = \ tools/e133/E133HealthCheckedConnection.cpp \ tools/e133/E133HealthCheckedConnection.h \ + tools/e133/E133Helper.cpp \ tools/e133/E133Receiver.cpp \ tools/e133/E133StatusHelper.cpp \ tools/e133/MessageBuilder.cpp From 557cd58f2f86738bae8d3d2e74010fb06f4631f2 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sun, 10 Mar 2024 21:10:25 +0000 Subject: [PATCH 37/86] Handle some conversion errors (cherry picked from commit 356decf0f7c27ba791592f35051600855652d9fc) --- include/ola/network/AdvancedTCPConnector.h | 2 +- include/ola/network/TCPConnector.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ola/network/AdvancedTCPConnector.h b/include/ola/network/AdvancedTCPConnector.h index fdc57c7b04..2810329486 100644 --- a/include/ola/network/AdvancedTCPConnector.h +++ b/include/ola/network/AdvancedTCPConnector.h @@ -84,7 +84,7 @@ class AdvancedTCPConnector { /** * @brief Return the number of connections tracked by this connector. */ - unsigned int EndpointCount() const { return m_connections.size(); } + unsigned int EndpointCount() const { return static_cast(m_connections.size()); } /** * @brief The state of a connection. diff --git a/include/ola/network/TCPConnector.h b/include/ola/network/TCPConnector.h index 4b74c71f9a..b7d8a92b9a 100644 --- a/include/ola/network/TCPConnector.h +++ b/include/ola/network/TCPConnector.h @@ -98,7 +98,7 @@ class TCPConnector { /** * @brief Return the number of pending connections */ - unsigned int ConnectionsPending() const { return m_connections.size(); } + unsigned int ConnectionsPending() const { return static_cast(m_connections.size()); } /** * @brief Called when the TCP socket connects. From cc02c0f145958b934e75c1ef48d2b8519f0036bf Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 12:34:43 +0000 Subject: [PATCH 38/86] Be more consistent with the representation of enums to match the standard (cherry picked from commit 35e4ed193da7691d5b40255a733ee05232a57d6c) --- include/ola/acn/ACNVectors.h | 94 ++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/include/ola/acn/ACNVectors.h b/include/ola/acn/ACNVectors.h index 8734583e81..b058beb810 100644 --- a/include/ola/acn/ACNVectors.h +++ b/include/ola/acn/ACNVectors.h @@ -43,13 +43,14 @@ namespace acn { * @brief ACN vectors used at the root layer. */ enum RootVector { - VECTOR_ROOT_E131_REV2 = 3, /**< Draft E1.31, used by some old gear. */ - VECTOR_ROOT_E131 = 4, /**< E1.31 (sACN) */ - VECTOR_ROOT_RPT = 5, /**< E1.33 (RPT) */ - VECTOR_ROOT_NULL = 6, /**< NULL (empty) root */ - VECTOR_ROOT_BROKER = 9, /**< E1.33 (Broker) */ - VECTOR_ROOT_LLRP = 0x0A, /**< E1.33 (LLRP) */ - VECTOR_ROOT_EPT = 0x0B, /**< E1.33 (EPT) */ + /** @brief Draft E1.31, used by some old gear. */ + VECTOR_ROOT_E131_REV2 = 0x00000003, + VECTOR_ROOT_E131 = 0x00000004, /**< E1.31 (sACN) */ + VECTOR_ROOT_RPT = 0x00000005, /**< E1.33 (RPT) */ + VECTOR_ROOT_NULL = 0x00000006, /**< NULL (empty) root */ + VECTOR_ROOT_BROKER = 0x00000009, /**< E1.33 (Broker) */ + VECTOR_ROOT_LLRP = 0x0000000A, /**< E1.33 (LLRP) */ + VECTOR_ROOT_EPT = 0x0000000B, /**< E1.33 (EPT) */ }; /** @@ -94,9 +95,9 @@ enum E133ControllerVector { * @brief Vectors used at the E1.33 LLRP layer. */ enum LLRPVector { - VECTOR_LLRP_PROBE_REQUEST = 1, /**< LLRP Probe Request */ - VECTOR_LLRP_PROBE_REPLY = 2, /**< LLRP Probe Reply */ - VECTOR_LLRP_RDM_CMD = 3, /**< LLRP RDM Command */ + VECTOR_LLRP_PROBE_REQUEST = 0x00000001, /**< LLRP Probe Request */ + VECTOR_LLRP_PROBE_REPLY = 0x00000002, /**< LLRP Probe Reply */ + VECTOR_LLRP_RDM_CMD = 0x00000003, /**< LLRP RDM Command */ }; /** @@ -105,17 +106,35 @@ enum LLRPVector { 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 */ + + /** @brief Broker Client Entry Update */ + VECTOR_BROKER_CLIENT_ENTRY_UPDATE = 0x0003, + 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 */ + + /** @brief Broker Connected Client List */ + VECTOR_BROKER_CONNECTED_CLIENT_LIST = 0x0007, + + /** @brief Broker Client Incremental Addition */ + VECTOR_BROKER_CLIENT_ADD = 0x0008, + + /** @brief Broker Client Incremental Deletion */ + VECTOR_BROKER_CLIENT_REMOVE = 0x0009, + + /** @brief Broker Client Entry Change */ + VECTOR_BROKER_CLIENT_ENTRY_CHANGE = 0x000A, + + /** @brief Broker Request Dynamic UID Assignment */ + VECTOR_BROKER_REQUEST_DYNAMIC_UIDS = 0x000B, + + /** @brief Broker Dynamic UID Assignment List */ + VECTOR_BROKER_ASSIGNED_DYNAMIC_UIDS = 0x000C, + + /** @brief Broker Fetch Dynamic UID Assignment List */ + VECTOR_BROKER_FETCH_DYNAMIC_UID_LIST = 0x000D, + VECTOR_BROKER_DISCONNECT = 0x000E, /**< Broker Client Disconnect */ VECTOR_BROKER_NULL = 0x000F, /**< Broker Client Null */ }; @@ -125,9 +144,9 @@ enum BrokerVector { * @brief Vectors used at the E1.33 RPT layer. */ enum RPTVector { - VECTOR_RPT_REQUEST = 1, /**< RPT Request */ - VECTOR_RPT_STATUS = 2, /**< RPT Status */ - VECTOR_RPT_NOTIFICATION = 3, /**< RPT Notification */ + VECTOR_RPT_REQUEST = 0x00000001, /**< RPT Request */ + VECTOR_RPT_STATUS = 0x00000002, /**< RPT Status */ + VECTOR_RPT_NOTIFICATION = 0x00000003, /**< RPT Notification */ }; // Table A-9, RPT Request PDU Vector @@ -135,7 +154,7 @@ enum RPTVector { * @brief Vectors used at the E1.33 RPT Request layer. */ enum RPTRequestVector { - VECTOR_REQUEST_RDM_CMD = 1, /**< RPT Request RDM Command */ + VECTOR_REQUEST_RDM_CMD = 0x01, /**< RPT Request RDM Command */ }; // Table A-10, RPT Status PDU Vector @@ -143,15 +162,30 @@ enum RPTRequestVector { * @brief Vectors used at the E1.33 RPT Status layer. */ enum RPTStatusVector { - VECTOR_RPT_STATUS_UNKNOWN_RPT_UID = 0x0001, /**< RPT Status Unknown RPT UID */ + /** @brief RPT Status Unknown RPT UID */ + VECTOR_RPT_STATUS_UNKNOWN_RPT_UID = 0x0001, + VECTOR_RPT_STATUS_RDM_TIMEOUT = 0x0002, /**< RPT Status RDM Timeout */ - VECTOR_RPT_STATUS_RDM_INVALID_RESPONSE = 0x0003, /**< RPT Status RDM Invalid Response */ - VECTOR_RPT_STATUS_UNKNOWN_RDM_UID = 0x0004, /**< RPT Status Unknown RDM UID */ - VECTOR_RPT_STATUS_UNKNOWN_ENDPOINT = 0x0005, /**< RPT Status Unknown Endpoint */ - VECTOR_RPT_STATUS_BROADCAST_COMPLETE = 0x0006, /**< RPT Status Broadcast Complete */ + + /** @brief RPT Status RDM Invalid Response */ + VECTOR_RPT_STATUS_RDM_INVALID_RESPONSE = 0x0003, + + /** @brief RPT Status Unknown RDM UID */ + VECTOR_RPT_STATUS_UNKNOWN_RDM_UID = 0x0004, + + /** @brief RPT Status Unknown Endpoint */ + VECTOR_RPT_STATUS_UNKNOWN_ENDPOINT = 0x0005, + + /** @brief RPT Status Broadcast Complete */ + VECTOR_RPT_STATUS_BROADCAST_COMPLETE = 0x0006, + VECTOR_RPT_STATUS_UNKNOWN_VECTOR = 0x0007, /**< RPT Status Unknown Vector */ - VECTOR_RPT_STATUS_INVALID_MESSAGE = 0x0008, /**< RPT Status Invalid Message */ - VECTOR_RPT_STATUS_INVALID_COMMAND_CLASS = 0x0009, /**< RPT Status Invalid Command Class */ + + /** @brief RPT Status Invalid Message */ + VECTOR_RPT_STATUS_INVALID_MESSAGE = 0x0008, + + /** @brief RPT Status Invalid Command Class */ + VECTOR_RPT_STATUS_INVALID_COMMAND_CLASS = 0x0009, }; // Table A-11, RPT Notification PDU Vector @@ -159,7 +193,7 @@ enum RPTStatusVector { * @brief Vectors used at the E1.33 RPT Notification layer. */ enum RPTNotificationVector { - VECTOR_NOTIFICATION_RDM_CMD = 1, /**< RPT Notification RDM Command */ + VECTOR_NOTIFICATION_RDM_CMD = 0x01, /**< RPT Notification RDM Command */ }; /** From 9c42ea0041a8bda4443d9bbc81ef9d6b317027a4 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 16:46:14 +0000 Subject: [PATCH 39/86] Fix some licensing of the new E133Helper stuff --- include/ola/e133/E133Helper.h | 20 ++++++++++---------- tools/e133/E133Helper.cpp | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/ola/e133/E133Helper.h b/include/ola/e133/E133Helper.h index 325f3aa920..4fad7608ae 100644 --- a/include/ola/e133/E133Helper.h +++ b/include/ola/e133/E133Helper.h @@ -1,17 +1,17 @@ /* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * 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 library is distributed in the hope that it will be useful, + * 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 - * Lesser General Public License for more details. + * 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 Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * 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. * * E133Helper.h * Various misc E1.33 functions. diff --git a/tools/e133/E133Helper.cpp b/tools/e133/E133Helper.cpp index 1905a16bce..61d0d053e6 100644 --- a/tools/e133/E133Helper.cpp +++ b/tools/e133/E133Helper.cpp @@ -1,17 +1,17 @@ /* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * 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 library is distributed in the hope that it will be useful, + * 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 - * Lesser General Public License for more details. + * 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 Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * 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. * * E133Helper.cpp * Various misc E1.33 functions. From 35f14cc6dc85d26bed0eaa3184b7aec34a63e01f Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 16:52:48 +0000 Subject: [PATCH 40/86] Fix some lint errors --- libs/acn/RootPDU.cpp | 8 ++++++-- libs/acn/RootPDU.h | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libs/acn/RootPDU.cpp b/libs/acn/RootPDU.cpp index cec65ed7bb..e5bf9c0dad 100644 --- a/libs/acn/RootPDU.cpp +++ b/libs/acn/RootPDU.cpp @@ -86,12 +86,16 @@ void RootPDU::SetBlock(const PDUBlock *block) { /* * Prepend a Root Layer flags, length, vector & header */ -void RootPDU::PrependPDU(IOStack *stack, uint32_t vector, const CID &cid, bool force_length_flag) { +void RootPDU::PrependPDU(IOStack *stack, + uint32_t vector, + const CID &cid, + bool force_length_flag) { cid.Write(stack); vector = HostToNetwork(vector); stack->Write(reinterpret_cast(&vector), sizeof(vector)); - PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, force_length_flag); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, + force_length_flag); } } // namespace acn } // namespace ola diff --git a/libs/acn/RootPDU.h b/libs/acn/RootPDU.h index 6d66ebc178..b46d9e601c 100644 --- a/libs/acn/RootPDU.h +++ b/libs/acn/RootPDU.h @@ -59,8 +59,10 @@ class RootPDU: public PDU { const ola::acn::CID &Cid(const ola::acn::CID &cid) { return m_cid = cid; } void SetBlock(const PDUBlock *block); - static void PrependPDU(ola::io::IOStack *stack, uint32_t vector, - const ola::acn::CID &cid, bool force_length_flag = false); + static void PrependPDU(ola::io::IOStack *stack, + uint32_t vector, + const ola::acn::CID &cid, + bool force_length_flag = false); private: ola::acn::CID m_cid; From cc2da4538c2fc5ea2d9f0e9f3291d97d4a93b7a7 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Tue, 4 Feb 2020 15:35:15 +0000 Subject: [PATCH 41/86] Add LLRP Probe Request PDU, fix the length flags bug (cherry picked from commit e9dd3742f9310c0a72bccacfc45cfb9bacf115aa) --- libs/acn/LLRPProbeRequestPDU.cpp | 2 +- libs/acn/LLRPProbeRequestPDUTest.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/acn/LLRPProbeRequestPDU.cpp b/libs/acn/LLRPProbeRequestPDU.cpp index 6fe5378081..ba1623ed3a 100644 --- a/libs/acn/LLRPProbeRequestPDU.cpp +++ b/libs/acn/LLRPProbeRequestPDU.cpp @@ -56,7 +56,7 @@ void LLRPProbeRequestPDU::PrependPDU(ola::io::IOStack *stack, (known_uids.Size() * UID::LENGTH))); uint8_t vector = HostToNetwork(VECTOR_PROBE_REQUEST_DATA); stack->Write(reinterpret_cast(&vector), sizeof(vector)); - PrependFlagsAndLength(stack); + PrependFlagsAndLength(stack, VFLAG_MASK | HFLAG_MASK | DFLAG_MASK, true); } } // namespace acn } // namespace ola diff --git a/libs/acn/LLRPProbeRequestPDUTest.cpp b/libs/acn/LLRPProbeRequestPDUTest.cpp index ca6596991c..6666002b6a 100644 --- a/libs/acn/LLRPProbeRequestPDUTest.cpp +++ b/libs/acn/LLRPProbeRequestPDUTest.cpp @@ -70,7 +70,7 @@ void LLRPProbeRequestPDUTest::testPrepend() { OLA_ASSERT(stack.Read(buffer, length)); const uint8_t expected_data[] = { - 0xf0, 0x23, 1, + 0xf0, 0x00, 0x24, 1, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, From c790863348c2339370d69397cfe9935e65b25032 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 17:03:42 +0000 Subject: [PATCH 42/86] Fix some more lint issues --- include/ola/network/AdvancedTCPConnector.h | 4 +++- include/ola/network/TCPConnector.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/ola/network/AdvancedTCPConnector.h b/include/ola/network/AdvancedTCPConnector.h index 2810329486..c6e3d61f26 100644 --- a/include/ola/network/AdvancedTCPConnector.h +++ b/include/ola/network/AdvancedTCPConnector.h @@ -84,7 +84,9 @@ class AdvancedTCPConnector { /** * @brief Return the number of connections tracked by this connector. */ - unsigned int EndpointCount() const { return static_cast(m_connections.size()); } + unsigned int EndpointCount() const { + return static_cast(m_connections.size()); + } /** * @brief The state of a connection. diff --git a/include/ola/network/TCPConnector.h b/include/ola/network/TCPConnector.h index b7d8a92b9a..866392b1a2 100644 --- a/include/ola/network/TCPConnector.h +++ b/include/ola/network/TCPConnector.h @@ -98,7 +98,9 @@ class TCPConnector { /** * @brief Return the number of pending connections */ - unsigned int ConnectionsPending() const { return static_cast(m_connections.size()); } + unsigned int ConnectionsPending() const { + return static_cast(m_connections.size()); + } /** * @brief Called when the TCP socket connects. From a20ce88cb87b4159df852532f1271d004926f55e Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 17:11:48 +0000 Subject: [PATCH 43/86] Update the TCP header for ACN to match the released standards in TCPTransport (cherry picked from commit 33ea03fd6956a631b342dbe0ace8d17584f21e66) --- libs/acn/TCPTransport.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/acn/TCPTransport.cpp b/libs/acn/TCPTransport.cpp index 5890f0c0ff..4060df25fa 100644 --- a/libs/acn/TCPTransport.cpp +++ b/libs/acn/TCPTransport.cpp @@ -31,8 +31,7 @@ namespace ola { namespace acn { const uint8_t ACN_HEADER[] = { - 0x00, 0x14, // preamble size - 0x00, 0x00, // post amble size + // No pre or post amble size for TCP 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 From 274e2c7daab6b9b4b4900a93f13aaba4a3aea288 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 17:19:34 +0000 Subject: [PATCH 44/86] Fix another cpplint issue --- libs/acn/RootSender.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/acn/RootSender.h b/libs/acn/RootSender.h index a09bbf6199..8f6f237687 100644 --- a/libs/acn/RootSender.h +++ b/libs/acn/RootSender.h @@ -32,7 +32,8 @@ namespace acn { class RootSender { public: - explicit RootSender(const ola::acn::CID &cid, bool force_length_flag = false); + explicit RootSender(const ola::acn::CID &cid, + bool force_length_flag = false); ~RootSender() {} // Convenience method to encapsulate & send a single PDU From 05b0dbdbac38ea66672b5981ffd0aff8c950c2f6 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 16 Mar 2024 18:19:46 +0000 Subject: [PATCH 45/86] 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 46/86] 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 47/86] 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 48/86] 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 49/86] 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 50/86] 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 51/86] 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 52/86] 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 53/86] 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 54/86] 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 55/86] 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 56/86] 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 57/86] 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 58/86] 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 59/86] 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 60/86] 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 61/86] 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 62/86] 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 63/86] 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 64/86] 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 65/86] 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 66/86] 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 67/86] 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 68/86] 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 69/86] 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 70/86] 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 71/86] 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 72/86] 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 73/86] 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 74/86] 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 75/86] 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 76/86] 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); + } } From 8d94b7c6801f56cd618faecefd6aff17e9bfa062 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 28 Mar 2024 16:28:47 +0000 Subject: [PATCH 77/86] Fix a comment typo --- common/rdm/VariableFieldSizeCalculator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/rdm/VariableFieldSizeCalculator.cpp b/common/rdm/VariableFieldSizeCalculator.cpp index b054a38589..cf904b12de 100644 --- a/common/rdm/VariableFieldSizeCalculator.cpp +++ b/common/rdm/VariableFieldSizeCalculator.cpp @@ -69,7 +69,7 @@ VariableFieldSizeCalculator::calculator_state return data_size > m_fixed_size_sum ? TOO_LARGE : FIXED_SIZE; // we know there is only one, now we need to work out the number of - // repeatitions or length if it's a string + // repetitions or length if it's a string unsigned int bytes_remaining = data_size - m_fixed_size_sum; if (variable_string_field_count) { // variable string From b64b89d142931cd41cb0696cccade2e4cece8553 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 26 Feb 2020 08:43:43 +0000 Subject: [PATCH 78/86] Add initial negative E1.33/E1.37-7 tests. Need to add categories still (cherry picked from commit 2aeaac8f33f3e75eb55e02a2aaa862c899474519) --- tools/rdm/TestDefinitions.py | 770 +++++++++++++++++++++++++++++++++++ 1 file changed, 770 insertions(+) diff --git a/tools/rdm/TestDefinitions.py b/tools/rdm/TestDefinitions.py index a59caf9b30..1b3a8bac27 100644 --- a/tools/rdm/TestDefinitions.py +++ b/tools/rdm/TestDefinitions.py @@ -7923,6 +7923,776 @@ class SetInterfaceHardwareAddressType1WithData( PID = 'INTERFACE_HARDWARE_ADDRESS_TYPE1' +# E1.33/E1.37-7 PIDS +# ============================================================================= + +class AllSubDevicesGetSearchDomain(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get SEARCH_DOMAIN to ALL_SUB_DEVICES.""" + PID = 'SEARCH_DOMAIN' + + +# class GetSearchDomain(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'SEARCH_DOMAIN' +# TODO(peter): Test get + + +class GetSearchDomainWithData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET SEARCH_DOMAIN with data.""" + PID = 'SEARCH_DOMAIN' + + +# class SetSearchDomain(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'SEARCH_DOMAIN' +# TODO(peter): Test set + + +class SetSearchDomainWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set SEARCH_DOMAIN command with no data.""" + PID = 'SEARCH_DOMAIN' + + +class SetSearchDomainWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET SEARCH_DOMAIN command with extra data.""" + PID = 'SEARCH_DOMAIN' + + +class AllSubDevicesGetBrokerStatus(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get BROKER_STATUS to ALL_SUB_DEVICES.""" + PID = 'BROKER_STATUS' + + +# class GetBrokerStatus(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'BROKER_STATUS' +# TODO(peter): Test get + + +class GetBrokerStatusWithData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET BROKER_STATUS with data.""" + PID = 'BROKER_STATUS' + + +# class SetBrokerStatus(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'BROKER_STATUS' +# TODO(peter): Test set + + +class SetBrokerStatusWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set BROKER_STATUS command with no data.""" + PID = 'BROKER_STATUS' + + +class SetBrokerStatusWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET BROKER_STATUS command with extra data.""" + PID = 'BROKER_STATUS' + + +class AllSubDevicesGetEndpointMode(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_MODE to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_MODE' + DATA = [0x0001] + + +# class GetEndpointMode(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_MODE' +# TODO(peter): Test get + + +class GetZeroEndpointMode(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET ENDPOINT_MODE for endpoint id 0.""" + PID = 'ENDPOINT_MODE' + + +class GetEndpointModeWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_MODE with no argument given.""" + PID = 'ENDPOINT_MODE' + + +class GetEndpointModeWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_MODE with more than 2 bytes of data.""" + PID = 'ENDPOINT_MODE' + + +# class SetEndpointMode(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_MODE' +# TODO(peter): Test set + + +# class SetZeroEndpointMode(TestMixins.SetZero, +# OptionalParameterTestFixture): +# """SET ENDPOINT_MODE for endpoint id 0.""" +# PID = 'ENDPOINT_MODE' +# TODO(peter): Test set zero + + +class SetEndpointModeWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set ENDPOINT_MODE command with no data.""" + PID = 'ENDPOINT_MODE' + + +class SetEndpointModeWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET ENDPOINT_MODE command with extra data.""" + PID = 'ENDPOINT_MODE' + DATA = 'foobar' + + +class AllSubDevicesGetEndpointLabel(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_LABEL to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_LABEL' + DATA = [0x0001] + + +# class GetEndpointLabel(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_LABEL' +# TODO(peter): Test get + + +class GetZeroEndpointLabel(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET ENDPOINT_LABEL for endpoint id 0.""" + PID = 'ENDPOINT_LABEL' + + +class GetEndpointLabelWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_LABEL with no argument given.""" + PID = 'ENDPOINT_LABEL' + + +class GetEndpointLabelWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_LABEL with more than 2 bytes of data.""" + PID = 'ENDPOINT_LABEL' + + +# class SetEndpointLabel(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_LABEL' +# TODO(peter): Test set + + +# class SetZeroEndpointLabel(TestMixins.SetZero, +# OptionalParameterTestFixture): +# """SET ENDPOINT_LABEL for endpoint id 0.""" +# PID = 'ENDPOINT_LABEL' +# TODO(peter): Test set zero + + +class SetEndpointLabelWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set ENDPOINT_LABEL command with no data.""" + PID = 'ENDPOINT_LABEL' + + +class SetEndpointLabelWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET ENDPOINT_LABEL command with extra data.""" + PID = 'ENDPOINT_LABEL' + + +class AllSubDevicesGetEndpointTiming(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_TIMING to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_TIMING' + DATA = [0x0001] + + +# class GetEndpointTiming(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_TIMING' +# TODO(peter): Test get + + +class GetZeroEndpointTiming(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TIMING for endpoint id 0.""" + PID = 'ENDPOINT_TIMING' + + +class GetEndpointTimingWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TIMING with no argument given.""" + PID = 'ENDPOINT_TIMING' + + +class GetEndpointTimingWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TIMING with more than 2 bytes of data.""" + PID = 'ENDPOINT_TIMING' + + +# class SetEndpointTiming(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_TIMING' +# TODO(peter): Test set + + +# class SetZeroEndpointTiming(TestMixins.SetZero, +# OptionalParameterTestFixture): +# """SET ENDPOINT_TIMING for endpoint id 0.""" +# PID = 'ENDPOINT_TIMING' +# TODO(peter): Test set zero + + +class SetEndpointTimingWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set ENDPOINT_TIMING command with no data.""" + PID = 'ENDPOINT_TIMING' + + +class SetEndpointTimingWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET ENDPOINT_TIMING command with extra data.""" + PID = 'ENDPOINT_TIMING' + DATA = 'foobar' + + +class AllSubDevicesGetEndpointTimingDescription( + TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_TIMING_DESCRIPTION to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_TIMING_DESCRIPTION' + DATA = [0x01] + + +# class GetEndpointTimingDescription(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_TIMING_DESCRIPTION' +# TODO(peter): Test get + + +class GetZeroEndpointTimingDescription(TestMixins.GetZeroUInt8Mixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TIMING_DESCRIPTION for timing setting 0.""" + PID = 'ENDPOINT_TIMING_DESCRIPTION' + + +class GetEndpointTimingDescriptionWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TIMING_DESCRIPTION with no argument given.""" + PID = 'ENDPOINT_TIMING_DESCRIPTION' + + +class GetEndpointTimingDescriptionWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TIMING_DESCRIPTION with more than 1 byte of data.""" + PID = 'ENDPOINT_TIMING_DESCRIPTION' + + +class SetEndpointTimingDescription(TestMixins.UnsupportedSetMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_TIMING_DESCRIPTION.""" + PID = 'ENDPOINT_TIMING_DESCRIPTION' + + +class SetEndpointTimingDescriptionWithData( + TestMixins.UnsupportedSetWithDataMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_TIMING_DESCRIPTION with data.""" + PID = 'ENDPOINT_TIMING_DESCRIPTION' + + +class AllSubDevicesGetEndpointResponders(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_RESPONDERS to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_RESPONDERS' + DATA = [0x0001] + + +# class GetEndpointResponders(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_RESPONDERS' +# TODO(peter): Test get + + +class GetZeroEndpointResponders(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET ENDPOINT_RESPONDERS for endpoint id 0.""" + PID = 'ENDPOINT_RESPONDERS' + + +class GetEndpointRespondersWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_RESPONDERS with no argument given.""" + PID = 'ENDPOINT_RESPONDERS' + + +class GetEndpointRespondersWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_RESPONDERS with more than 2 bytes of data.""" + PID = 'ENDPOINT_RESPONDERS' + + +class SetEndpointResponders(TestMixins.UnsupportedSetMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_RESPONDERS.""" + PID = 'ENDPOINT_RESPONDERS' + + +class SetEndpointRespondersWithData(TestMixins.UnsupportedSetWithDataMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_RESPONDERS with data.""" + PID = 'ENDPOINT_RESPONDERS' + + +class AllSubDevicesGetEndpointResponderListChange( + TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_RESPONDER_LIST_CHANGE to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' + DATA = [0x0001] + + +# class GetEndpointResponderListChange(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' +# TODO(peter): Test get + + +class GetZeroEndpointResponderListChange(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET ENDPOINT_RESPONDER_LIST_CHANGE for endpoint id 0.""" + PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' + + +class GetEndpointResponderListChangeWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_RESPONDER_LIST_CHANGE with no argument given.""" + PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' + + +class GetEndpointResponderListChangeWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_RESPONDER_LIST_CHANGE with more than 2 bytes of data.""" + PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' + + +class SetEndpointResponderListChange(TestMixins.UnsupportedSetMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_RESPONDER_LIST_CHANGE.""" + PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' + + +class SetEndpointResponderListChangeWithData( + TestMixins.UnsupportedSetWithDataMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_RESPONDER_LIST_CHANGE with data.""" + PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' + + +class AllSubDevicesGetEndpointList(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_LIST to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_LIST' + + +# class GetEndpointList(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_LIST' +# TODO(peter): Test get + + +class GetEndpointListWithData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_LIST with data.""" + PID = 'ENDPOINT_LIST' + + +class SetEndpointList(TestMixins.UnsupportedSetMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_LIST.""" + PID = 'ENDPOINT_LIST' + + +class SetEndpointListWithData(TestMixins.UnsupportedSetWithDataMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_LIST with data.""" + PID = 'ENDPOINT_LIST' + + +class AllSubDevicesGetEndpointListChange(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_LIST_CHANGE to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_LIST_CHANGE' + + +# class GetEndpointListChange(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_LIST_CHANGE' +# TODO(peter): Test get + + +class GetEndpointListChangeWithData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_LIST_CHANGE with data.""" + PID = 'ENDPOINT_LIST_CHANGE' + + +class SetEndpointListChange(TestMixins.UnsupportedSetMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_LIST_CHANGE.""" + PID = 'ENDPOINT_LIST_CHANGE' + + +class SetEndpointListChangeWithData(TestMixins.UnsupportedSetWithDataMixin, + OptionalParameterTestFixture): + """Attempt to SET ENDPOINT_LIST_CHANGE with data.""" + PID = 'ENDPOINT_LIST_CHANGE' + + +class AllSubDevicesGetEndpointToUniverse(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get ENDPOINT_TO_UNIVERSE to ALL_SUB_DEVICES.""" + PID = 'ENDPOINT_TO_UNIVERSE' + DATA = [0x0001] + + +# class GetEndpointToUniverse(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_TO_UNIVERSE' +# TODO(peter): Test get + + +class GetZeroEndpointToUniverse(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TO_UNIVERSE for endpoint id 0.""" + PID = 'ENDPOINT_TO_UNIVERSE' + + +class GetEndpointToUniverseWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TO_UNIVERSE with no argument given.""" + PID = 'ENDPOINT_TO_UNIVERSE' + + +class GetEndpointToUniverseWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET ENDPOINT_TO_UNIVERSE with more than 2 bytes of data.""" + PID = 'ENDPOINT_TO_UNIVERSE' + + +# class SetEndpointToUniverse(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'ENDPOINT_TO_UNIVERSE' +# TODO(peter): Test set + + +# class SetZeroEndpointToUniverse(TestMixins.SetZero, +# OptionalParameterTestFixture): +# """SET ENDPOINT_TO_UNIVERSE for endpoint id 0.""" +# PID = 'ENDPOINT_TO_UNIVERSE' +# TODO(peter): Test set zero + + +class SetEndpointToUniverseWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set ENDPOINT_TO_UNIVERSE command with no data.""" + PID = 'ENDPOINT_TO_UNIVERSE' + + +class SetEndpointToUniverseWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET ENDPOINT_TO_UNIVERSE command with extra data.""" + PID = 'ENDPOINT_TO_UNIVERSE' + DATA = 'foobar' + + +class AllSubDevicesGetRdmTrafficEnable(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get RDM_TRAFFIC_ENABLE to ALL_SUB_DEVICES.""" + PID = 'RDM_TRAFFIC_ENABLE' + DATA = [0x0001] + + +# class GetRdmTrafficEnable(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'RDM_TRAFFIC_ENABLE' +# TODO(peter): Test get + + +class GetZeroRdmTrafficEnable(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET RDM_TRAFFIC_ENABLE for endpoint id 0.""" + PID = 'RDM_TRAFFIC_ENABLE' + + +class GetRdmTrafficEnableWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET RDM_TRAFFIC_ENABLE with no argument given.""" + PID = 'RDM_TRAFFIC_ENABLE' + + +class GetRdmTrafficEnableWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET RDM_TRAFFIC_ENABLE with more than 2 bytes of data.""" + PID = 'RDM_TRAFFIC_ENABLE' + + +# class SetRdmTrafficEnable(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'RDM_TRAFFIC_ENABLE' +# TODO(peter): Test set + + +# class SetZeroRdmTrafficEnable(TestMixins.SetZero, +# OptionalParameterTestFixture): +# """SET RDM_TRAFFIC_ENABLE for endpoint id 0.""" +# PID = 'RDM_TRAFFIC_ENABLE' +# TODO(peter): Test set zero + + +class SetRdmTrafficEnableWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set RDM_TRAFFIC_ENABLE command with no data.""" + PID = 'RDM_TRAFFIC_ENABLE' + + +class SetRdmTrafficEnableWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET RDM_TRAFFIC_ENABLE command with extra data.""" + PID = 'RDM_TRAFFIC_ENABLE' + DATA = 'foobar' + + +class AllSubDevicesGetDiscoveryState(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get DISCOVERY_STATE to ALL_SUB_DEVICES.""" + PID = 'DISCOVERY_STATE' + DATA = [0x0001] + + +# class GetDiscoveryState(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'DISCOVERY_STATE' +# TODO(peter): Test get + + +class GetZeroDiscoveryState(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET DISCOVERY_STATE for endpoint id 0.""" + PID = 'DISCOVERY_STATE' + + +class GetDiscoveryStateWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET DISCOVERY_STATE with no argument given.""" + PID = 'DISCOVERY_STATE' + + +class GetDiscoveryStateWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET DISCOVERY_STATE with more than 2 bytes of data.""" + PID = 'DISCOVERY_STATE' + + +# class SetDiscoveryState(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'DISCOVERY_STATE' +# TODO(peter): Test set + + +# class SetZeroDiscoveryState(TestMixins.SetZero, +# OptionalParameterTestFixture): +# """SET DISCOVERY_STATE for endpoint id 0.""" +# PID = 'DISCOVERY_STATE' +# TODO(peter): Test set zero + + +class SetDiscoveryStateWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set DISCOVERY_STATE command with no data.""" + PID = 'DISCOVERY_STATE' + + +class SetDiscoveryStateWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET DISCOVERY_STATE command with extra data.""" + PID = 'DISCOVERY_STATE' + DATA = 'foobar' + + +class AllSubDevicesGetBackgroundDiscovery(TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get BACKGROUND_DISCOVERY to ALL_SUB_DEVICES.""" + PID = 'BACKGROUND_DISCOVERY' + DATA = [0x0001] + + +# class GetBackgroundDiscovery(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'BACKGROUND_DISCOVERY' +# TODO(peter): Test get + + +class GetZeroBackgroundDiscovery(TestMixins.GetZeroUInt16Mixin, + OptionalParameterTestFixture): + """GET BACKGROUND_DISCOVERY for endpoint id 0.""" + PID = 'BACKGROUND_DISCOVERY' + + +class GetBackgroundDiscoveryWithNoData(TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET BACKGROUND_DISCOVERY with no argument given.""" + PID = 'BACKGROUND_DISCOVERY' + + +class GetBackgroundDiscoveryWithExtraData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET BACKGROUND_DISCOVERY with more than 2 bytes of data.""" + PID = 'BACKGROUND_DISCOVERY' + + +# class SetBackgroundDiscovery(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'BACKGROUND_DISCOVERY' +# TODO(peter): Test set + + +# class SetZeroBackgroundDiscovery(TestMixins.SetZero, +# OptionalParameterTestFixture): +# """SET BACKGROUND_DISCOVERY for endpoint id 0.""" +# PID = 'BACKGROUND_DISCOVERY' +# TODO(peter): Test set zero + + +class SetBackgroundDiscoveryWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set BACKGROUND_DISCOVERY command with no data.""" + PID = 'BACKGROUND_DISCOVERY' + + +class SetBackgroundDiscoveryWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET BACKGROUND_DISCOVERY command with extra data.""" + PID = 'BACKGROUND_DISCOVERY' + DATA = 'foobar' + + +class AllSubDevicesGetBackgroundQueuedStatusPolicy( + TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get BACKGROUND_QUEUED_STATUS_POLICY to ALL_SUB_DEVICES.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY' + + +# class GetBackgroundQueuedStatusPolicy(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'BACKGROUND_QUEUED_STATUS_POLICY' +# TODO(peter): Test get + + +class GetBackgroundQueuedStatusPolicyWithData(TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET BACKGROUND_QUEUED_STATUS_POLICY with data.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY' + + +# class SetBackgroundQueuedStatusPolicy(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'BACKGROUND_QUEUED_STATUS_POLICY' +# TODO(peter): Test set + + +class SetBackgroundQueuedStatusPolicyWithNoData(TestMixins.SetWithNoDataMixin, + OptionalParameterTestFixture): + """Set BACKGROUND_QUEUED_STATUS_POLICY command with no data.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY' + + +class SetBackgroundQueuedStatusPolicyWithExtraData(TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): + """Send a SET BACKGROUND_QUEUED_STATUS_POLICY command with extra data.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY' + + +class AllSubDevicesGetBackgroundQueuedStatusPolicyDescription( + TestMixins.AllSubDevicesGetMixin, + OptionalParameterTestFixture): + """Send a get BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION to ALL_SUB_DEVICES.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' + DATA = [0x00] + + +# class GetBackgroundQueuedStatusPolicyDescription(TestMixins., +# OptionalParameterTestFixture): +# CATEGORY = TestCategory. +# PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' +# TODO(peter): Test get + + +class GetBackgroundQueuedStatusPolicyDescriptionWithNoData( + TestMixins.GetWithNoDataMixin, + OptionalParameterTestFixture): + """GET BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION with no argument given.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' + + +class GetBackgroundQueuedStatusPolicyDescriptionWithExtraData( + TestMixins.GetWithDataMixin, + OptionalParameterTestFixture): + """GET BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION with more than 1 byte of data.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' + + +class SetBackgroundQueuedStatusPolicyDescription(TestMixins.UnsupportedSetMixin, + OptionalParameterTestFixture): + """Attempt to SET BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' + + +class SetBackgroundQueuedStatusPolicyDescriptionWithData( + TestMixins.UnsupportedSetWithDataMixin, + OptionalParameterTestFixture): + """Attempt to SET BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION with data.""" + PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' + + # Cross check the control fields with various other properties # ----------------------------------------------------------------------------- class SubDeviceControlField(TestFixture): From 8fdae01987d10fbd1a837c368fb13e21c50288d5 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 26 Feb 2020 11:48:27 +0000 Subject: [PATCH 79/86] Add the ability to override the expected NACK for GetZeroMixin (cherry picked from commit 68703616d688d41d0f0a6d43e048aa5b806051c7) --- tools/rdm/TestMixins.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/rdm/TestMixins.py b/tools/rdm/TestMixins.py index 66e54ae2b9..e4866fe15d 100644 --- a/tools/rdm/TestMixins.py +++ b/tools/rdm/TestMixins.py @@ -1025,16 +1025,27 @@ def ResetState(self): class GetZeroMixin(ResponderTestFixture): - """Send a get to index 0, expect NR_DATA_OUT_OF_RANGE""" + """Send a get to index 0, normally expect NR_DATA_OUT_OF_RANGE + + If OVERRIDE_NACKS is non-empty, this overrides NR_DATA_OUT_OF_RANGE and adds + a custom NackGetResult to the list of allowed results for each entry. + """ CATEGORY = TestCategory.ERROR_CONDITIONS DATA = None + OVERRIDE_NACKS = [] def Test(self): if self.DATA is None: self.SetBroken('No DATA given for %s' % self.__class__.__name__) return - self.AddIfGetSupported(self.NackGetResult(RDMNack.NR_DATA_OUT_OF_RANGE)) + results = [] + if self.OVERRIDE_NACKS: + for nack in self.OVERRIDE_NACKS: + results.append(self.NackGetResult(nack)) + else: + results.append(self.NackGetResult(RDMNack.NR_DATA_OUT_OF_RANGE)) + self.AddIfGetSupported(results) self.SendRawGet(ROOT_DEVICE, self.pid, self.DATA) From 43d6450159ea1d82442de628ef9a1e3fd014f290 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Wed, 26 Feb 2020 11:48:54 +0000 Subject: [PATCH 80/86] Correct the expected NACK for some endpoint number checks (cherry picked from commit f67491fa6b7a6403788f1bec94e8c03c4d40637d) --- tools/rdm/TestDefinitions.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/rdm/TestDefinitions.py b/tools/rdm/TestDefinitions.py index 1b3a8bac27..696d0d05b1 100644 --- a/tools/rdm/TestDefinitions.py +++ b/tools/rdm/TestDefinitions.py @@ -8020,6 +8020,7 @@ class GetZeroEndpointMode(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET ENDPOINT_MODE for endpoint id 0.""" PID = 'ENDPOINT_MODE' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetEndpointModeWithNoData(TestMixins.GetWithNoDataMixin, @@ -8079,6 +8080,7 @@ class GetZeroEndpointLabel(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET ENDPOINT_LABEL for endpoint id 0.""" PID = 'ENDPOINT_LABEL' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetEndpointLabelWithNoData(TestMixins.GetWithNoDataMixin, @@ -8137,6 +8139,7 @@ class GetZeroEndpointTiming(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET ENDPOINT_TIMING for endpoint id 0.""" PID = 'ENDPOINT_TIMING' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetEndpointTimingWithNoData(TestMixins.GetWithNoDataMixin, @@ -8242,6 +8245,7 @@ class GetZeroEndpointResponders(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET ENDPOINT_RESPONDERS for endpoint id 0.""" PID = 'ENDPOINT_RESPONDERS' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetEndpointRespondersWithNoData(TestMixins.GetWithNoDataMixin, @@ -8287,6 +8291,7 @@ class GetZeroEndpointResponderListChange(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET ENDPOINT_RESPONDER_LIST_CHANGE for endpoint id 0.""" PID = 'ENDPOINT_RESPONDER_LIST_CHANGE' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetEndpointResponderListChangeWithNoData(TestMixins.GetWithNoDataMixin, @@ -8394,6 +8399,7 @@ class GetZeroEndpointToUniverse(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET ENDPOINT_TO_UNIVERSE for endpoint id 0.""" PID = 'ENDPOINT_TO_UNIVERSE' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetEndpointToUniverseWithNoData(TestMixins.GetWithNoDataMixin, @@ -8453,6 +8459,7 @@ class GetZeroRdmTrafficEnable(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET RDM_TRAFFIC_ENABLE for endpoint id 0.""" PID = 'RDM_TRAFFIC_ENABLE' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetRdmTrafficEnableWithNoData(TestMixins.GetWithNoDataMixin, @@ -8512,6 +8519,7 @@ class GetZeroDiscoveryState(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET DISCOVERY_STATE for endpoint id 0.""" PID = 'DISCOVERY_STATE' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetDiscoveryStateWithNoData(TestMixins.GetWithNoDataMixin, @@ -8571,6 +8579,7 @@ class GetZeroBackgroundDiscovery(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET BACKGROUND_DISCOVERY for endpoint id 0.""" PID = 'BACKGROUND_DISCOVERY' + OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] class GetBackgroundDiscoveryWithNoData(TestMixins.GetWithNoDataMixin, From ca14c3232fd5aed863ff4e3b5c9211b3a55776e8 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Sat, 4 Mar 2023 08:16:44 +0000 Subject: [PATCH 81/86] Improve some size calculations, only output SetWithNoData when actually required and improve how and when we set the DATA variable (cherry picked from commit 9d60884097e6ae5cedd05126a82f2fe382ae6c6e) --- tools/rdm/list_rdm_tests.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tools/rdm/list_rdm_tests.py b/tools/rdm/list_rdm_tests.py index 099594d5c7..1fd8771cdf 100755 --- a/tools/rdm/list_rdm_tests.py +++ b/tools/rdm/list_rdm_tests.py @@ -154,10 +154,14 @@ def GetWithExtraData(names, pid, pid_test_base_name, get_size): dummy_data = GenerateDummyData(get_size) if dummy_data is None: print((" #DATA = b'foo' # TODO(%s): Specify extra data if this isn't " - "enough") % (getpass.getuser())) + "enough. Ensure the first %d bytes are sane/valid.") % (getpass.getuser(), get_size)) elif dummy_data != 'foo': - # Doesn't match default - print(" DATA = b'%s'" % (dummy_data)) + # Doesn't match default, explicitly set value + print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), get_size)) + else: + print((" #DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), get_size)) print('') print('') @@ -273,10 +277,14 @@ def SetWithExtraData(names, pid, pid_test_base_name, set_size): dummy_data = GenerateDummyData(set_size) if dummy_data is None: print((" #DATA = b'foo' # TODO(%s): Specify extra data if this isn't " - "enough") % (getpass.getuser())) + "enough. Ensure the first %d bytes are sane/valid.") % (getpass.getuser(), set_size)) elif dummy_data != 'foo': - # Doesn't match default - print(" DATA = b'%s'" % (dummy_data)) + # Doesn't match default, explicitly set value + print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), set_size)) + else: + print((" #DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), set_size)) print('') print('') @@ -343,8 +351,11 @@ def main(): get_size = 0 if ((pid.RequestSupported(PidStore.RDM_GET)) and (pid.GetRequest(PidStore.RDM_GET).HasAtoms())): - get_size = pid.GetRequest(PidStore.RDM_GET).GetAtoms()[0].size - # print('# Get requires %d bytes' % (get_size)) + for atom in pid.GetRequest(PidStore.RDM_GET).GetAtoms(): + get_size += atom.size + #TODO(Peter): Should we just print this total all the time? + if get_size != pid.GetRequest(PidStore.RDM_GET).GetAtoms()[0].size: + print('# Get requires %d bytes' % (get_size)) AllSubDevicesGet(names, pid, pid_test_base_name, get_size) @@ -382,7 +393,8 @@ def main(): first_atom.ValidateRawValueInRange(1))): SetZero(names, pid, pid_test_base_name, first_atom) - SetWithNoData(names, pid, pid_test_base_name) + if set_size > 0: + SetWithNoData(names, pid, pid_test_base_name) SetWithExtraData(names, pid, pid_test_base_name, set_size) else: From b48ec1427e121357e0889441d6c084e3170677a2 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 28 Mar 2024 22:30:00 +0000 Subject: [PATCH 82/86] Apply equivalent Python 3 fixes to old code --- tools/rdm/TestDefinitions.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/rdm/TestDefinitions.py b/tools/rdm/TestDefinitions.py index 696d0d05b1..d0ecf2635d 100644 --- a/tools/rdm/TestDefinitions.py +++ b/tools/rdm/TestDefinitions.py @@ -8059,7 +8059,7 @@ class SetEndpointModeWithExtraData(TestMixins.SetWithDataMixin, OptionalParameterTestFixture): """Send a SET ENDPOINT_MODE command with extra data.""" PID = 'ENDPOINT_MODE' - DATA = 'foobar' + DATA = b'foobar' class AllSubDevicesGetEndpointLabel(TestMixins.AllSubDevicesGetMixin, @@ -8178,7 +8178,7 @@ class SetEndpointTimingWithExtraData(TestMixins.SetWithDataMixin, OptionalParameterTestFixture): """Send a SET ENDPOINT_TIMING command with extra data.""" PID = 'ENDPOINT_TIMING' - DATA = 'foobar' + DATA = b'foobar' class AllSubDevicesGetEndpointTimingDescription( @@ -8438,7 +8438,7 @@ class SetEndpointToUniverseWithExtraData(TestMixins.SetWithDataMixin, OptionalParameterTestFixture): """Send a SET ENDPOINT_TO_UNIVERSE command with extra data.""" PID = 'ENDPOINT_TO_UNIVERSE' - DATA = 'foobar' + DATA = b'foobar' class AllSubDevicesGetRdmTrafficEnable(TestMixins.AllSubDevicesGetMixin, @@ -8498,7 +8498,7 @@ class SetRdmTrafficEnableWithExtraData(TestMixins.SetWithDataMixin, OptionalParameterTestFixture): """Send a SET RDM_TRAFFIC_ENABLE command with extra data.""" PID = 'RDM_TRAFFIC_ENABLE' - DATA = 'foobar' + DATA = b'foobar' class AllSubDevicesGetDiscoveryState(TestMixins.AllSubDevicesGetMixin, @@ -8558,7 +8558,7 @@ class SetDiscoveryStateWithExtraData(TestMixins.SetWithDataMixin, OptionalParameterTestFixture): """Send a SET DISCOVERY_STATE command with extra data.""" PID = 'DISCOVERY_STATE' - DATA = 'foobar' + DATA = b'foobar' class AllSubDevicesGetBackgroundDiscovery(TestMixins.AllSubDevicesGetMixin, @@ -8618,7 +8618,7 @@ class SetBackgroundDiscoveryWithExtraData(TestMixins.SetWithDataMixin, OptionalParameterTestFixture): """Send a SET BACKGROUND_DISCOVERY command with extra data.""" PID = 'BACKGROUND_DISCOVERY' - DATA = 'foobar' + DATA = b'foobar' class AllSubDevicesGetBackgroundQueuedStatusPolicy( From e1c2de71675fa40eff24b89adcda4f4ebc4631fe Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 28 Mar 2024 22:42:51 +0000 Subject: [PATCH 83/86] Fix some flake8 issues --- tools/rdm/TestDefinitions.py | 18 ++++++++++++------ tools/rdm/list_rdm_tests.py | 20 +++++++++++++------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/rdm/TestDefinitions.py b/tools/rdm/TestDefinitions.py index d0ecf2635d..db3f98a1a2 100644 --- a/tools/rdm/TestDefinitions.py +++ b/tools/rdm/TestDefinitions.py @@ -8654,8 +8654,9 @@ class SetBackgroundQueuedStatusPolicyWithNoData(TestMixins.SetWithNoDataMixin, PID = 'BACKGROUND_QUEUED_STATUS_POLICY' -class SetBackgroundQueuedStatusPolicyWithExtraData(TestMixins.SetWithDataMixin, - OptionalParameterTestFixture): +class SetBackgroundQueuedStatusPolicyWithExtraData( + TestMixins.SetWithDataMixin, + OptionalParameterTestFixture): """Send a SET BACKGROUND_QUEUED_STATUS_POLICY command with extra data.""" PID = 'BACKGROUND_QUEUED_STATUS_POLICY' @@ -8663,13 +8664,16 @@ class SetBackgroundQueuedStatusPolicyWithExtraData(TestMixins.SetWithDataMixin, class AllSubDevicesGetBackgroundQueuedStatusPolicyDescription( TestMixins.AllSubDevicesGetMixin, OptionalParameterTestFixture): - """Send a get BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION to ALL_SUB_DEVICES.""" + """Send a get BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION to + ALL_SUB_DEVICES. + """ PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' DATA = [0x00] -# class GetBackgroundQueuedStatusPolicyDescription(TestMixins., -# OptionalParameterTestFixture): +# class GetBackgroundQueuedStatusPolicyDescription( +# TestMixins., +# OptionalParameterTestFixture): # CATEGORY = TestCategory. # PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' # TODO(peter): Test get @@ -8685,7 +8689,9 @@ class GetBackgroundQueuedStatusPolicyDescriptionWithNoData( class GetBackgroundQueuedStatusPolicyDescriptionWithExtraData( TestMixins.GetWithDataMixin, OptionalParameterTestFixture): - """GET BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION with more than 1 byte of data.""" + """GET BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION with more than 1 byte of + data. + """ PID = 'BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION' diff --git a/tools/rdm/list_rdm_tests.py b/tools/rdm/list_rdm_tests.py index 1fd8771cdf..5e65512d67 100755 --- a/tools/rdm/list_rdm_tests.py +++ b/tools/rdm/list_rdm_tests.py @@ -154,14 +154,17 @@ def GetWithExtraData(names, pid, pid_test_base_name, get_size): dummy_data = GenerateDummyData(get_size) if dummy_data is None: print((" #DATA = b'foo' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % (getpass.getuser(), get_size)) + "enough. Ensure the first %d bytes are sane/valid.") % + (getpass.getuser(), get_size)) elif dummy_data != 'foo': # Doesn't match default, explicitly set value print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), get_size)) + "enough. Ensure the first %d bytes are sane/valid.") % + (dummy_data, getpass.getuser(), get_size)) else: print((" #DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), get_size)) + "enough. Ensure the first %d bytes are sane/valid.") % + (dummy_data, getpass.getuser(), get_size)) print('') print('') @@ -277,14 +280,17 @@ def SetWithExtraData(names, pid, pid_test_base_name, set_size): dummy_data = GenerateDummyData(set_size) if dummy_data is None: print((" #DATA = b'foo' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % (getpass.getuser(), set_size)) + "enough. Ensure the first %d bytes are sane/valid.") % + (getpass.getuser(), set_size)) elif dummy_data != 'foo': # Doesn't match default, explicitly set value print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), set_size)) + "enough. Ensure the first %d bytes are sane/valid.") % + (dummy_data, getpass.getuser(), set_size)) else: print((" #DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % (dummy_data, getpass.getuser(), set_size)) + "enough. Ensure the first %d bytes are sane/valid.") % + (dummy_data, getpass.getuser(), set_size)) print('') print('') @@ -353,7 +359,7 @@ def main(): (pid.GetRequest(PidStore.RDM_GET).HasAtoms())): for atom in pid.GetRequest(PidStore.RDM_GET).GetAtoms(): get_size += atom.size - #TODO(Peter): Should we just print this total all the time? + # TODO(Peter): Should we just print this total all the time? if get_size != pid.GetRequest(PidStore.RDM_GET).GetAtoms()[0].size: print('# Get requires %d bytes' % (get_size)) From 1e16dd92c33b7647f5f0b83dbfeb9f7b9d6e19be Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 28 Mar 2024 22:47:41 +0000 Subject: [PATCH 84/86] Fix the capitalisation in some test names --- tools/rdm/TestDefinitions.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/rdm/TestDefinitions.py b/tools/rdm/TestDefinitions.py index db3f98a1a2..68069ea354 100644 --- a/tools/rdm/TestDefinitions.py +++ b/tools/rdm/TestDefinitions.py @@ -8441,60 +8441,60 @@ class SetEndpointToUniverseWithExtraData(TestMixins.SetWithDataMixin, DATA = b'foobar' -class AllSubDevicesGetRdmTrafficEnable(TestMixins.AllSubDevicesGetMixin, +class AllSubDevicesGetRDMTrafficEnable(TestMixins.AllSubDevicesGetMixin, OptionalParameterTestFixture): """Send a get RDM_TRAFFIC_ENABLE to ALL_SUB_DEVICES.""" PID = 'RDM_TRAFFIC_ENABLE' DATA = [0x0001] -# class GetRdmTrafficEnable(TestMixins., +# class GetRDMTrafficEnable(TestMixins., # OptionalParameterTestFixture): # CATEGORY = TestCategory. # PID = 'RDM_TRAFFIC_ENABLE' # TODO(peter): Test get -class GetZeroRdmTrafficEnable(TestMixins.GetZeroUInt16Mixin, +class GetZeroRDMTrafficEnable(TestMixins.GetZeroUInt16Mixin, OptionalParameterTestFixture): """GET RDM_TRAFFIC_ENABLE for endpoint id 0.""" PID = 'RDM_TRAFFIC_ENABLE' OVERRIDE_NACKS = [RDMNack.NR_ENDPOINT_NUMBER_INVALID] -class GetRdmTrafficEnableWithNoData(TestMixins.GetWithNoDataMixin, +class GetRDMTrafficEnableWithNoData(TestMixins.GetWithNoDataMixin, OptionalParameterTestFixture): """GET RDM_TRAFFIC_ENABLE with no argument given.""" PID = 'RDM_TRAFFIC_ENABLE' -class GetRdmTrafficEnableWithExtraData(TestMixins.GetWithDataMixin, +class GetRDMTrafficEnableWithExtraData(TestMixins.GetWithDataMixin, OptionalParameterTestFixture): """GET RDM_TRAFFIC_ENABLE with more than 2 bytes of data.""" PID = 'RDM_TRAFFIC_ENABLE' -# class SetRdmTrafficEnable(TestMixins., +# class SetRDMTrafficEnable(TestMixins., # OptionalParameterTestFixture): # CATEGORY = TestCategory. # PID = 'RDM_TRAFFIC_ENABLE' # TODO(peter): Test set -# class SetZeroRdmTrafficEnable(TestMixins.SetZero, +# class SetZeroRDMTrafficEnable(TestMixins.SetZero, # OptionalParameterTestFixture): # """SET RDM_TRAFFIC_ENABLE for endpoint id 0.""" # PID = 'RDM_TRAFFIC_ENABLE' # TODO(peter): Test set zero -class SetRdmTrafficEnableWithNoData(TestMixins.SetWithNoDataMixin, +class SetRDMTrafficEnableWithNoData(TestMixins.SetWithNoDataMixin, OptionalParameterTestFixture): """Set RDM_TRAFFIC_ENABLE command with no data.""" PID = 'RDM_TRAFFIC_ENABLE' -class SetRdmTrafficEnableWithExtraData(TestMixins.SetWithDataMixin, +class SetRDMTrafficEnableWithExtraData(TestMixins.SetWithDataMixin, OptionalParameterTestFixture): """Send a SET RDM_TRAFFIC_ENABLE command with extra data.""" PID = 'RDM_TRAFFIC_ENABLE' From 840fa1b6e3238c8e84885d2b02cf8eec8ca72a35 Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 28 Mar 2024 23:10:16 +0000 Subject: [PATCH 85/86] Ensure the output of list_rdm_tests.py is itself more flake8 compliant --- tools/rdm/list_rdm_tests.py | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/rdm/list_rdm_tests.py b/tools/rdm/list_rdm_tests.py index 5e65512d67..a8f467be85 100755 --- a/tools/rdm/list_rdm_tests.py +++ b/tools/rdm/list_rdm_tests.py @@ -101,7 +101,7 @@ def AllSubDevicesGet(names, pid, pid_test_base_name, get_size): (pid.name)) print(' PID = \'%s\'' % (pid.name)) if get_size > 0: - print(' #DATA = [] # TODO(%s): Specify some suitable data, %d byte%s' % + print(' # DATA = [] # TODO(%s): Specify some suitable data, %d byte%s' % (getpass.getuser(), get_size, 's' if get_size > 1 else '')) print('') print('') @@ -153,18 +153,18 @@ def GetWithExtraData(names, pid, pid_test_base_name, get_size): print(' PID = \'%s\'' % (pid.name)) dummy_data = GenerateDummyData(get_size) if dummy_data is None: - print((" #DATA = b'foo' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % - (getpass.getuser(), get_size)) + print((" # DATA = b'foo' # TODO(%s): Specify extra data if this isn't " + "enough.") % (getpass.getuser())) + print(" # Ensure the first %d bytes are sane/valid." % (get_size)) elif dummy_data != 'foo': # Doesn't match default, explicitly set value - print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % - (dummy_data, getpass.getuser(), get_size)) + print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough.") % (dummy_data, getpass.getuser())) + print(" # Ensure the first %d bytes are sane/valid." % (get_size)) else: - print((" #DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % - (dummy_data, getpass.getuser(), get_size)) + print((" # DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough.") % (dummy_data, getpass.getuser())) + print(" # Ensure the first %d bytes are sane/valid." % (get_size)) print('') print('') @@ -279,18 +279,18 @@ def SetWithExtraData(names, pid, pid_test_base_name, set_size): print(' PID = \'%s\'' % (pid.name)) dummy_data = GenerateDummyData(set_size) if dummy_data is None: - print((" #DATA = b'foo' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % - (getpass.getuser(), set_size)) + print((" # DATA = b'foo' # TODO(%s): Specify extra data if this isn't " + "enough.") % (dummy_data, getpass.getuser())) + print(" # Ensure the first %d bytes are sane/valid." % (set_size)) elif dummy_data != 'foo': # Doesn't match default, explicitly set value - print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % - (dummy_data, getpass.getuser(), set_size)) + print((" DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough.") % (dummy_data, getpass.getuser())) + print(" # Ensure the first %d bytes are sane/valid." % (set_size)) else: - print((" #DATA = b'%s' # TODO(%s): Specify extra data if this isn't " - "enough. Ensure the first %d bytes are sane/valid.") % - (dummy_data, getpass.getuser(), set_size)) + print((" # DATA = b'%s' # TODO(%s): Specify extra data if this isn't " + "enough.") % (dummy_data, getpass.getuser())) + print(" # Ensure the first %d bytes are sane/valid." % (set_size)) print('') print('') From e3aa1e170bec2ce8ec7170dfcc89a7a928cd67ba Mon Sep 17 00:00:00 2001 From: Peter Newman Date: Thu, 28 Mar 2024 23:57:14 +0000 Subject: [PATCH 86/86] Fix a copy/paste error --- tools/rdm/list_rdm_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/rdm/list_rdm_tests.py b/tools/rdm/list_rdm_tests.py index a8f467be85..fc7a818469 100755 --- a/tools/rdm/list_rdm_tests.py +++ b/tools/rdm/list_rdm_tests.py @@ -280,7 +280,7 @@ def SetWithExtraData(names, pid, pid_test_base_name, set_size): dummy_data = GenerateDummyData(set_size) if dummy_data is None: print((" # DATA = b'foo' # TODO(%s): Specify extra data if this isn't " - "enough.") % (dummy_data, getpass.getuser())) + "enough.") % (getpass.getuser())) print(" # Ensure the first %d bytes are sane/valid." % (set_size)) elif dummy_data != 'foo': # Doesn't match default, explicitly set value