syndilights/open-lighting-architecture/ola-0.8.4/common/rdm/RDMAPITest.cpp

1071 lines
34 KiB
C++

/*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* RDMAPITest.cpp
* Test fixture for the RDM API class
* Copyright (C) 2005-2010 Simon Newton
*/
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
#include <deque>
#include <string>
#include <vector>
#include "ola/network/NetworkUtils.h"
#include "ola/rdm/UID.h"
#include "ola/rdm/RDMAPI.h"
#include "ola/rdm/RDMAPIImplInterface.h"
using ola::NewSingleCallback;
using ola::network::HostToNetwork;
using ola::rdm::RDMAPI;
using ola::rdm::RDMAPIImplResponseStatus;
using ola::rdm::ResponseStatus;
using ola::rdm::UID;
using std::deque;
using std::string;
using std::vector;
class ExpectedResult {
public:
unsigned int universe;
const UID uid;
uint16_t sub_device;
uint16_t pid;
const string return_data;
const uint8_t *data;
unsigned int data_length;
ExpectedResult(unsigned int universe,
const UID &uid,
uint16_t sub_device,
uint16_t pid,
const string &return_data,
const uint8_t *data_arg = NULL,
unsigned int data_length = 0):
universe(universe),
uid(uid),
sub_device(sub_device),
pid(pid),
return_data(return_data),
data(NULL),
data_length(data_length) {
if (data_arg) {
uint8_t *d = new uint8_t[data_length];
memcpy(d, data_arg, data_length);
data = d;
}
}
~ExpectedResult() {
if (data)
delete[] data;
}
};
class MockRDMAPIImpl: public ola::rdm::RDMAPIImplInterface {
public:
bool RDMGet(rdm_callback *callback,
unsigned int universe,
const UID &uid,
uint16_t sub_device,
uint16_t pid,
const uint8_t *data = NULL,
unsigned int data_length = 0) {
CPPUNIT_ASSERT(m_get_expected.size());
const ExpectedResult *result = m_get_expected.front();
CPPUNIT_ASSERT_EQUAL(result->universe, universe);
CPPUNIT_ASSERT_EQUAL(result->uid, uid);
CPPUNIT_ASSERT_EQUAL(result->sub_device, sub_device);
CPPUNIT_ASSERT_EQUAL(result->pid, pid);
(void) data;
(void) data_length;
RDMAPIImplResponseStatus status;
status.was_broadcast = uid.IsBroadcast();
status.response_type = ola::rdm::ACK;
status.message_count = 0;
callback->Run(status, result->return_data);
delete result;
m_get_expected.pop_front();
return true;
}
bool RDMSet(rdm_callback *callback,
unsigned int universe,
const UID &uid,
uint16_t sub_device,
uint16_t pid,
const uint8_t *data = NULL,
unsigned int data_length = 0) {
CPPUNIT_ASSERT(m_set_expected.size());
const ExpectedResult *result = m_set_expected.front();
CPPUNIT_ASSERT_EQUAL(result->universe, universe);
CPPUNIT_ASSERT_EQUAL(result->uid, uid);
CPPUNIT_ASSERT_EQUAL(result->sub_device, sub_device);
CPPUNIT_ASSERT_EQUAL(result->pid, pid);
if (result->data) {
CPPUNIT_ASSERT_EQUAL(result->data_length, data_length);
CPPUNIT_ASSERT(0 == memcmp(result->data, data, data_length));
}
RDMAPIImplResponseStatus status;
status.was_broadcast = uid.IsBroadcast();
status.response_type = ola::rdm::ACK;
status.message_count = 0;
callback->Run(status, result->return_data);
delete result;
m_set_expected.pop_front();
return true;
}
void AddExpectedGet(
// const RDMAPIImplResponseStatus &status,
const string &return_data,
unsigned int universe,
const UID &uid,
uint16_t sub_device,
uint16_t pid,
const uint8_t *data = NULL,
unsigned int data_length = 0) {
ExpectedResult *expected_result = new ExpectedResult(universe,
uid,
sub_device,
pid,
return_data,
data,
data_length);
m_get_expected.push_back(expected_result);
}
void AddExpectedSet(unsigned int universe,
const UID &uid,
uint16_t sub_device,
uint16_t pid,
const uint8_t *data = NULL,
unsigned int data_length = 0) {
string s;
ExpectedResult *expected_result = new ExpectedResult(universe,
uid,
sub_device,
pid,
s,
data,
data_length);
m_set_expected.push_back(expected_result);
}
void Verify() {
CPPUNIT_ASSERT(!m_get_expected.size());
CPPUNIT_ASSERT(!m_set_expected.size());
}
private:
deque<ExpectedResult*> m_get_expected;
deque<ExpectedResult*> m_set_expected;
};
class RDMAPITest: public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(RDMAPITest);
CPPUNIT_TEST(testProxyCommands);
CPPUNIT_TEST(testNetworkCommands);
CPPUNIT_TEST(testRDMInformation);
CPPUNIT_TEST(testProductInformation);
CPPUNIT_TEST(testDmxSetup);
CPPUNIT_TEST_SUITE_END();
public:
RDMAPITest():
m_api(&m_impl),
m_uid(1, 2),
m_bcast_uid(UID::AllDevices()),
m_group_uid(UID::AllManufactureDevices(52)),
m_test_uid1(4, 5),
m_test_uid2(7, 9) {
}
void testProxyCommands();
void testNetworkCommands();
void testRDMInformation();
void testProductInformation();
void testDmxSetup();
void setUp() {}
void tearDown();
private:
static const unsigned int UNIVERSE = 1;
static const char BROADCAST_ERROR[];
static const char DEVICE_RANGE_ERROR[];
static const char DEVICE_RANGE_BCAST_ERROR[];
static const char TEST_DESCRIPTION[];
MockRDMAPIImpl m_impl;
RDMAPI m_api;
UID m_uid;
UID m_bcast_uid;
UID m_group_uid;
UID m_test_uid1;
UID m_test_uid2;
// check that a RDM call failed because we tried to send to the bcast UID
void CheckForBroadcastError(string *error) {
CPPUNIT_ASSERT_EQUAL(string(BROADCAST_ERROR), *error);
error->clear();
}
// check that a RDM call failed because we tried to send to all devices
void CheckForDeviceRangeError(string *error) {
CPPUNIT_ASSERT_EQUAL(string(DEVICE_RANGE_ERROR), *error);
error->clear();
}
void CheckForDeviceRangeBcastError(string *error) {
CPPUNIT_ASSERT_EQUAL(string(DEVICE_RANGE_BCAST_ERROR), *error);
error->clear();
}
// check that a RDM command was successful
void CheckResponseStatus(const ResponseStatus &status) {
CPPUNIT_ASSERT_EQUAL(ola::rdm::ResponseStatus::VALID_RESPONSE,
status.ResponseType());
}
// check that a RDM command was successful and broadcast
void CheckWasBroadcast(const ResponseStatus &status) {
CPPUNIT_ASSERT_EQUAL(ola::rdm::ResponseStatus::BROADCAST_REQUEST,
status.ResponseType());
}
void CheckProxiedDeviceCount(const ResponseStatus &status,
uint16_t count,
bool changed) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(2), count);
CPPUNIT_ASSERT_EQUAL(false, changed);
}
void CheckProxiedDevices(const ResponseStatus &status,
const vector<UID> &devices) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), devices.size());
CPPUNIT_ASSERT_EQUAL(m_test_uid1, devices[0]);
CPPUNIT_ASSERT_EQUAL(m_test_uid2, devices[1]);
}
void CheckCommsStatus(const ResponseStatus &status,
uint16_t short_message,
uint16_t length_mismatch,
uint16_t checksum_fail) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(14), short_message);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(187), length_mismatch);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(92), checksum_fail);
}
void CheckLabel(const ResponseStatus &status,
const string &description) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(string(TEST_DESCRIPTION), description);
}
void CheckSupportedParams(const ResponseStatus &status,
const vector<uint16_t> &params) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), params.size());
// params are sorted
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(0x00aa), params[0]);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(0x1234), params[1]);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(0xabcd), params[2]);
}
void CheckParameterDescription(
const ResponseStatus &status,
const ola::rdm::ParameterDescriptor &description) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(0x1234), description.pid);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(10), description.pdl_size);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(ola::rdm::DS_UNSIGNED_DWORD),
description.data_type);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(ola::rdm::CC_GET),
description.command_class);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(ola::rdm::UNITS_METERS),
description.unit);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(ola::rdm::PREFIX_KILO),
description.prefix);
CPPUNIT_ASSERT_EQUAL(static_cast<uint32_t>(0), description.min_value);
CPPUNIT_ASSERT_EQUAL(static_cast<uint32_t>(200000),
description.max_value);
CPPUNIT_ASSERT_EQUAL(static_cast<uint32_t>(1000),
description.default_value);
CPPUNIT_ASSERT_EQUAL(string(TEST_DESCRIPTION).size(),
description.description.size());
CPPUNIT_ASSERT_EQUAL(string(TEST_DESCRIPTION), description.description);
}
void CheckMalformedParameterDescription(
const ResponseStatus &status,
const ola::rdm::ParameterDescriptor &description) {
CPPUNIT_ASSERT_EQUAL(ola::rdm::ResponseStatus::MALFORMED_RESPONSE,
status.ResponseType());
(void) description;
}
void CheckDeviceInfo(const ResponseStatus &status,
const ola::rdm::DeviceDescriptor &descriptor) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(1),
descriptor.protocol_version_high);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(0),
descriptor.protocol_version_low);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(2),
descriptor.device_model);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(3),
descriptor.product_category);
CPPUNIT_ASSERT_EQUAL(static_cast<uint32_t>(0x12345678),
descriptor.software_version);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(400),
descriptor.dmx_footprint);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(1),
descriptor.current_personality);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(2),
descriptor.personaility_count);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(12),
descriptor.dmx_start_address);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(10),
descriptor.sub_device_count);
CPPUNIT_ASSERT_EQUAL(static_cast<uint8_t>(4),
descriptor.sensor_count);
}
void CheckProductDetailList(const ResponseStatus &status,
const vector<uint16_t> &params) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), params.size());
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(0x5678), params[0]);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(0xfedc), params[1]);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(0xaa00), params[2]);
}
void CheckDMXStartAddress(const ResponseStatus &status,
uint16_t start_address) {
CheckResponseStatus(status);
CPPUNIT_ASSERT_EQUAL(static_cast<uint16_t>(44), start_address);
}
};
const char RDMAPITest::BROADCAST_ERROR[] = "Cannot send to broadcast address";
const char RDMAPITest::DEVICE_RANGE_ERROR[] = "Sub device must be <= 0x0200";
const char RDMAPITest::DEVICE_RANGE_BCAST_ERROR[] =
"Sub device must be <= 0x0200 or 0xffff";
const char RDMAPITest::TEST_DESCRIPTION[] = "This is a description";
void RDMAPITest::tearDown() {
m_impl.Verify();
}
CPPUNIT_TEST_SUITE_REGISTRATION(RDMAPITest);
/*
* Test the proxied commands work.
*/
void RDMAPITest::testProxyCommands() {
string error;
// get proxied device count
CPPUNIT_ASSERT(!m_api.GetProxiedDeviceCount(
UNIVERSE,
m_bcast_uid,
NewSingleCallback(this, &RDMAPITest::CheckProxiedDeviceCount),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetProxiedDeviceCount(
UNIVERSE,
m_group_uid,
NewSingleCallback(this, &RDMAPITest::CheckProxiedDeviceCount),
&error));
CheckForBroadcastError(&error);
struct {
uint16_t count;
uint8_t changed;
} count_response;
count_response.count = HostToNetwork(static_cast<uint16_t>(2));
count_response.changed = 0;
string s(reinterpret_cast<char*>(&count_response), sizeof(count_response));
m_impl.AddExpectedGet(s,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_PROXIED_DEVICE_COUNT);
CPPUNIT_ASSERT(m_api.GetProxiedDeviceCount(
UNIVERSE,
m_uid,
NewSingleCallback(this, &RDMAPITest::CheckProxiedDeviceCount),
&error));
// get proxied devices
CPPUNIT_ASSERT(!m_api.GetProxiedDevices(
UNIVERSE,
m_bcast_uid,
NewSingleCallback(this, &RDMAPITest::CheckProxiedDevices),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetProxiedDevices(
UNIVERSE,
m_bcast_uid,
NewSingleCallback(this, &RDMAPITest::CheckProxiedDevices),
&error));
CheckForBroadcastError(&error);
struct {
uint8_t uid1[UID::UID_SIZE];
uint8_t uid2[UID::UID_SIZE];
} uids_response;
m_test_uid1.Pack(uids_response.uid1, UID::UID_SIZE);
m_test_uid2.Pack(uids_response.uid2, UID::UID_SIZE);
string s2(reinterpret_cast<char*>(&uids_response), sizeof(uids_response));
m_impl.AddExpectedGet(s2,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_PROXIED_DEVICES);
CPPUNIT_ASSERT(m_api.GetProxiedDevices(
UNIVERSE,
m_uid,
NewSingleCallback(this, &RDMAPITest::CheckProxiedDevices),
&error));
}
/*
* test that network commands work
*/
void RDMAPITest::testNetworkCommands() {
string error;
// get comms status
CPPUNIT_ASSERT(!m_api.GetCommStatus(
UNIVERSE,
m_group_uid,
NewSingleCallback(this, &RDMAPITest::CheckCommsStatus),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetCommStatus(
UNIVERSE,
m_group_uid,
NewSingleCallback(this, &RDMAPITest::CheckCommsStatus),
&error));
CheckForBroadcastError(&error);
struct {
uint16_t short_message;
uint16_t length_mismatch;
uint16_t checksum_fail;
} comms_response;
comms_response.short_message = HostToNetwork(static_cast<uint16_t>(14));
comms_response.length_mismatch = HostToNetwork(static_cast<uint16_t>(187));
comms_response.checksum_fail = HostToNetwork(static_cast<uint16_t>(92));
string s(reinterpret_cast<char*>(&comms_response), sizeof(comms_response));
m_impl.AddExpectedGet(s,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_COMMS_STATUS);
CPPUNIT_ASSERT(m_api.GetCommStatus(
UNIVERSE,
m_uid,
NewSingleCallback(this, &RDMAPITest::CheckCommsStatus),
&error));
// clear comms status
m_impl.AddExpectedSet(UNIVERSE,
m_bcast_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_COMMS_STATUS);
CPPUNIT_ASSERT(m_api.ClearCommStatus(
UNIVERSE,
m_bcast_uid,
NewSingleCallback(this, &RDMAPITest::CheckWasBroadcast),
&error));
m_impl.AddExpectedSet(UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_COMMS_STATUS);
CPPUNIT_ASSERT(m_api.ClearCommStatus(
UNIVERSE,
m_uid,
NewSingleCallback(this, &RDMAPITest::CheckResponseStatus),
&error));
// TODO(simon): test status message here
// status id description
uint16_t status_id = 12;
CPPUNIT_ASSERT(!m_api.GetStatusIdDescription(
UNIVERSE,
m_bcast_uid,
status_id,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetStatusIdDescription(
UNIVERSE,
m_bcast_uid,
status_id,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
m_impl.AddExpectedGet(string(TEST_DESCRIPTION),
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_STATUS_ID_DESCRIPTION);
CPPUNIT_ASSERT(m_api.GetStatusIdDescription(
UNIVERSE,
m_uid,
status_id,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
// clear status id
uint16_t sub_device = 3;
m_impl.AddExpectedSet(UNIVERSE,
m_bcast_uid,
sub_device,
ola::rdm::PID_CLEAR_STATUS_ID);
CPPUNIT_ASSERT(m_api.ClearStatusId(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckWasBroadcast),
&error));
m_impl.AddExpectedSet(UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_CLEAR_STATUS_ID);
CPPUNIT_ASSERT(m_api.ClearStatusId(
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
NewSingleCallback(this, &RDMAPITest::CheckResponseStatus),
&error));
// TODO(simon): add sub device reporting threshold here
}
/*
* Test RDM Information commands work correctly
*/
void RDMAPITest::testRDMInformation() {
string error;
// supported params
struct {
uint16_t param1;
uint16_t param2;
uint16_t param3;
} pid_list;
pid_list.param1 = HostToNetwork(static_cast<uint16_t>(0x1234));
pid_list.param2 = HostToNetwork(static_cast<uint16_t>(0xabcd));
pid_list.param3 = HostToNetwork(static_cast<uint16_t>(0x00aa));
uint16_t sub_device = 1;
CPPUNIT_ASSERT(!m_api.GetSupportedParameters(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckSupportedParams),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetSupportedParameters(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckSupportedParams),
&error));
CheckForBroadcastError(&error);
string s(reinterpret_cast<char*>(&pid_list), sizeof(pid_list));
m_impl.AddExpectedGet(s,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_SUPPORTED_PARAMETERS);
CPPUNIT_ASSERT(m_api.GetSupportedParameters(
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
NewSingleCallback(this, &RDMAPITest::CheckSupportedParams),
&error));
// parameter description
uint16_t pid = 16;
CPPUNIT_ASSERT(!m_api.GetParameterDescription(
UNIVERSE,
m_bcast_uid,
pid,
NewSingleCallback(this, &RDMAPITest::CheckMalformedParameterDescription),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetParameterDescription(
UNIVERSE,
m_bcast_uid,
pid,
NewSingleCallback(this, &RDMAPITest::CheckMalformedParameterDescription),
&error));
CheckForBroadcastError(&error);
s = "";
m_impl.AddExpectedGet(s,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_PARAMETER_DESCRIPTION);
CPPUNIT_ASSERT(m_api.GetParameterDescription(
UNIVERSE,
m_uid,
pid,
NewSingleCallback(this, &RDMAPITest::CheckMalformedParameterDescription),
&error));
struct param_info_s {
uint16_t pid;
uint8_t pdl_size;
uint8_t data_type;
uint8_t command_class;
uint8_t type;
uint8_t unit;
uint8_t prefix;
uint32_t min_value;
uint32_t max_value;
uint32_t default_value;
char label[32];
} __attribute__((packed));
struct param_info_s param_info;
param_info.pid = HostToNetwork(static_cast<uint16_t>(0x1234));
param_info.pdl_size = 10;
param_info.data_type = ola::rdm::DS_UNSIGNED_DWORD;
param_info.command_class = ola::rdm::CC_GET;
param_info.type = 0;
param_info.unit = ola::rdm::UNITS_METERS;
param_info.prefix = ola::rdm::PREFIX_KILO;
param_info.min_value = HostToNetwork(static_cast<uint32_t>(0));
param_info.max_value = HostToNetwork(static_cast<uint32_t>(200000));
param_info.default_value = HostToNetwork(static_cast<uint32_t>(1000));
strncpy(param_info.label, TEST_DESCRIPTION, sizeof(param_info.label));
string s2(reinterpret_cast<char*>(&param_info),
sizeof(param_info) - sizeof(param_info.label) +
strlen(TEST_DESCRIPTION));
m_impl.AddExpectedGet(s2,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_PARAMETER_DESCRIPTION);
CPPUNIT_ASSERT(m_api.GetParameterDescription(
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
NewSingleCallback(this, &RDMAPITest::CheckParameterDescription),
&error));
}
/*
* Check that the product information commands work correctly
*/
void RDMAPITest::testProductInformation() {
string error;
uint16_t sub_device = 1;
// device info
struct device_info_s {
uint8_t version_high;
uint8_t version_low;
uint16_t model;
uint16_t product_category;
uint32_t software_version;
uint16_t dmx_footprint;
uint8_t current_personality;
uint8_t personaility_count;
uint16_t dmx_start_address;
uint16_t sub_device_count;
uint8_t sensor_count;
} __attribute__((packed));
struct device_info_s device_info;
device_info.version_high = 1;
device_info.version_low = 0;
device_info.model = HostToNetwork(static_cast<uint16_t>(2));
device_info.product_category = HostToNetwork(static_cast<uint16_t>(3));
device_info.software_version = HostToNetwork(
static_cast<uint32_t>(0x12345678));
device_info.dmx_footprint = HostToNetwork(static_cast<uint16_t>(400));
device_info.current_personality = 1;
device_info.personaility_count = 2;
device_info.dmx_start_address = HostToNetwork(static_cast<uint16_t>(12));
device_info.sub_device_count = HostToNetwork(static_cast<uint16_t>(10));
device_info.sensor_count = 4;
CPPUNIT_ASSERT(!m_api.GetDeviceInfo(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckDeviceInfo),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetDeviceInfo(
UNIVERSE,
m_group_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckDeviceInfo),
&error));
CheckForBroadcastError(&error);
string s(reinterpret_cast<char*>(&device_info), sizeof(device_info));
m_impl.AddExpectedGet(s,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_DEVICE_INFO);
CPPUNIT_ASSERT(m_api.GetDeviceInfo(
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
NewSingleCallback(this, &RDMAPITest::CheckDeviceInfo),
&error));
// product detail id list
struct {
uint16_t detail1;
uint16_t detail2;
uint16_t detail3;
} detail_list;
detail_list.detail1 = HostToNetwork(static_cast<uint16_t>(0x5678));
detail_list.detail2 = HostToNetwork(static_cast<uint16_t>(0xfedc));
detail_list.detail3 = HostToNetwork(static_cast<uint16_t>(0xaa00));
CPPUNIT_ASSERT(!m_api.GetProductDetailIdList(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckProductDetailList),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetProductDetailIdList(
UNIVERSE,
m_group_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckProductDetailList),
&error));
CheckForBroadcastError(&error);
string s2(reinterpret_cast<char*>(&detail_list), sizeof(detail_list));
m_impl.AddExpectedGet(s2,
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
ola::rdm::PID_PRODUCT_DETAIL_ID_LIST);
CPPUNIT_ASSERT(m_api.GetProductDetailIdList(
UNIVERSE,
m_uid,
ola::rdm::ROOT_RDM_DEVICE,
NewSingleCallback(this, &RDMAPITest::CheckProductDetailList),
&error));
// device model description
CPPUNIT_ASSERT(!m_api.GetDeviceModelDescription(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetDeviceModelDescription(
UNIVERSE,
m_group_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
m_impl.AddExpectedGet(string(TEST_DESCRIPTION),
UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_DEVICE_MODEL_DESCRIPTION);
CPPUNIT_ASSERT(m_api.GetDeviceModelDescription(
UNIVERSE,
m_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
// manufacturer label
CPPUNIT_ASSERT(!m_api.GetManufacturerLabel(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetManufacturerLabel(
UNIVERSE,
m_group_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
m_impl.AddExpectedGet(string(TEST_DESCRIPTION),
UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_MANUFACTURER_LABEL);
CPPUNIT_ASSERT(m_api.GetManufacturerLabel(
UNIVERSE,
m_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
// get device label
CPPUNIT_ASSERT(!m_api.GetDeviceLabel(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetDeviceLabel(
UNIVERSE,
m_group_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
m_impl.AddExpectedGet(string(TEST_DESCRIPTION),
UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_DEVICE_LABEL);
CPPUNIT_ASSERT(m_api.GetDeviceLabel(
UNIVERSE,
m_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
// set device label
s = TEST_DESCRIPTION;
m_impl.AddExpectedSet(UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_DEVICE_LABEL,
reinterpret_cast<const uint8_t*>(s.data()),
s.size());
CPPUNIT_ASSERT(m_api.SetDeviceLabel(
UNIVERSE,
m_uid,
sub_device,
s,
NewSingleCallback(this, &RDMAPITest::CheckResponseStatus),
&error));
// check we can bcast
m_impl.AddExpectedSet(UNIVERSE,
m_bcast_uid,
ola::rdm::ALL_RDM_SUBDEVICES,
ola::rdm::PID_DEVICE_LABEL,
reinterpret_cast<const uint8_t*>(s.data()),
s.size());
CPPUNIT_ASSERT(m_api.SetDeviceLabel(
UNIVERSE,
m_bcast_uid,
ola::rdm::ALL_RDM_SUBDEVICES,
s,
NewSingleCallback(this, &RDMAPITest::CheckWasBroadcast),
&error));
m_impl.AddExpectedSet(UNIVERSE,
m_group_uid,
ola::rdm::ALL_RDM_SUBDEVICES,
ola::rdm::PID_DEVICE_LABEL,
reinterpret_cast<const uint8_t*>(s.data()),
s.size());
CPPUNIT_ASSERT(m_api.SetDeviceLabel(
UNIVERSE,
m_group_uid,
ola::rdm::ALL_RDM_SUBDEVICES,
s,
NewSingleCallback(this, &RDMAPITest::CheckWasBroadcast),
&error));
// check out of range sub devices fail
CPPUNIT_ASSERT(!m_api.SetDeviceLabel(
UNIVERSE,
m_group_uid,
0x0201,
s,
NewSingleCallback(this, &RDMAPITest::CheckResponseStatus),
&error));
CheckForDeviceRangeBcastError(&error);
// software version label
CPPUNIT_ASSERT(!m_api.GetSoftwareVersionLabel(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetSoftwareVersionLabel(
UNIVERSE,
m_group_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
m_impl.AddExpectedGet(string(TEST_DESCRIPTION),
UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_SOFTWARE_VERSION_LABEL);
CPPUNIT_ASSERT(m_api.GetSoftwareVersionLabel(
UNIVERSE,
m_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
// Boot software label
CPPUNIT_ASSERT(!m_api.GetBootSoftwareVersionLabel(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetBootSoftwareVersionLabel(
UNIVERSE,
m_group_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
CheckForBroadcastError(&error);
m_impl.AddExpectedGet(string(TEST_DESCRIPTION),
UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_BOOT_SOFTWARE_VERSION_LABEL);
CPPUNIT_ASSERT(m_api.GetBootSoftwareVersionLabel(
UNIVERSE,
m_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckLabel),
&error));
}
/*
* Check that DMX commands work
*/
void RDMAPITest::testDmxSetup() {
string error;
uint16_t sub_device = 1;
// Check get start address
CPPUNIT_ASSERT(!m_api.GetDMXAddress(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckDMXStartAddress),
&error));
CheckForBroadcastError(&error);
CPPUNIT_ASSERT(!m_api.GetDMXAddress(
UNIVERSE,
m_bcast_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckDMXStartAddress),
&error));
CheckForBroadcastError(&error);
uint16_t start_address = HostToNetwork(static_cast<uint16_t>(44));
string s(reinterpret_cast<char*>(&start_address), sizeof(start_address));
m_impl.AddExpectedGet(s,
UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_DMX_START_ADDRESS);
CPPUNIT_ASSERT(m_api.GetDMXAddress(
UNIVERSE,
m_uid,
sub_device,
NewSingleCallback(this, &RDMAPITest::CheckDMXStartAddress),
&error));
// Check set start address
start_address = 64;
uint16_t address_data = HostToNetwork(start_address);
m_impl.AddExpectedSet(UNIVERSE,
m_uid,
sub_device,
ola::rdm::PID_DMX_START_ADDRESS,
reinterpret_cast<const uint8_t*>(&address_data),
sizeof(address_data));
CPPUNIT_ASSERT(m_api.SetDMXAddress(
UNIVERSE,
m_uid,
sub_device,
start_address,
NewSingleCallback(this, &RDMAPITest::CheckResponseStatus),
&error));
// check bcasts work
m_impl.AddExpectedSet(UNIVERSE,
m_bcast_uid,
ola::rdm::ALL_RDM_SUBDEVICES,
ola::rdm::PID_DMX_START_ADDRESS,
reinterpret_cast<const uint8_t*>(&address_data),
sizeof(address_data));
CPPUNIT_ASSERT(m_api.SetDMXAddress(
UNIVERSE,
m_bcast_uid,
ola::rdm::ALL_RDM_SUBDEVICES,
start_address,
NewSingleCallback(this, &RDMAPITest::CheckWasBroadcast),
&error));
m_impl.AddExpectedSet(UNIVERSE,
m_group_uid,
0x0200,
ola::rdm::PID_DMX_START_ADDRESS,
reinterpret_cast<const uint8_t*>(&address_data),
sizeof(address_data));
CPPUNIT_ASSERT(m_api.SetDMXAddress(
UNIVERSE,
m_group_uid,
0x0200,
start_address,
NewSingleCallback(this, &RDMAPITest::CheckWasBroadcast),
&error));
CPPUNIT_ASSERT(!m_api.SetDMXAddress(
UNIVERSE,
m_group_uid,
0x0201,
start_address,
NewSingleCallback(this, &RDMAPITest::CheckWasBroadcast),
&error));
CheckForDeviceRangeBcastError(&error);
}