Skip to content

More RDM Responder tests #1999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions common/rdm/DummyResponder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,15 @@ const ResponderOps<DummyResponder>::ParamHandler
{ PID_TEST_DATA,
&DummyResponder::GetTestData,
&DummyResponder::SetTestData},
{ PID_METADATA_PARAMETER_VERSION,
&DummyResponder::GetMetadataParameterVersion,
NULL},
{ PID_METADATA_JSON,
&DummyResponder::GetMetadataJSON,
NULL},
{ PID_METADATA_JSON_URL,
&DummyResponder::GetMetadataJSONURL,
NULL},
{ OLA_MANUFACTURER_PID_CODE_VERSION,
&DummyResponder::GetOlaCodeVersion,
NULL},
Expand Down Expand Up @@ -460,7 +469,7 @@ RDMResponse *DummyResponder::GetProductURL(
request,
"https://openlighting.org/rdm-tools/dummy-responders/",
0,
UINT8_MAX); // TODO(Peter): This field's length isn't limited in the spec
UINT8_MAX); // TODO(Peter): This field's length isn't limited in the spec
}

RDMResponse *DummyResponder::GetFirmwareURL(
Expand All @@ -469,7 +478,7 @@ RDMResponse *DummyResponder::GetFirmwareURL(
request,
"https://github.com/OpenLightingProject/ola",
0,
UINT8_MAX); // TODO(Peter): This field's length isn't limited in the spec
UINT8_MAX); // TODO(Peter): This field's length isn't limited in the spec
}

RDMResponse *DummyResponder::GetTestData(const RDMRequest *request) {
Expand All @@ -480,6 +489,58 @@ RDMResponse *DummyResponder::SetTestData(const RDMRequest *request) {
return ResponderHelper::SetTestData(request);
}

RDMResponse *DummyResponder::GetMetadataParameterVersion(
const RDMRequest *request) {
// Check that it's OLA_MANUFACTURER_PID_CODE_VERSION being requested
uint16_t parameter_id;
if (!ResponderHelper::ExtractUInt16(request, &parameter_id)) {
return NackWithReason(request, NR_FORMAT_ERROR);
}

if (parameter_id != OLA_MANUFACTURER_PID_CODE_VERSION) {
OLA_WARN << "Dummy responder received metadata parameter version request "
<< "with unknown PID, expected "
<< OLA_MANUFACTURER_PID_CODE_VERSION << ", got " << parameter_id;
return NackWithReason(request, NR_DATA_OUT_OF_RANGE);
} else {
return ResponderHelper::GetMetadataParameterVersion(
request,
OLA_MANUFACTURER_PID_CODE_VERSION,
OLA_MANUFACTURER_PID_JSON_VERSION_CODE_VERSION);
}
}

RDMResponse *DummyResponder::GetMetadataJSON(
const RDMRequest *request) {
// Check that it's OLA_MANUFACTURER_PID_CODE_VERSION being requested
uint16_t parameter_id;
if (!ResponderHelper::ExtractUInt16(request, &parameter_id)) {
return NackWithReason(request, NR_FORMAT_ERROR);
}

if (parameter_id != OLA_MANUFACTURER_PID_CODE_VERSION) {
OLA_WARN << "Dummy responder received metadata JSON request with unknown "
<< "PID, expected "
<< OLA_MANUFACTURER_PID_CODE_VERSION << ", got " << parameter_id;
return NackWithReason(request, NR_DATA_OUT_OF_RANGE);
} else {
return ResponderHelper::GetMetadataJSON(
request,
OLA_MANUFACTURER_PID_CODE_VERSION,
OLA_MANUFACTURER_PID_JSON_CODE_VERSION);
}
}

RDMResponse *DummyResponder::GetMetadataJSONURL(
const RDMRequest *request) {
return ResponderHelper::GetString(
request,
// TODO(Peter): Consider what this should actually be permanently
"https://docs.openlighting.org/ola/json/latest/metadata/0x0001.json",
0,
UINT8_MAX); // TODO(Peter): This field's length isn't limited in the spec
}

RDMResponse *DummyResponder::GetOlaCodeVersion(
const RDMRequest *request) {
return ResponderHelper::GetString(request, VERSION);
Expand Down
6 changes: 6 additions & 0 deletions common/rdm/OpenLightingEnums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ namespace rdm {

const char OLA_MANUFACTURER_LABEL[] = "Open Lighting Project";
const char OLA_MANUFACTURER_URL[] = "https://openlighting.org/";

const char OLA_MANUFACTURER_PID_JSON_CODE_VERSION[] = "{\"name\":"
"\"CODE_VERSION\",\"manufacturer_id\":31344,\"pid\":32769,\"version\":1,"
"\"get_request_subdevice_range\":[\"root\",\"subdevices\"],"
"\"get_request\":[],\"get_response\":[{\"name\":\"code_version\","
"\"type\":\"string\",""\"maxLength\":32,\"restrictToASCII\":true}]}";
} // namespace rdm
} // namespace ola
122 changes: 119 additions & 3 deletions common/rdm/ResponderHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ RDMResponse *ResponderHelper::GetParamDescription(
uint32_t min_value,
uint32_t default_value,
uint32_t max_value,
string description,
const string description,
uint8_t queued_message_count) {
PACK(
struct parameter_description_s {
Expand Down Expand Up @@ -1019,7 +1019,7 @@ RDMResponse *ResponderHelper::GetASCIIParamDescription(
const RDMRequest *request,
uint16_t pid,
rdm_command_class command_class,
string description,
const string description,
uint8_t queued_message_count) {
return GetParamDescription(
request,
Expand All @@ -1041,7 +1041,7 @@ RDMResponse *ResponderHelper::GetBitFieldParamDescription(
uint16_t pid,
uint8_t pdl_size,
rdm_command_class command_class,
string description,
const string description,
uint8_t queued_message_count) {
return GetParamDescription(
request,
Expand Down Expand Up @@ -1110,6 +1110,65 @@ RDMResponse *ResponderHelper::SetTestData(
queued_message_count);
}

/**
* Get NSC comms status
*/
RDMResponse *ResponderHelper::GetCommsStatusNSC(
const RDMRequest *request,
const NSCStatus *status,
uint8_t queued_message_count) {
if (request->ParamDataSize()) {
return NackWithReason(request, NR_FORMAT_ERROR, queued_message_count);
}

PACK(
struct comms_status_nsc_s {
uint8_t supported_fields;
uint32_t additive_checksum;
uint32_t packet_count;
uint16_t most_recent_slot_count;
uint16_t min_slot_count;
uint16_t max_slot_count;
uint32_t packet_error_count;
});
STATIC_ASSERT(sizeof(comms_status_nsc_s) == 19);

struct comms_status_nsc_s comms_status_nsc;
comms_status_nsc.supported_fields = status->SupportedFieldsBitMask();
comms_status_nsc.additive_checksum = HostToNetwork(
status->AdditiveChecksum());
comms_status_nsc.packet_count = HostToNetwork(status->PacketCount());
comms_status_nsc.most_recent_slot_count = HostToNetwork(
status->MostRecentSlotCount());
comms_status_nsc.min_slot_count = HostToNetwork(status->MinSlotCount());
comms_status_nsc.max_slot_count = HostToNetwork(status->MaxSlotCount());
comms_status_nsc.packet_error_count = HostToNetwork(
status->PacketErrorCount());
return GetResponseFromData(
request,
reinterpret_cast<const uint8_t*>(&comms_status_nsc),
sizeof(comms_status_nsc),
RDM_ACK,
queued_message_count);
}

/**
* Set NSC comms status
*/
RDMResponse *ResponderHelper::SetCommsStatusNSC(
const RDMRequest *request,
NSCStatus *status,
uint8_t queued_message_count) {
if (request->ParamDataSize()) {
return NackWithReason(request, NR_FORMAT_ERROR, queued_message_count);
}

// Reset the counts...
status->Reset();

return GetResponseFromData(request, NULL, queued_message_count);
}

RDMResponse *ResponderHelper::GetListTags(
const RDMRequest *request,
const TagSet *tag_set,
Expand Down Expand Up @@ -1187,6 +1246,63 @@ RDMResponse *ResponderHelper::SetClearTags(
return ResponderHelper::EmptySetResponse(request, queued_message_count);
}

RDMResponse *ResponderHelper::GetMetadataParameterVersion(
const RDMRequest *request,
uint16_t pid,
uint16_t version,
uint8_t queued_message_count) {
PACK(
struct metadata_parameter_version_s {
uint16_t pid;
uint16_t version;
});
STATIC_ASSERT(sizeof(metadata_parameter_version_s) == 4);

struct metadata_parameter_version_s metadata_param_version;
metadata_param_version.pid = HostToNetwork(pid);
metadata_param_version.version = HostToNetwork(version);

return GetResponseFromData(
request,
reinterpret_cast<uint8_t*>(&metadata_param_version),
sizeof(metadata_parameter_version_s),
RDM_ACK,
queued_message_count);
}

RDMResponse *ResponderHelper::GetMetadataJSON(
const RDMRequest *request,
uint16_t pid,
const string json,
uint8_t queued_message_count) {
PACK(
struct metadata_json_s {
uint16_t pid;
// TODO(Peter): This should effectively be unlimited...?
char json[(UINT8_MAX - 2)];
});
STATIC_ASSERT(sizeof(metadata_json_s) == UINT8_MAX);

struct metadata_json_s metadata_json;
metadata_json.pid = HostToNetwork(pid);

size_t str_len = min(json.size(),
sizeof(metadata_json.json));
strncpy(metadata_json.json, json.c_str(), str_len);

unsigned int param_data_size = (
sizeof(metadata_json) -
sizeof(metadata_json.json) + str_len);

return GetResponseFromData(
request,
reinterpret_cast<uint8_t*>(&metadata_json),
param_data_size,
RDM_ACK,
queued_message_count);
}


/**
* @brief Handle a request that returns a string
* @note this truncates the string to max_length
Expand Down
9 changes: 9 additions & 0 deletions common/utils/DmxBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ bool DmxBuffer::operator!=(const DmxBuffer &other) const {
}


unsigned int DmxBuffer::AdditiveChecksum() const {
unsigned int checksum = 0;
for (unsigned int i = 0; i < Size(); i++) {
checksum += m_data[i];
}
return checksum;
}


bool DmxBuffer::HTPMerge(const DmxBuffer &other) {
if (!m_data) {
if (!Init())
Expand Down
17 changes: 17 additions & 0 deletions common/utils/DmxBufferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class DmxBufferTest: public CppUnit::TestFixture {
CPPUNIT_TEST(testStringGetSet);
CPPUNIT_TEST(testAssign);
CPPUNIT_TEST(testCopy);
CPPUNIT_TEST(testAdditiveChecksum);
CPPUNIT_TEST(testMerge);
CPPUNIT_TEST(testStringToDmx);
CPPUNIT_TEST(testCopyOnWrite);
Expand All @@ -52,6 +53,7 @@ class DmxBufferTest: public CppUnit::TestFixture {
void testAssign();
void testStringGetSet();
void testCopy();
void testAdditiveChecksum();
void testMerge();
void testStringToDmx();
void testCopyOnWrite();
Expand Down Expand Up @@ -261,6 +263,21 @@ void DmxBufferTest::testCopy() {
}


/*
* Check that the additive checksum works
*/
void DmxBufferTest::testAdditiveChecksum() {
DmxBuffer buffer1(TEST_DATA, sizeof(TEST_DATA));
OLA_ASSERT_EQ(15u, buffer1.AdditiveChecksum());

DmxBuffer buffer2(TEST_DATA2, sizeof(TEST_DATA2));
OLA_ASSERT_EQ(45u, buffer2.AdditiveChecksum());

DmxBuffer buffer3(TEST_DATA3, sizeof(TEST_DATA3));
OLA_ASSERT_EQ(33u, buffer3.AdditiveChecksum());
}


/*
* Check that HTP Merging works
*/
Expand Down
6 changes: 6 additions & 0 deletions include/ola/DmxBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ class DmxBuffer {
*/
unsigned int Size() const { return m_length; }

/**
* @brief Additive checksum of DmxBuffer
* @return the additive checksum of slots in the buffer.
*/
unsigned int AdditiveChecksum() const;

/**
* @brief HTP Merge from another DmxBuffer.
* @param other the DmxBuffer to HTP merge into this one
Expand Down
3 changes: 3 additions & 0 deletions include/ola/rdm/DummyResponder.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ class DummyResponder: public RDMControllerInterface {
RDMResponse *GetFirmwareURL(const RDMRequest *request);
RDMResponse *GetTestData(const RDMRequest *request);
RDMResponse *SetTestData(const RDMRequest *request);
RDMResponse *GetMetadataParameterVersion(const RDMRequest *request);
RDMResponse *GetMetadataJSON(const RDMRequest *request);
RDMResponse *GetMetadataJSONURL(const RDMRequest *request);

static const ResponderOps<DummyResponder>::ParamHandler PARAM_HANDLERS[];
static const uint8_t DEFAULT_PERSONALITY = 2;
Expand Down
1 change: 1 addition & 0 deletions include/ola/rdm/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ olardminclude_HEADERS = \
include/ola/rdm/RDMReply.h \
include/ola/rdm/ResponderHelper.h \
include/ola/rdm/ResponderLoadSensor.h \
include/ola/rdm/ResponderNSCStatus.h \
include/ola/rdm/ResponderOps.h \
include/ola/rdm/ResponderOpsPrivate.h \
include/ola/rdm/ResponderPersonality.h \
Expand Down
8 changes: 8 additions & 0 deletions include/ola/rdm/OpenLightingEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ typedef enum {
OLA_MANUFACTURER_PID_CODE_VERSION = 0x8001,
} rdm_ola_manufacturer_pid;

// TODO(Peter): Some sort of vector against rdm_ola_manufacturer_pid or
// something nicer?
typedef enum {
OLA_MANUFACTURER_PID_JSON_VERSION_SERIAL_NUMBER = 1,
OLA_MANUFACTURER_PID_JSON_VERSION_CODE_VERSION = 1,
} rdm_ola_manufacturer_pid_json_version;

/**
* Also see the list here
* https://wiki.openlighting.org/index.php/Open_Lighting_Allocations#RDM_Model_Numbers
Expand Down Expand Up @@ -77,6 +84,7 @@ typedef enum {

extern const char OLA_MANUFACTURER_LABEL[];
extern const char OLA_MANUFACTURER_URL[];
extern const char OLA_MANUFACTURER_PID_JSON_CODE_VERSION[];
} // namespace rdm
} // namespace ola
#endif // INCLUDE_OLA_RDM_OPENLIGHTINGENUMS_H_
23 changes: 23 additions & 0 deletions include/ola/rdm/RDMEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,29 @@ static const uint8_t DNS_NAME_SERVER_MAX_INDEX = 2;
// Consts for E1.37-5
static const uint16_t MAX_RDM_TEST_DATA_PATTERN_LENGTH = 4096;

// bit masks for NSC status
static const uint8_t NSC_STATUS_ADDITIVE_CHECKSUM_SUPPORTED_VALUE = 0x01;
static const uint8_t NSC_STATUS_PACKET_COUNT_SUPPORTED_VALUE = 0x02;
static const uint8_t NSC_STATUS_MOST_RECENT_SLOT_COUNT_SUPPORTED_VALUE = 0x04;
static const uint8_t NSC_STATUS_MIN_SLOT_COUNT_SUPPORTED_VALUE = 0x08;
static const uint8_t NSC_STATUS_MAX_SLOT_COUNT_SUPPORTED_VALUE = 0x10;
static const uint8_t NSC_STATUS_PACKET_ERROR_COUNT_SUPPORTED_VALUE = 0x20;

// Consts for NSC status when unsupported
static const uint32_t NSC_STATUS_ADDITIVE_CHECKSUM_UNSUPPORTED = 0xFFFFFFFF;
static const uint32_t NSC_STATUS_PACKET_COUNT_UNSUPPORTED = 0xFFFFFFFF;
static const uint16_t NSC_STATUS_MOST_RECENT_SLOT_COUNT_UNSUPPORTED = 0xFFFF;
static const uint16_t NSC_STATUS_MIN_SLOT_COUNT_UNSUPPORTED = 0xFFFF;
static const uint16_t NSC_STATUS_MAX_SLOT_COUNT_UNSUPPORTED = 0xFFFF;
static const uint32_t NSC_STATUS_PACKET_ERROR_COUNT_UNSUPPORTED = 0xFFFFFFFF;

// Consts for NSC status max range
static const uint32_t NSC_STATUS_PACKET_COUNT_MAX = 0xFFFFFFFE;
static const uint16_t NSC_STATUS_MOST_RECENT_SLOT_COUNT_MAX = 0xFFFE;
static const uint16_t NSC_STATUS_MIN_SLOT_COUNT_MAX = 0xFFFE;
static const uint16_t NSC_STATUS_MAX_SLOT_COUNT_MAX = 0xFFFE;
static const uint32_t NSC_STATUS_PACKET_ERROR_COUNT_MAX = 0xFFFFFFFE;

// The shipping lock states
typedef enum {
SHIPPING_LOCK_STATE_UNLOCKED = 0x00,
Expand Down
Loading
Loading