Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* add RDM support for the Enttec USB Pro

  • Loading branch information...
commit 04417fa38bee20200eab383c95aba8f009bde030 1 parent c642e9c
@nomis52 nomis52 authored
View
375 plugins/usbpro/EnttecUsbProWidget.cpp
@@ -15,12 +15,13 @@
*
* EnttecUsbProWidget.h
* The Enttec USB Pro Widget
- * TODO(simon): implement RDM for this device - bug #146.
- * It doesn't do discovery onboard through which makes thing pretty difficult.
* Copyright (C) 2010 Simon Newton
*/
#include <string.h>
+#include <iostream>
+#include <string>
+#include <vector>
#include "ola/BaseTypes.h"
#include "ola/Logging.h"
#include "ola/rdm/RDMCommand.h"
@@ -40,14 +41,358 @@ using ola::rdm::UID;
using ola::rdm::UIDSet;
+const uint16_t EnttecUsbProWidget::ENTTEC_ESTA_ID = 0x454E;
+
/*
* New Enttec Usb Pro Device.
* This also works for the RDM Pro with the standard firmware loaded.
*/
EnttecUsbProWidgetImpl::EnttecUsbProWidgetImpl(
ola::thread::SchedulerInterface *scheduler,
- ola::network::ConnectedDescriptor *descriptor)
- : GenericUsbProWidget(scheduler, descriptor) {
+ ola::network::ConnectedDescriptor *descriptor,
+ uint16_t esta_id,
+ uint32_t serial)
+ : GenericUsbProWidget(scheduler, descriptor),
+ m_discovery_agent(this),
+ m_uid(esta_id ? esta_id : EnttecUsbProWidget::ENTTEC_ESTA_ID, serial),
+ m_transaction_number(0),
+ m_rdm_request_callback(NULL),
+ m_mute_callback(NULL),
+ m_unmute_callback(NULL),
+ m_branch_callback(NULL),
+ m_pending_request(NULL),
+ m_discovery_response(NULL),
+ m_discovery_response_size(0) {
+}
+
+
+/**
+ * Stop this widget
+ */
+void EnttecUsbProWidgetImpl::Stop() {
+ m_discovery_agent.Abort();
+ GenericStop();
+}
+
+
+/**
+ * Send an RDM Request.
+ */
+void EnttecUsbProWidgetImpl::SendRDMRequest(
+ const ola::rdm::RDMRequest *request,
+ ola::rdm::RDMCallback *on_complete) {
+ std::vector<string> packets;
+ if (m_rdm_request_callback) {
+ OLA_WARN << "Previous request hasn't completed yet, dropping request";
+ on_complete->Run(ola::rdm::RDM_FAILED_TO_SEND, NULL, packets);
+ delete request;
+ return;
+ }
+
+ // Prepare the buffer for the RDM data including the start code.
+ unsigned int rdm_size = request->Size();
+ uint8_t *data = new uint8_t[rdm_size + 1];
+ data[0] = RDMCommand::START_CODE;
+
+ unsigned int this_transaction_number = m_transaction_number++;
+ unsigned int port_id = 1;
+
+ bool r = request->PackWithControllerParams(&data[1],
+ &rdm_size,
+ m_uid,
+ this_transaction_number,
+ port_id);
+
+ if (!r) {
+ OLA_WARN << "Failed to pack message, dropping request";
+ delete[] data;
+ delete request;
+ on_complete->Run(ola::rdm::RDM_FAILED_TO_SEND, NULL, packets);
+ return;
+ }
+
+ m_rdm_request_callback = on_complete;
+ // re-write the request so it appears to originate from this widget.
+ m_pending_request = request->DuplicateWithControllerParams(
+ m_uid,
+ this_transaction_number,
+ port_id);
+ delete request;
+ if (!SendMessage(RDM_PACKET, data, rdm_size + 1)) {
+ m_rdm_request_callback = NULL;
+ m_pending_request = NULL;
+ delete[] data;
+ delete request;
+ on_complete->Run(ola::rdm::RDM_FAILED_TO_SEND, NULL, packets);
+ return;
+ }
+ delete[] data;
+}
+
+
+/**
+ * Start full discovery for this widget.
+ */
+void EnttecUsbProWidgetImpl::RunFullDiscovery(
+ ola::rdm::RDMDiscoveryCallback *callback) {
+ OLA_INFO << "Full discovery triggered";
+ m_discovery_agent.StartFullDiscovery(
+ ola::NewSingleCallback(this,
+ &EnttecUsbProWidgetImpl::DiscoveryComplete,
+ callback));
+}
+
+
+/**
+ * Start incremental discovery for this widget
+ */
+void EnttecUsbProWidgetImpl::RunIncrementalDiscovery(
+ ola::rdm::RDMDiscoveryCallback *callback) {
+ OLA_INFO << "Incremental discovery triggered";
+ m_discovery_agent.StartIncrementalDiscovery(
+ ola::NewSingleCallback(this,
+ &EnttecUsbProWidgetImpl::DiscoveryComplete,
+ callback));
+}
+
+
+/**
+ * Mute a responder
+ * @param target the UID to mute
+ * @param MuteDeviceCallback the callback to run once the mute request
+ * completes.
+ */
+void EnttecUsbProWidgetImpl::MuteDevice(const ola::rdm::UID &target,
+ MuteDeviceCallback *mute_complete) {
+ ola::rdm::MuteRequest mute_request(
+ m_uid,
+ target,
+ m_transaction_number++);
+ unsigned int rdm_length = mute_request.Size();
+ uint8_t *data = new uint8_t[rdm_length + 1]; // inc start code
+ data[0] = RDMCommand::START_CODE;
+ mute_request.Pack(&data[1], &rdm_length);
+ OLA_INFO << "Muting " << target;
+ bool r = SendMessage(RDM_PACKET, data, rdm_length + 1);
+ if (r)
+ m_mute_callback = mute_complete;
+ else
+ mute_complete->Run(false);
+ delete[] data;
+}
+
+
+/**
+ * Unmute all responders
+ * @param UnMuteDeviceCallback the callback to run once the unmute request
+ * completes.
+ */
+void EnttecUsbProWidgetImpl::UnMuteAll(UnMuteDeviceCallback *unmute_complete) {
+ ola::rdm::UnMuteRequest unmute_request(
+ m_uid,
+ ola::rdm::UID::AllDevices(),
+ m_transaction_number++);
+
+ unsigned int rdm_length = unmute_request.Size();
+ uint8_t *data = new uint8_t[rdm_length + 1]; // inc start code
+ data[0] = RDMCommand::START_CODE;
+ unmute_request.Pack(&data[1], &rdm_length);
+ OLA_INFO << "Un-muting all devices";
+ SendMessage(RDM_PACKET, data, rdm_length + 1);
+ m_unmute_callback = unmute_complete;
+ delete[] data;
+}
+
+
+/**
+ * Send a Discovery Unique Branch
+ */
+void EnttecUsbProWidgetImpl::Branch(const ola::rdm::UID &lower,
+ const ola::rdm::UID &upper,
+ BranchCallback *callback) {
+ ola::rdm::DiscoveryUniqueBranchRequest branch_request(
+ m_uid,
+ lower,
+ upper,
+ m_transaction_number++);
+
+ unsigned int rdm_length = branch_request.Size();
+ uint8_t *data = new uint8_t[rdm_length + 1]; // inc start code
+ data[0] = RDMCommand::START_CODE;
+ branch_request.Pack(&data[1], &rdm_length);
+ OLA_INFO << "Sending DUB packet: " << lower << " - " << upper;
+ SendMessage(RDM_DISCOVERY_PACKET,
+ data,
+ rdm_length + 1);
+ m_branch_callback = callback;
+ delete[] data;
+}
+
+
+/*
+ * Handle a message received from the widget
+ */
+void EnttecUsbProWidgetImpl::HandleMessage(uint8_t label,
+ const uint8_t *data,
+ unsigned int length) {
+ switch (label) {
+ case RDM_PACKET:
+ // The widget isn't supposed to send frames with an id of 7, these are
+ // just sent from the host to the widget.
+ OLA_WARN <<
+ "Enttec Pro received an RDM frame (id 7), this shouldn't happen.";
+ break;
+ case RDM_TIMEOUT_PACKET:
+ HandleRDMTimeout(length);
+ break;
+ case GenericUsbProWidget::RECEIVED_DMX_LABEL:
+ HandleIncommingDataMessage(data, length);
+ break;
+ default:
+ GenericUsbProWidget::HandleMessage(label, data, length);
+ }
+}
+
+
+/**
+ * Called to indicate the completion of an RDM request.
+ * According to the spec:
+ * The timeout message will follow the RDM discovery reply message, whether or
+ * not the reply is partial or complete.
+ * The timeout message will follow the RDM reply message (GET or SET), only
+ * when the reply is incomplete or unrecognizable.
+ *
+ * Experiments suggest that sending another RDM message before this 'timeout'
+ * is received results in Bad Things Happening.
+ *
+ * The length of this message should be 0.
+ */
+void EnttecUsbProWidgetImpl::HandleRDMTimeout(unsigned int length) {
+ if (length)
+ OLA_WARN << "Strange RDM timeout message, length was " << length;
+
+ // check what operation we were waiting on
+ if (m_unmute_callback) {
+ UnMuteDeviceCallback *callback = m_unmute_callback;
+ m_unmute_callback = NULL;
+ callback->Run();
+ } else if (m_mute_callback) {
+ MuteDeviceCallback *callback = m_mute_callback;
+ m_mute_callback = NULL;
+ OLA_INFO << "Failed to mute device";
+ callback->Run(false);
+ } else if (m_branch_callback) {
+ BranchCallback *callback = m_branch_callback;
+ m_branch_callback = NULL;
+ callback->Run(m_discovery_response, m_discovery_response_size);
+ if (m_discovery_response) {
+ delete[] m_discovery_response;
+ m_discovery_response = NULL;
+ m_discovery_response_size = 0;
+ }
+ } else if (m_rdm_request_callback && m_pending_request) {
+ ola::rdm::rdm_response_code code = (
+ m_pending_request->DestinationUID().IsBroadcast() ?
+ ola::rdm::RDM_WAS_BROADCAST :
+ ola::rdm::RDM_TIMEOUT);
+ ola::rdm::RDMCallback *callback = m_rdm_request_callback;
+ m_rdm_request_callback = NULL;
+ delete m_pending_request;
+ m_pending_request = NULL;
+ std::vector<std::string> packets;
+ callback->Run(code, NULL, packets);
+ }
+}
+
+
+/**
+ * Handle an incomming frame.
+ * @param data the incoming data buffer
+ * @param length the length of the data buffer.
+ *
+ * The first byte is a status code: 0: good, non-0: bad
+ * The second byte is the start code
+ * The remaining bytes are the actual data.
+ */
+void EnttecUsbProWidgetImpl::HandleIncommingDataMessage(
+ const uint8_t *data,
+ unsigned int length) {
+ // if we're not waiting for a DUB response, and this isn't an RDM frame, then
+ // let the super class handle it.
+ if (m_branch_callback == NULL && length >= 2 &&
+ data[1] != ola::rdm::RDMCommand::START_CODE) {
+ HandleDMX(data, length);
+ return;
+ }
+
+ // It's not clear what happens if we get an overrun on an RDM response.
+ // Do we still get the timeout message or is this the only response?
+ // I need to check with Nic.
+ if (data[0]) {
+ OLA_WARN << "Incomming frame corrupted";
+ return;
+ }
+
+ // skip over the status bit
+ data++;
+ length--;
+
+ if (m_branch_callback) {
+ // discovery responses are *always* followed by the timeout message and
+ // it's important that we wait for this before sending the next command
+ if (m_discovery_response) {
+ OLA_WARN <<
+ "multiple discovery responses received, ignoring all but the first.";
+ return;
+ }
+ uint8_t *response_data = new uint8_t[length];
+ memcpy(response_data, data, length);
+ m_discovery_response = response_data;
+ m_discovery_response_size = length;
+ } else if (m_mute_callback) {
+ // we take any response as a mute acknowledgment here, which isn't great,
+ // but it seems to work.
+ MuteDeviceCallback *callback = m_mute_callback;
+ m_mute_callback = NULL;
+ OLA_INFO << "Probably muted device";
+ callback->Run(true);
+ } else if (m_rdm_request_callback) {
+ ola::rdm::RDMCallback *callback = m_rdm_request_callback;
+ m_rdm_request_callback = NULL;
+ const ola::rdm::RDMRequest *request = m_pending_request;
+ m_pending_request = NULL;
+
+ std::vector<std::string> packets;
+ string packet;
+ packet.assign(reinterpret_cast<const char*>(data + 1), length - 1);
+ packets.push_back(packet);
+
+ // try to inflate
+ ola::rdm::rdm_response_code response_code;
+ ola::rdm::RDMResponse *response = ola::rdm::RDMResponse::InflateFromData(
+ packet,
+ &response_code,
+ request);
+ callback->Run(response_code, response, packets);
+ delete request;
+ }
+}
+
+
+/**
+ * Called when the discovery process finally completes
+ * @param callback the callback passed to StartFullDiscovery or
+ * StartIncrementalDiscovery that we should execute.
+ * @param status true if discovery worked, false otherwise
+ * @param uids the UIDSet of UIDs that were found.
+ */
+void EnttecUsbProWidgetImpl::DiscoveryComplete(
+ ola::rdm::RDMDiscoveryCallback *callback,
+ bool,
+ const UIDSet &uids) {
+ OLA_DEBUG << "Enttec Pro discovery complete: " << uids;
+ if (callback)
+ callback->Run(uids);
}
@@ -57,14 +402,20 @@ EnttecUsbProWidgetImpl::EnttecUsbProWidgetImpl(
EnttecUsbProWidget::EnttecUsbProWidget(
ola::thread::SchedulerInterface *scheduler,
ola::network::ConnectedDescriptor *descriptor,
- unsigned int queue_size)
- : m_impl(scheduler, descriptor) {
- // m_controller(&m_impl, queue_size) {
- /*
- m_impl.SetDiscoveryCallback(
- NewCallback(this, &UsbProWidget::ResumeRDMCommands));
- */
- (void) queue_size;
+ uint16_t esta_id,
+ uint32_t serial,
+ unsigned int queue_size) {
+ m_impl = new EnttecUsbProWidgetImpl(scheduler, descriptor, esta_id, serial);
+ m_controller = new ola::rdm::DiscoverableQueueingRDMController(m_impl,
+ queue_size);
+}
+
+
+EnttecUsbProWidget::~EnttecUsbProWidget() {
+ // delete the controller after the impl because the controller owns the
+ // callback
+ delete m_impl;
+ delete m_controller;
}
} // usbpro
} // plugin
View
142 plugins/usbpro/EnttecUsbProWidget.h
@@ -26,137 +26,149 @@
#include "ola/Callback.h"
#include "ola/DmxBuffer.h"
#include "ola/thread/SchedulerInterface.h"
+#include "ola/rdm/DiscoveryAgent.h"
#include "ola/rdm/QueueingRDMController.h"
#include "ola/rdm/RDMControllerInterface.h"
#include "ola/rdm/UIDSet.h"
#include "plugins/usbpro/GenericUsbProWidget.h"
+class EnttecUsbProWidgetTest;
+
namespace ola {
namespace plugin {
namespace usbpro {
+
/*
* An Enttec DMX USB PRO Widget implementation. We separate the Widget from the
- * implementation so we can leverage the QueueingRDMController when we add RDM
- * support one day.
+ * implementation so we can use the QueueingRDMController.
*/
-class EnttecUsbProWidgetImpl: public GenericUsbProWidget {
- // : public ola::rdm::RDMControllerInterface {
+class EnttecUsbProWidgetImpl
+ : public GenericUsbProWidget,
+ public ola::rdm::DiscoverableRDMControllerInterface,
+ public ola::rdm::DiscoveryTargetInterface {
public:
EnttecUsbProWidgetImpl(ola::thread::SchedulerInterface *scheduler,
- ola::network::ConnectedDescriptor *descriptor);
- ~EnttecUsbProWidgetImpl() {}
+ ola::network::ConnectedDescriptor *descriptor,
+ uint16_t esta_id,
+ uint32_t serial);
+ ~EnttecUsbProWidgetImpl() { Stop(); }
- void Stop() { GenericStop(); }
+ void Stop();
- /*
- * TODO(simon): add RDM support
+ // the following are from DiscoverableRDMControllerInterface
void SendRDMRequest(const ola::rdm::RDMRequest *request,
ola::rdm::RDMCallback *on_complete);
- void bool RunFullDiscovery(RDMDiscoveryCallback *callback);
- void RunIncrementalDiscovery(RDMDiscoveryCallback *callback);
- bool CheckDiscoveryStatus();
- */
+ void RunFullDiscovery(ola::rdm::RDMDiscoveryCallback *callback);
+ void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback);
+
+ // The following are the implementation of DiscoveryTargetInterface
+ void MuteDevice(const ola::rdm::UID &target,
+ MuteDeviceCallback *mute_complete);
+ void UnMuteAll(UnMuteDeviceCallback *unmute_complete);
+ void Branch(const ola::rdm::UID &lower,
+ const ola::rdm::UID &upper,
+ BranchCallback *callback);
+
+ // We override handle message to catch the incomming RDM frames
+ void HandleMessage(uint8_t label,
+ const uint8_t *data,
+ unsigned int length);
private:
- ola::thread::SchedulerInterface *m_scheduler;
- // ola::thread::timeout_id m_rdm_timeout_id;
- /*
- ola::Callback1<void, const ola::rdm::UIDSet&> *m_uid_set_callback;
- ola::Callback0<void> *m_discovery_callback;
+ ola::rdm::DiscoveryAgent m_discovery_agent;
+ const ola::rdm::UID m_uid;
+ uint8_t m_transaction_number;
ola::rdm::RDMCallback *m_rdm_request_callback;
+ MuteDeviceCallback *m_mute_callback;
+ UnMuteDeviceCallback *m_unmute_callback;
+ BranchCallback *m_branch_callback;
const ola::rdm::RDMRequest *m_pending_request;
- uint8_t m_transaction_number;
-
- bool InDiscoveryMode() const;
- bool SendDiscoveryStart();
- bool SendDiscoveryStat();
- void FetchNextUID();
- void DispatchRequest(const ola::rdm::RDMRequest *request,
- ola::rdm::RDMCallback *callback);
- void DispatchQueuedGet(const ola::rdm::RDMRequest* request,
- ola::rdm::RDMCallback *callback);
- void StopDiscovery();
-
- void HandleRemoteRDMResponse(uint8_t return_code,
- const uint8_t *data,
- unsigned int length);
- */
+ // holds the discovery response while we're waiting for the timeout message
+ const uint8_t *m_discovery_response;
+ unsigned int m_discovery_response_size;
+
+ void HandleRDMTimeout(unsigned int length);
+ void HandleIncommingDataMessage(const uint8_t *data, unsigned int length);
+ void DiscoveryComplete(ola::rdm::RDMDiscoveryCallback *callback,
+ bool status,
+ const ola::rdm::UIDSet &uids);
+
+ static const uint8_t RDM_PACKET = 7;
+ static const uint8_t RDM_TIMEOUT_PACKET = 12;
+ static const uint8_t RDM_DISCOVERY_PACKET = 11;
};
/*
- * An Usb Pro Widget
+ * An Enttec Usb Pro Widget
*/
-class EnttecUsbProWidget: public SerialWidgetInterface {
+class EnttecUsbProWidget: public SerialWidgetInterface,
+ public ola::rdm::DiscoverableRDMControllerInterface {
public:
EnttecUsbProWidget(ola::thread::SchedulerInterface *scheduler,
ola::network::ConnectedDescriptor *descriptor,
+ uint16_t esta_id,
+ uint32_t serial,
unsigned int queue_size = 20);
- ~EnttecUsbProWidget() {}
+ ~EnttecUsbProWidget();
- void Stop() { m_impl.Stop(); }
+ void Stop() { m_impl->Stop(); }
bool SendDMX(const DmxBuffer &buffer) {
- return m_impl.SendDMX(buffer);
+ return m_impl->SendDMX(buffer);
}
const DmxBuffer &FetchDMX() const {
- return m_impl.FetchDMX();
+ return m_impl->FetchDMX();
}
void SetDMXCallback(
ola::Callback0<void> *callback) {
- m_impl.SetDMXCallback(callback);
+ m_impl->SetDMXCallback(callback);
}
bool ChangeToReceiveMode(bool change_only) {
- return m_impl.ChangeToReceiveMode(change_only);
+ return m_impl->ChangeToReceiveMode(change_only);
}
void GetParameters(usb_pro_params_callback *callback) {
- m_impl.GetParameters(callback);
+ m_impl->GetParameters(callback);
}
bool SetParameters(uint8_t break_time,
uint8_t mab_time,
uint8_t rate) {
- return m_impl.SetParameters(break_time, mab_time, rate);
- }
-
- /*
- void SetUIDListCallback(
- ola::Callback1<void, const ola::rdm::UIDSet&> *callback) {
- m_impl.SetUIDListCallback(callback);
+ return m_impl->SetParameters(break_time, mab_time, rate);
}
void SendRDMRequest(const ola::rdm::RDMRequest *request,
ola::rdm::RDMCallback *on_complete) {
- m_controller.SendRDMRequest(request, on_complete);
+ m_controller->SendRDMRequest(request, on_complete);
}
- bool RunFullDiscovery(RDMDiscoveryCallback *callback) {
- m_controller.RunFullDiscovery(callback);
+ void RunFullDiscovery(ola::rdm::RDMDiscoveryCallback *callback) {
+ m_impl->RunFullDiscovery(callback);
}
- bool RunIncrementalDiscovery(RDMDiscoveryCallback *callback) {
- m_controller.RunIncrementalDiscovery(callback);
+ void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback) {
+ m_impl->RunIncrementalDiscovery(callback);
}
- */
ola::network::ConnectedDescriptor *GetDescriptor() const {
- return m_impl.GetDescriptor();
+ return m_impl->GetDescriptor();
}
- private:
- EnttecUsbProWidgetImpl m_impl;
- // ola::rdm::QueueingRDMController m_controller;
+ static const uint16_t ENTTEC_ESTA_ID;
- /*
- void ResumeRDMCommands() {
- m_controller.Resume();
- }
- */
+ // the tests access the implementation directly.
+ friend class ::EnttecUsbProWidgetTest;
+
+ private:
+ // we need to control the order of construction & destruction here so these
+ // are pointers.
+ EnttecUsbProWidgetImpl *m_impl;
+ ola::rdm::QueueingRDMController *m_controller;
};
} // usbpro
} // plugin
View
488 plugins/usbpro/EnttecUsbProWidgetTest.cpp
@@ -20,15 +20,29 @@
#include <cppunit/extensions/HelperMacros.h>
#include <memory>
+#include <string>
+#include <vector>
#include "ola/Callback.h"
#include "ola/DmxBuffer.h"
#include "ola/Logging.h"
+#include "ola/rdm/UID.h"
#include "plugins/usbpro/EnttecUsbProWidget.h"
#include "plugins/usbpro/CommonWidgetTest.h"
+using ola::plugin::usbpro::EnttecUsbProWidget;
+using ola::rdm::DiscoveryUniqueBranchRequest;
+using ola::rdm::GetResponseFromData;
+using ola::rdm::MuteRequest;
+using ola::rdm::RDMDiscoveryCommand;
+using ola::rdm::RDMRequest;
+using ola::rdm::RDMResponse;
+using ola::rdm::UID;
+using ola::rdm::UnMuteRequest;
using std::auto_ptr;
+using std::string;
+using std::vector;
using ola::plugin::usbpro::usb_pro_parameters;
@@ -37,6 +51,10 @@ class EnttecUsbProWidgetTest: public CommonWidgetTest {
CPPUNIT_TEST(testParams);
CPPUNIT_TEST(testReceiveDMX);
CPPUNIT_TEST(testChangeMode);
+ CPPUNIT_TEST(testSendRDMRequest);
+ CPPUNIT_TEST(testMuteDevice);
+ CPPUNIT_TEST(testUnMuteAll);
+ CPPUNIT_TEST(testBranch);
CPPUNIT_TEST_SUITE_END();
public:
@@ -45,9 +63,39 @@ class EnttecUsbProWidgetTest: public CommonWidgetTest {
void testParams();
void testReceiveDMX();
void testChangeMode();
+ void testSendRDMRequest();
+ void testMuteDevice();
+ void testUnMuteAll();
+ void testBranch();
private:
- auto_ptr<ola::plugin::usbpro::EnttecUsbProWidget> m_widget;
+ auto_ptr<EnttecUsbProWidget> m_widget;
+ uint8_t m_transaction_number;
+ ola::rdm::rdm_response_code m_received_code;
+
+ const RDMRequest *NewRequest(const UID &destination,
+ const uint8_t *data = NULL,
+ unsigned int length = 0);
+ uint8_t *PackRDMRequest(const RDMRequest *request, unsigned int *size);
+ uint8_t *PackDiscoveryReqest(const RDMDiscoveryCommand *request,
+ unsigned int *size);
+ uint8_t *PackRDMResponse(const RDMResponse *response, unsigned int *size);
+ void ValidateResponse(ola::rdm::rdm_response_code code,
+ const ola::rdm::RDMResponse *response,
+ const vector<string> &packets);
+ void ValidateStatus(ola::rdm::rdm_response_code expected_code,
+ vector<string> expected_packets,
+ ola::rdm::rdm_response_code code,
+ const ola::rdm::RDMResponse *response,
+ const vector<string> &packets);
+ void ValidateMuteStatus(bool expected,
+ bool actual);
+ void ValidateBranchStatus(const uint8_t *expected_data,
+ unsigned int length,
+ const uint8_t *actual_data,
+ unsigned int actual_length);
+ void SendResponseAndTimeout(const uint8_t *response_data,
+ unsigned int length);
void Terminate() { m_ss.Terminate(); }
void ValidateParams(bool status, const usb_pro_parameters &params);
@@ -55,27 +103,226 @@ class EnttecUsbProWidgetTest: public CommonWidgetTest {
bool m_got_dmx;
+ static const UID BCAST_DESTINATION;
+ static const UID DESTINATION;
+ static const UID SOURCE;
+ static const uint16_t ESTA_ID = 0x00a1;
+ static const uint32_t SERIAL_NUMBER = 0x01020304;
static const uint8_t CHANGE_MODE_LABEL = 8;
static const uint8_t CHANGE_OF_STATE_LABEL = 9;
static const uint8_t GET_PARAM_LABEL = 3;
+ static const uint8_t RDM_DISCOVERY_PACKET = 11;
+ static const uint8_t RDM_PACKET = 7;
+ static const uint8_t RDM_TIMEOUT_PACKET = 12;
static const uint8_t RECEIVE_DMX_LABEL = 5;
static const uint8_t SET_PARAM_LABEL = 4;
+ static const uint8_t TEST_RDM_DATA[];
static const unsigned int FOOTER_SIZE = 1;
static const unsigned int HEADER_SIZE = 4;
};
+const UID EnttecUsbProWidgetTest::DESTINATION(ESTA_ID, SERIAL_NUMBER);
+const UID EnttecUsbProWidgetTest::BCAST_DESTINATION(ESTA_ID, 0xffffffff);
+const UID EnttecUsbProWidgetTest::SOURCE(EnttecUsbProWidget::ENTTEC_ESTA_ID,
+ 1);
+const uint8_t EnttecUsbProWidgetTest::TEST_RDM_DATA[] =
+ { 0x5a, 0x5a, 0x5a, 0x5a};
+
CPPUNIT_TEST_SUITE_REGISTRATION(EnttecUsbProWidgetTest);
void EnttecUsbProWidgetTest::setUp() {
CommonWidgetTest::setUp();
m_widget.reset(
- new ola::plugin::usbpro::EnttecUsbProWidget(&m_ss, &m_descriptor));
+ new EnttecUsbProWidget(
+ &m_ss,
+ &m_descriptor,
+ EnttecUsbProWidget::ENTTEC_ESTA_ID,
+ 1));
+ m_transaction_number = 0;
m_got_dmx = false;
}
+/*
+ * Helper method to create new GetRDMRequest objects.
+ * @param destination the destination UID
+ * @param data the RDM Request data
+ * @param length the size of the RDM data.
+ */
+const RDMRequest *EnttecUsbProWidgetTest::NewRequest(const UID &destination,
+ const uint8_t *data,
+ unsigned int length) {
+ return new ola::rdm::RDMGetRequest(
+ SOURCE,
+ destination,
+ m_transaction_number++, // transaction #
+ 1, // port id
+ 0, // message count
+ 10, // sub device
+ 296, // param id
+ data,
+ length);
+}
+
+
+/**
+ * Pack a RDM request into a buffer
+ */
+uint8_t *EnttecUsbProWidgetTest::PackRDMRequest(const RDMRequest *request,
+ unsigned int *size) {
+ unsigned int request_size = request->Size();
+ uint8_t *rdm_data = new uint8_t[request_size + 1];
+ rdm_data[0] = ola::rdm::RDMCommand::START_CODE;
+ memset(&rdm_data[1], 0, request_size);
+ CPPUNIT_ASSERT(request->Pack(
+ &rdm_data[1],
+ &request_size));
+ *size = request_size + 1;
+ return rdm_data;
+}
+
+
+/**
+ * Pack a RDM Discovery Command
+ */
+uint8_t *EnttecUsbProWidgetTest::PackDiscoveryReqest(
+ const RDMDiscoveryCommand *request,
+ unsigned int *size) {
+ unsigned int request_size = request->Size();
+ uint8_t *rdm_data = new uint8_t[request_size + 1];
+ memset(rdm_data, 0, request_size);
+ rdm_data[0] = ola::rdm::RDMCommand::START_CODE;
+ memset(&rdm_data[1], 0, request_size);
+ CPPUNIT_ASSERT(request->Pack(
+ &rdm_data[1],
+ &request_size));
+ *size = request_size + 1;
+ return rdm_data;
+}
+
+
+/**
+ * Pack a RDM Response into a buffer
+ */
+uint8_t *EnttecUsbProWidgetTest::PackRDMResponse(const RDMResponse *response,
+ unsigned int *size) {
+ unsigned int response_size = response->Size();
+ uint8_t *rdm_data = new uint8_t[response_size + 2];
+ rdm_data[0] = 0; // status ok
+ rdm_data[1] = ola::rdm::RDMCommand::START_CODE;
+ memset(&rdm_data[2], 0, response_size);
+ CPPUNIT_ASSERT(response->Pack(
+ &rdm_data[2],
+ &response_size));
+ *size = response_size + 2;
+ return rdm_data;
+}
+
+
+/*
+ * Check the response matches what we expected.
+ */
+void EnttecUsbProWidgetTest::ValidateResponse(
+ ola::rdm::rdm_response_code code,
+ const ola::rdm::RDMResponse *response,
+ const vector<string> &packets) {
+ CPPUNIT_ASSERT_EQUAL(ola::rdm::RDM_COMPLETED_OK, code);
+ CPPUNIT_ASSERT(response);
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<unsigned int>(sizeof(TEST_RDM_DATA)),
+ response->ParamDataSize());
+ CPPUNIT_ASSERT(0 == memcmp(TEST_RDM_DATA, response->ParamData(),
+ response->ParamDataSize()));
+
+ CPPUNIT_ASSERT_EQUAL((size_t) 1, packets.size());
+ ola::rdm::rdm_response_code raw_code;
+ auto_ptr<ola::rdm::RDMResponse> raw_response(
+ ola::rdm::RDMResponse::InflateFromData(packets[0], &raw_code));
+ CPPUNIT_ASSERT(*(raw_response.get()) == *response);
+ delete response;
+ m_ss.Terminate();
+}
+
+
+/*
+ * Check that this request returned the expected status code
+ * @param expected_code the expected widget status code
+ * @param expected_code a list of expected packets
+ * @param code the actual status code returns
+ * @param response the RDMResponse object, or NULL
+ * @param packets the actual packets involved
+ */
+void EnttecUsbProWidgetTest::ValidateStatus(
+ ola::rdm::rdm_response_code expected_code,
+ vector<string> expected_packets,
+ ola::rdm::rdm_response_code code,
+ const ola::rdm::RDMResponse *response,
+ const vector<string> &packets) {
+ CPPUNIT_ASSERT_EQUAL(expected_code, code);
+ CPPUNIT_ASSERT(!response);
+
+ CPPUNIT_ASSERT_EQUAL(expected_packets.size(), packets.size());
+ for (unsigned int i = 0; i < packets.size(); i++) {
+ if (expected_packets[i].size() != packets[i].size())
+ OLA_INFO << expected_packets[i].size() << " != " << packets[i].size();
+ CPPUNIT_ASSERT_EQUAL(expected_packets[i].size(), packets[i].size());
+
+ if (expected_packets[i] != packets[i]) {
+ for (unsigned int j = 0; j < packets[i].size(); j++) {
+ OLA_INFO << std::hex << static_cast<int>(packets[i][j]) << " - " <<
+ static_cast<int>(expected_packets[i][j]);
+ }
+ }
+ CPPUNIT_ASSERT(expected_packets[i] == packets[i]);
+ }
+ m_received_code = expected_code;
+ m_ss.Terminate();
+}
+
+
+/**
+ * Validate that a mute response matches what we expect
+ */
+void EnttecUsbProWidgetTest::ValidateMuteStatus(bool expected,
+ bool actual) {
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
+ m_ss.Terminate();
+}
+
+
+
+/**
+ * Validate that a branch request returns what we expect.
+ */
+void EnttecUsbProWidgetTest::ValidateBranchStatus(const uint8_t *expected_data,
+ unsigned int length,
+ const uint8_t *actual_data,
+ unsigned int actual_length) {
+ CPPUNIT_ASSERT_EQUAL(length, actual_length);
+ CPPUNIT_ASSERT(!memcmp(expected_data, actual_data, length));
+ m_ss.Terminate();
+}
+
+
+/**
+ * Send a RDM response message, followed by a RDM timeout message
+ */
+void EnttecUsbProWidgetTest::SendResponseAndTimeout(
+ const uint8_t *response_data,
+ unsigned int length) {
+ m_endpoint->SendUnsolicitedUsbProData(
+ RECEIVE_DMX_LABEL,
+ response_data,
+ length);
+ m_endpoint->SendUnsolicitedUsbProData(
+ RDM_TIMEOUT_PACKET,
+ NULL,
+ 0);
+}
+
+
/**
* Check the params are ok
*/
@@ -243,3 +490,240 @@ void EnttecUsbProWidgetTest::testChangeMode() {
m_ss.Run();
m_endpoint->Verify();
}
+
+
+/**
+ * Check that we send RDM messages correctly.
+ */
+void EnttecUsbProWidgetTest::testSendRDMRequest() {
+ // request
+ const RDMRequest *rdm_request = NewRequest(DESTINATION);
+ unsigned int expected_request_frame_size;
+ uint8_t *expected_request_frame = PackRDMRequest(
+ rdm_request,
+ &expected_request_frame_size);
+
+ // response
+ auto_ptr<const RDMResponse> response(
+ GetResponseFromData(rdm_request, TEST_RDM_DATA, sizeof(TEST_RDM_DATA)));
+ unsigned int response_size;
+ uint8_t *response_frame = PackRDMResponse(response.get(), &response_size);
+
+ // add the expected response, send and verify
+ m_endpoint->AddExpectedUsbProDataAndReturn(
+ RDM_PACKET,
+ expected_request_frame,
+ expected_request_frame_size,
+ RECEIVE_DMX_LABEL,
+ response_frame,
+ response_size);
+
+ m_widget->SendRDMRequest(
+ rdm_request,
+ ola::NewSingleCallback(this, &EnttecUsbProWidgetTest::ValidateResponse));
+ m_ss.Run();
+ m_endpoint->Verify();
+
+ delete[] expected_request_frame;
+ delete[] response_frame;
+
+ // now check broadcast messages
+ // request
+ rdm_request = NewRequest(BCAST_DESTINATION);
+ uint8_t *expected_bcast_request_frame = PackRDMRequest(
+ rdm_request,
+ &expected_request_frame_size);
+
+ // add the expected response, send and verify
+ m_endpoint->AddExpectedUsbProDataAndReturn(
+ RDM_PACKET,
+ expected_bcast_request_frame,
+ expected_request_frame_size,
+ RDM_TIMEOUT_PACKET,
+ NULL,
+ 0);
+
+ vector<string> packets;
+ m_received_code = ola::rdm::RDM_COMPLETED_OK;
+ m_widget->SendRDMRequest(
+ rdm_request,
+ ola::NewSingleCallback(this,
+ &EnttecUsbProWidgetTest::ValidateStatus,
+ ola::rdm::RDM_WAS_BROADCAST,
+ packets));
+ m_ss.Run();
+ CPPUNIT_ASSERT_EQUAL(ola::rdm::RDM_WAS_BROADCAST, m_received_code);
+ m_endpoint->Verify();
+
+ // cleanup time
+ delete[] expected_bcast_request_frame;
+}
+
+
+/**
+ * Test mute device
+ */
+void EnttecUsbProWidgetTest::testMuteDevice() {
+ // first test when a device doesn't respond
+ const MuteRequest mute_request(SOURCE,
+ DESTINATION,
+ m_transaction_number++);
+ unsigned int expected_request_frame_size;
+ uint8_t *expected_request_frame = PackDiscoveryReqest(
+ &mute_request,
+ &expected_request_frame_size);
+
+ // add the expected response, send and verify
+ m_endpoint->AddExpectedUsbProDataAndReturn(
+ RDM_PACKET,
+ expected_request_frame,
+ expected_request_frame_size,
+ RDM_TIMEOUT_PACKET,
+ NULL,
+ 0);
+
+ m_widget.get()->m_impl->MuteDevice(
+ DESTINATION,
+ ola::NewSingleCallback(this,
+ &EnttecUsbProWidgetTest::ValidateMuteStatus,
+ false));
+ m_ss.Run();
+ m_endpoint->Verify();
+ delete[] expected_request_frame;
+
+ // now try an actual mute response
+ const MuteRequest mute_request2(SOURCE,
+ DESTINATION,
+ m_transaction_number++);
+ expected_request_frame = PackDiscoveryReqest(
+ &mute_request2,
+ &expected_request_frame_size);
+
+ // We can really return anything
+ // TODO(simon): make this better
+ uint8_t mute_response_frame[] = {
+ 0,
+ ola::rdm::RDMCommand::START_CODE,
+ 0};
+
+ // add the expected response, send and verify
+ m_endpoint->AddExpectedUsbProDataAndReturn(
+ RDM_PACKET,
+ expected_request_frame,
+ expected_request_frame_size,
+ RECEIVE_DMX_LABEL,
+ mute_response_frame,
+ sizeof(mute_response_frame));
+
+ m_widget.get()->m_impl->MuteDevice(
+ DESTINATION,
+ ola::NewSingleCallback(this,
+ &EnttecUsbProWidgetTest::ValidateMuteStatus,
+ true));
+ m_ss.Run();
+ m_endpoint->Verify();
+ delete[] expected_request_frame;
+}
+
+
+/**
+ * Test the unmute all request works
+ */
+void EnttecUsbProWidgetTest::testUnMuteAll() {
+ const UnMuteRequest unmute_request(SOURCE,
+ UID::AllDevices(),
+ m_transaction_number++);
+ unsigned int expected_request_frame_size;
+ uint8_t *expected_request_frame = PackDiscoveryReqest(
+ &unmute_request,
+ &expected_request_frame_size);
+
+ // add the expected response, send and verify
+ m_endpoint->AddExpectedUsbProDataAndReturn(
+ RDM_PACKET,
+ expected_request_frame,
+ expected_request_frame_size,
+ RDM_TIMEOUT_PACKET,
+ NULL,
+ 0);
+
+ m_widget.get()->m_impl->UnMuteAll(
+ ola::NewSingleCallback(this,
+ &EnttecUsbProWidgetTest::Terminate));
+ m_ss.Run();
+ m_endpoint->Verify();
+ delete[] expected_request_frame;
+}
+
+
+/**
+ * Test the DUB request works
+ */
+void EnttecUsbProWidgetTest::testBranch() {
+ // first test when no devices respond
+ const DiscoveryUniqueBranchRequest discovery_request(
+ SOURCE,
+ UID(0, 0),
+ UID::AllDevices(),
+ m_transaction_number++);
+ unsigned int expected_request_frame_size;
+ uint8_t *expected_request_frame = PackDiscoveryReqest(
+ &discovery_request,
+ &expected_request_frame_size);
+
+ // add the expected response, send and verify
+ m_endpoint->AddExpectedUsbProDataAndReturn(
+ RDM_DISCOVERY_PACKET,
+ expected_request_frame,
+ expected_request_frame_size,
+ RDM_TIMEOUT_PACKET,
+ NULL,
+ 0);
+
+ m_widget.get()->m_impl->Branch(
+ UID(0, 0),
+ UID::AllDevices(),
+ ola::NewSingleCallback(this,
+ &EnttecUsbProWidgetTest::ValidateBranchStatus,
+ static_cast<const uint8_t*>(NULL),
+ static_cast<unsigned int>(0)));
+ m_ss.Run();
+ m_endpoint->Verify();
+ delete[] expected_request_frame;
+
+ // now try an actual response, the data doesn't actually have to be valid
+ // because it's just passed straight to the callback.
+ const DiscoveryUniqueBranchRequest discovery_request2(
+ SOURCE,
+ UID(0, 0),
+ UID::AllDevices(),
+ m_transaction_number++);
+ expected_request_frame = PackDiscoveryReqest(
+ &discovery_request2,
+ &expected_request_frame_size);
+
+ // the response, can be anything really, only the first byte counts
+ uint8_t response_frame2[] = {0, 1, 2, 3, 4};
+
+ m_endpoint->AddExpectedUsbProMessage(
+ RDM_DISCOVERY_PACKET,
+ expected_request_frame,
+ expected_request_frame_size,
+ ola::NewSingleCallback(
+ this,
+ &EnttecUsbProWidgetTest::SendResponseAndTimeout,
+ static_cast<const uint8_t*>(response_frame2),
+ static_cast<unsigned int>(sizeof(response_frame2))));
+
+ m_widget.get()->m_impl->Branch(
+ UID(0, 0),
+ UID::AllDevices(),
+ ola::NewSingleCallback(
+ this,
+ &EnttecUsbProWidgetTest::ValidateBranchStatus,
+ static_cast<const uint8_t*>(&response_frame2[1]),
+ static_cast<unsigned int>(sizeof(response_frame2) - 1)));
+ m_ss.Run();
+ m_endpoint->Verify();
+ delete[] expected_request_frame;
+}
View
60 plugins/usbpro/GenericUsbProWidget.cpp
@@ -198,36 +198,6 @@ void GenericUsbProWidget::HandleMessage(uint8_t label,
/*
- * Called when we get new parameters from the widget.
- */
-void GenericUsbProWidget::HandleParameters(const uint8_t *data,
- unsigned int length) {
- if (m_outstanding_param_callbacks.empty())
- return;
-
- // parameters
- typedef struct {
- uint8_t firmware;
- uint8_t firmware_high;
- uint8_t break_time;
- uint8_t mab_time;
- uint8_t rate;
- } widget_parameters_reply;
-
- if (length < sizeof(usb_pro_parameters))
- return;
-
- usb_pro_parameters params;
- memcpy(&params, data, sizeof(usb_pro_parameters));
-
- usb_pro_params_callback *callback = m_outstanding_param_callbacks.front();
- m_outstanding_param_callbacks.pop_front();
-
- callback->Run(true, params);
-}
-
-
-/*
* Handle the dmx frame
*/
void GenericUsbProWidget::HandleDMX(const uint8_t *data,
@@ -260,6 +230,36 @@ void GenericUsbProWidget::HandleDMX(const uint8_t *data,
/*
+ * Called when we get new parameters from the widget.
+ */
+void GenericUsbProWidget::HandleParameters(const uint8_t *data,
+ unsigned int length) {
+ if (m_outstanding_param_callbacks.empty())
+ return;
+
+ // parameters
+ typedef struct {
+ uint8_t firmware;
+ uint8_t firmware_high;
+ uint8_t break_time;
+ uint8_t mab_time;
+ uint8_t rate;
+ } widget_parameters_reply;
+
+ if (length < sizeof(usb_pro_parameters))
+ return;
+
+ usb_pro_parameters params;
+ memcpy(&params, data, sizeof(usb_pro_parameters));
+
+ usb_pro_params_callback *callback = m_outstanding_param_callbacks.front();
+ m_outstanding_param_callbacks.pop_front();
+
+ callback->Run(true, params);
+}
+
+
+/*
* Handle the dmx change of state frame
*/
void GenericUsbProWidget::HandleDMXDiff(const uint8_t *data,
View
5 plugins/usbpro/GenericUsbProWidget.h
@@ -73,6 +73,9 @@ class GenericUsbProWidget: public BaseUsbProWidget {
virtual void HandleMessage(uint8_t label,
const uint8_t *data,
unsigned int length);
+ void HandleDMX(const uint8_t *data, unsigned int length);
+
+ static const uint8_t RECEIVED_DMX_LABEL = 5;
private:
ola::thread::SchedulerInterface *m_scheduler;
@@ -82,13 +85,11 @@ class GenericUsbProWidget: public BaseUsbProWidget {
std::deque<usb_pro_params_callback*> m_outstanding_param_callbacks;
void HandleParameters(const uint8_t *data, unsigned int length);
- void HandleDMX(const uint8_t *data, unsigned int length);
void HandleDMXDiff(const uint8_t *data, unsigned int length);
static const uint8_t REPROGRAM_FIRMWARE_LABEL = 2;
static const uint8_t PARAMETERS_LABEL = 3;
static const uint8_t SET_PARAMETERS_LABEL = 4;
- static const uint8_t RECEIVED_DMX_LABEL = 5;
static const uint8_t DMX_RX_MODE_LABEL = 8;
static const uint8_t DMX_CHANGED_LABEL = 9;
};
View
4 plugins/usbpro/UsbProDevice.cpp
@@ -52,8 +52,6 @@ UsbProDevice::UsbProDevice(ola::PluginAdaptor *plugin_adaptor,
ola::AbstractPlugin *owner,
const string &name,
EnttecUsbProWidget *widget,
- uint16_t esta_id,
- uint16_t device_id,
uint32_t serial,
unsigned int fps_limit):
UsbSerialDevice(owner, name, widget),
@@ -97,8 +95,6 @@ UsbProDevice::UsbProDevice(ola::PluginAdaptor *plugin_adaptor,
AddPort(output_port);
Start(); // this does nothing but set IsEnabled() to true
- (void) esta_id;
- (void) device_id;
}
View
17 plugins/usbpro/UsbProDevice.h
@@ -48,8 +48,6 @@ class UsbProDevice: public UsbSerialDevice {
ola::AbstractPlugin *owner,
const string &name,
EnttecUsbProWidget *widget,
- uint16_t esta_id,
- uint16_t device_id,
uint32_t serial,
unsigned int fps_limit);
@@ -130,7 +128,7 @@ class UsbProOutputPort: public BasicOutputPort {
const TimeStamp *wake_time,
unsigned int max_burst,
unsigned int rate)
- : BasicOutputPort(parent, id),
+ : BasicOutputPort(parent, id, true),
m_path(path),
m_widget(widget),
m_bucket(max_burst, rate, max_burst, *wake_time),
@@ -151,6 +149,19 @@ class UsbProOutputPort: public BasicOutputPort {
(void) old_universe;
}
+ void SendRDMRequest(const ola::rdm::RDMRequest *request,
+ ola::rdm::RDMCallback *callback) {
+ m_widget->SendRDMRequest(request, callback);
+ }
+
+ void RunFullDiscovery(ola::rdm::RDMDiscoveryCallback *callback) {
+ m_widget->RunFullDiscovery(callback);
+ }
+
+ void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback) {
+ m_widget->RunIncrementalDiscovery(callback);
+ }
+
string Description() const { return m_path; }
private:
View
3  plugins/usbpro/UsbSerialPlugin.cpp
@@ -65,7 +65,6 @@ const char UsbSerialPlugin::TRI_USE_RAW_RDM_KEY[] = "tri_use_raw_rdm";
const char UsbSerialPlugin::USBPRO_DEVICE_NAME[] = "Enttec Usb Pro Device";
const char UsbSerialPlugin::USB_PRO_FPS_LIMIT_KEY[] = "pro_fps_limit";
const char UsbSerialPlugin::ULTRA_FPS_LIMIT_KEY[] = "ultra_fps_limit";
-const uint16_t UsbSerialPlugin::ENTTEC_ESTA_ID = 0x454E;
UsbSerialPlugin::UsbSerialPlugin(PluginAdaptor *plugin_adaptor)
: Plugin(plugin_adaptor),
@@ -172,8 +171,6 @@ void UsbSerialPlugin::NewWidget(
this,
device_name,
widget,
- information.esta_id ? information.esta_id : ENTTEC_ESTA_ID,
- information.device_id ? information.device_id : 0,
information.serial,
GetProFrameLimit()));
}
View
1  plugins/usbpro/UsbSerialPlugin.h
@@ -89,7 +89,6 @@ class UsbSerialPlugin: public ola::Plugin, public NewWidgetHandler {
static const char USBPRO_DEVICE_NAME[];
static const char USB_PRO_FPS_LIMIT_KEY[];
static const char ULTRA_FPS_LIMIT_KEY[];
- static const uint16_t ENTTEC_ESTA_ID;
static const unsigned int MAX_DMX_TRI_FPS_LIMIT = 1000;
static const unsigned int MAX_PRO_FPS_LIMIT = 1000;
static const unsigned int MAX_ULTRA_FPS_LIMIT = 1000;
View
8 plugins/usbpro/WidgetDetectorThread.cpp
@@ -283,7 +283,9 @@ void WidgetDetectorThread::UsbProWidgetReady(
DispatchWidget(
new EnttecUsbProWidget(
m_other_ss,
- descriptor),
+ descriptor,
+ information->esta_id,
+ information->serial),
information);
return;
}
@@ -327,7 +329,9 @@ void WidgetDetectorThread::UsbProWidgetReady(
DispatchWidget(
new EnttecUsbProWidget(
m_other_ss,
- descriptor),
+ descriptor,
+ information->esta_id,
+ information->serial),
information);
}
Please sign in to comment.
Something went wrong with that request. Please try again.