Skip to content

Commit 32ecc52

Browse files
committed
Add the ability to pack an RDMPDU
1 parent 1955638 commit 32ecc52

File tree

3 files changed

+141
-1
lines changed

3 files changed

+141
-1
lines changed

libs/acn/RDMPDU.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ namespace acn {
2929
using ola::io::OutputStream;
3030
using ola::network::HostToNetwork;
3131

32+
unsigned int RDMPDU::DataSize() const {
33+
return static_cast<unsigned int>(m_command.size());
34+
}
35+
36+
bool RDMPDU::PackData(uint8_t *data, unsigned int *length) const {
37+
*length = static_cast<unsigned int>(m_command.size());
38+
memcpy(data, reinterpret_cast<const uint8_t*>(m_command.data()), *length);
39+
return true;
40+
}
41+
42+
void RDMPDU::PackData(ola::io::OutputStream *stream) const {
43+
stream->Write(reinterpret_cast<const uint8_t*>(m_command.data()),
44+
static_cast<unsigned int>(m_command.size()));
45+
}
46+
3247
void RDMPDU::PrependPDU(ola::io::IOStack *stack) {
3348
uint8_t vector = HostToNetwork(ola::rdm::START_CODE);
3449
stack->Write(reinterpret_cast<uint8_t*>(&vector), sizeof(vector));

libs/acn/RDMPDU.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,38 @@
2121
#ifndef LIBS_ACN_RDMPDU_H_
2222
#define LIBS_ACN_RDMPDU_H_
2323

24+
#include <string>
25+
#include <ola/io/ByteString.h>
2426
#include <ola/io/IOStack.h>
27+
#include <ola/rdm/RDMPacket.h>
2528

2629
#include "libs/acn/PDU.h"
2730

2831
namespace ola {
2932
namespace acn {
3033

31-
class RDMPDU : private PDU {
34+
class RDMPDU : public PDU {
3235
public:
36+
explicit RDMPDU(const ola::io::ByteString &command):
37+
PDU(ola::rdm::START_CODE, ONE_BYTE, true),
38+
m_command(command) {}
39+
40+
unsigned int HeaderSize() const { return 0; }
41+
bool PackHeader(OLA_UNUSED uint8_t *data,
42+
unsigned int *length) const {
43+
*length = 0;
44+
return true;
45+
}
46+
void PackHeader(OLA_UNUSED ola::io::OutputStream *stream) const {}
47+
48+
unsigned int DataSize() const;
49+
bool PackData(uint8_t *data, unsigned int *length) const;
50+
void PackData(ola::io::OutputStream *stream) const;
51+
3352
static void PrependPDU(ola::io::IOStack *stack);
53+
54+
private:
55+
const ola::io::ByteString m_command;
3456
};
3557
} // namespace acn
3658
} // namespace ola

libs/acn/RDMPDUTest.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <string>
2424

2525
#include "ola/Logging.h"
26+
#include "ola/io/ByteString.h"
27+
#include "ola/io/IOQueue.h"
2628
#include "ola/io/IOStack.h"
2729
#include "ola/network/NetworkUtils.h"
2830
#include "ola/testing/TestUtils.h"
@@ -32,24 +34,125 @@
3234
namespace ola {
3335
namespace acn {
3436

37+
using ola::io::ByteString;
38+
using ola::io::IOQueue;
3539
using ola::io::IOStack;
40+
using ola::io::OutputStream;
41+
using ola::network::HostToNetwork;
3642

3743
class RDMPDUTest: public CppUnit::TestFixture {
3844
CPPUNIT_TEST_SUITE(RDMPDUTest);
45+
CPPUNIT_TEST(testSimpleRDMPDU);
46+
CPPUNIT_TEST(testSimpleRDMPDUToOutputStream);
3947
CPPUNIT_TEST(testPrepend);
4048
CPPUNIT_TEST_SUITE_END();
4149

4250
public:
51+
void testSimpleRDMPDU();
52+
void testSimpleRDMPDUToOutputStream();
4353
void testPrepend();
4454

4555
private:
4656
static const unsigned int TEST_VECTOR;
57+
static const uint8_t EXPECTED_GET_RESPONSE_BUFFER[];
4758
};
4859

4960
CPPUNIT_TEST_SUITE_REGISTRATION(RDMPDUTest);
5061

5162
const unsigned int RDMPDUTest::TEST_VECTOR = 0xcc;
5263

64+
const uint8_t RDMPDUTest::EXPECTED_GET_RESPONSE_BUFFER[] = {
65+
1, 28, // sub code & length
66+
0, 3, 0, 0, 0, 4, // dst uid
67+
0, 1, 0, 0, 0, 2, // src uid
68+
0, 0, 0, 0, 10, // transaction, port id, msg count & sub device
69+
0x21, 1, 40, 4, // command, param id, param data length
70+
0x5a, 0x5a, 0x5a, 0x5a, // param data
71+
0x02, 0xb3 // checksum
72+
};
73+
74+
/*
75+
* Test that packing an RDMPDU works.
76+
*/
77+
void RDMPDUTest::testSimpleRDMPDU() {
78+
ByteString empty;
79+
RDMPDU empty_pdu(empty);
80+
81+
OLA_ASSERT_EQ(0u, empty_pdu.HeaderSize());
82+
OLA_ASSERT_EQ(0u, empty_pdu.DataSize());
83+
OLA_ASSERT_EQ(4u, empty_pdu.Size());
84+
85+
ByteString response(EXPECTED_GET_RESPONSE_BUFFER,
86+
sizeof(EXPECTED_GET_RESPONSE_BUFFER));
87+
RDMPDU pdu(response);
88+
89+
OLA_ASSERT_EQ(0u, pdu.HeaderSize());
90+
OLA_ASSERT_EQ(29u, pdu.DataSize());
91+
OLA_ASSERT_EQ(33u, pdu.Size());
92+
93+
unsigned int size = pdu.Size();
94+
uint8_t *data = new uint8_t[size];
95+
unsigned int bytes_used = size;
96+
OLA_ASSERT(pdu.Pack(data, &bytes_used));
97+
OLA_ASSERT_EQ(size, bytes_used);
98+
99+
// spot check the data
100+
OLA_ASSERT_EQ((uint8_t) 0xf0, data[0]);
101+
// bytes_used is technically data[1] and data[2] if > 255
102+
OLA_ASSERT_EQ((uint8_t) bytes_used, data[2]);
103+
OLA_ASSERT_EQ(HostToNetwork((uint8_t) TEST_VECTOR), data[3]);
104+
105+
// test undersized buffer
106+
bytes_used = size - 1;
107+
OLA_ASSERT_FALSE(pdu.Pack(data, &bytes_used));
108+
OLA_ASSERT_EQ(0u, bytes_used);
109+
110+
// test oversized buffer
111+
bytes_used = size + 1;
112+
OLA_ASSERT(pdu.Pack(data, &bytes_used));
113+
OLA_ASSERT_EQ(size, bytes_used);
114+
delete[] data;
115+
}
116+
117+
118+
/*
119+
* Test that writing to an output stream works.
120+
*/
121+
void RDMPDUTest::testSimpleRDMPDUToOutputStream() {
122+
ByteString response(EXPECTED_GET_RESPONSE_BUFFER,
123+
sizeof(EXPECTED_GET_RESPONSE_BUFFER));
124+
RDMPDU pdu(response);
125+
126+
OLA_ASSERT_EQ(0u, pdu.HeaderSize());
127+
OLA_ASSERT_EQ(29u, pdu.DataSize());
128+
OLA_ASSERT_EQ(33u, pdu.Size());
129+
130+
IOQueue output;
131+
OutputStream stream(&output);
132+
pdu.Write(&stream);
133+
OLA_ASSERT_EQ(33u, output.Size());
134+
135+
uint8_t *pdu_data = new uint8_t[output.Size()];
136+
unsigned int pdu_size = output.Peek(pdu_data, output.Size());
137+
OLA_ASSERT_EQ(output.Size(), pdu_size);
138+
139+
uint8_t EXPECTED[] = {
140+
0xf0, 0x00, 0x21,
141+
0xcc,
142+
1, 28, // sub code & length
143+
0, 3, 0, 0, 0, 4, // dst uid
144+
0, 1, 0, 0, 0, 2, // src uid
145+
0, 0, 0, 0, 10, // transaction, port id, msg count & sub device
146+
0x21, 1, 40, 4, // command, param id, param data length
147+
0x5a, 0x5a, 0x5a, 0x5a, // param data
148+
0x02, 0xb3 // checksum
149+
};
150+
OLA_ASSERT_DATA_EQUALS(EXPECTED, sizeof(EXPECTED), pdu_data, pdu_size);
151+
output.Pop(output.Size());
152+
delete[] pdu_data;
153+
}
154+
155+
53156
void RDMPDUTest::testPrepend() {
54157
IOStack stack;
55158
RDMPDU::PrependPDU(&stack);

0 commit comments

Comments
 (0)