Open Lighting Architecture: plugins/usbpro/DmxTriWidget.h Source File

| Open Lighting Architecture 0.10.9

Loading...
Searching...
No Matches
DmxTriWidget.h
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15 *
16 * DmxTriWidget.h
17 * The Jese DMX-TRI/RDM-TRI widget.
18 * Copyright (C) 2010 Simon Newton
19 */
20
21#ifndef PLUGINS_USBPRO_DMXTRIWIDGET_H_
22#define PLUGINS_USBPRO_DMXTRIWIDGET_H_
23
24#include <map>
25#include <string>
26#include <queue>
27#include "ola/Callback.h"
28#include "ola/DmxBuffer.h"
29#include "ola/rdm/QueueingRDMController.h"
30#include "ola/rdm/RDMControllerInterface.h"
31#include "ola/rdm/UIDSet.h"
32#include "ola/thread/SchedulerInterface.h"
33#include "plugins/usbpro/BaseUsbProWidget.h"
34
35namespace ola {
36namespace plugin {
37namespace usbpro {
38
39/*
40 * A DMX TRI Widget implementation. We separate the Widget from the
41 * implementation so we can leverage the QueueingRDMController.
42 */
43 class DmxTriWidgetImpl: public BaseUsbProWidget,
44 public ola::rdm::DiscoverableRDMControllerInterface {
45 public:
46 DmxTriWidgetImpl(ola::thread::SchedulerInterface *executor,
47 ola::io::ConnectedDescriptor *descriptor,
48 bool use_raw_rdm);
49 ~DmxTriWidgetImpl();
50
51 void UseRawRDM(bool use_raw_rdm) { m_use_raw_rdm = use_raw_rdm; }
52
53 void Stop();
54
55 bool SendDMX(const DmxBuffer &buffer);
56 void SendRDMRequest(ola::rdm::RDMRequest *request,
57 ola::rdm::RDMCallback *on_complete);
58 void RunFullDiscovery(ola::rdm::RDMDiscoveryCallback *callback);
59 void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback);
60
61 private:
62 typedef enum {
63 SINGLE_TX_COMMAND_ID = 0x21,
64 DISCOVER_AUTO_COMMAND_ID = 0x33,
65 DISCOVER_STATUS_COMMAND_ID = 0x34,
66 REMOTE_UID_COMMAND_ID = 0x35,
67 RAW_RDM_COMMAND_ID = 0x37,
68 REMOTE_GET_COMMAND_ID = 0x38,
69 REMOTE_SET_COMMAND_ID = 0x39,
70 QUEUED_GET_COMMAND_ID = 0x3a,
71 SET_FILTER_COMMAND_ID = 0x3d,
72
73 RESERVED_COMMAND_ID = 0xff,
74 } TriCommandId;
75
76 typedef enum {
77 NO_DISCOVERY_ACTION,
78 DISCOVER_AUTO_REQUIRED,
79 DISCOVER_STATUS_REQUIRED,
80 FETCH_UID_REQUIRED,
81 } TriDiscoveryState;
82
83 typedef std::map<ola::rdm::UID, uint8_t> UIDToIndexMap;
84
85 ola::thread::SchedulerInterface *m_scheduler;
86 UIDToIndexMap m_uid_index_map;
87 uint8_t m_uid_count;
88 uint16_t m_last_esta_id;
89 bool m_use_raw_rdm;
90
91 // State for sending DMX
92 DmxBuffer m_outgoing_dmx;
93
94 // State for handling RDM discovery
95 ola::thread::timeout_id m_disc_stat_timeout_id;
96 ola::rdm::RDMDiscoveryCallback *m_discovery_callback;
97 TriDiscoveryState m_discovery_state;
98
99 // State for sending RDM Gets/Sets
100 // This holds pointers to the RDMRequest and Callback that is queued or in
101 // flight.
102 ola::rdm::RDMCallback *m_rdm_request_callback;
103 std::auto_ptr<ola::rdm::RDMRequest> m_pending_rdm_request;
104 uint8_t m_transaction_number;
105 // The command id that we expect to see in the response.
106 uint8_t m_last_command, m_expected_command;
107
108 void SendDMXBuffer();
109 void SendQueuedRDMCommand();
110 void RunDiscoveryCallback(ola::rdm::RDMDiscoveryCallback *callback);
111 bool CheckDiscoveryStatus();
112 void HandleMessage(uint8_t label,
113 const uint8_t *data,
114 unsigned int length);
115 void SendDiscoveryAuto();
116 void SendDiscoveryStat();
117 void FetchNextUID();
118 void SendRawRDMRequest();
119 void DispatchRequest();
120 void DispatchQueuedGet();
121 void StopDiscovery();
122
123 void HandleSingleTXResponse(uint8_t return_code);
124 void HandleDiscoveryAutoResponse(uint8_t return_code,
125 const uint8_t *data,
126 unsigned int length);
127 void HandleDiscoverStatResponse(uint8_t return_code,
128 const uint8_t *data,
129 unsigned int length);
130 void HandleRemoteUIDResponse(uint8_t return_code,
131 const uint8_t *data,
132 unsigned int length);
133 void HandleRawRDMResponse(uint8_t return_code,
134 const uint8_t *data,
135 unsigned int length);
136 void HandleRemoteRDMResponse(uint8_t return_code,
137 const uint8_t *data,
138 unsigned int length);
139 void HandleQueuedGetResponse(uint8_t return_code,
140 const uint8_t *data,
141 unsigned int length);
142 void HandleGenericRDMResponse(uint8_t return_code,
143 uint16_t pid,
144 const uint8_t *data,
145 unsigned int length);
146 void HandleSetFilterResponse(uint8_t return_code,
147 const uint8_t *data,
148 unsigned int length);
149 bool PendingTransaction() const;
150 void MaybeSendNextRequest();
151 void HandleRDMError(ola::rdm::RDMStatusCode error_code);
152 bool SendCommandToTRI(uint8_t label, const uint8_t *data,
153 unsigned int length);
154 bool TriToOlaReturnCode(uint8_t return_code,
155 ola::rdm::RDMStatusCode *code);
156 bool ReturnCodeToNackReason(uint8_t return_code,
157 ola::rdm::rdm_nack_reason *reason);
158
159 typedef enum {
160 EC_NO_ERROR = 0,
161 EC_CONSTRAINT = 1,
162 EC_UNKNOWN_COMMAND = 2,
163 EC_INVALID_OPTION = 3,
164 EC_FRAME_FORMAT = 4,
165 EC_DATA_TOO_LONG = 5,
166 EC_DATA_MISSING = 6,
167 EC_SYSTEM_MODE = 7,
168 EC_SYSTEM_BUSY = 8,
169 EC_DATA_CHECKSUM = 0x0a,
170 EC_INCOMPATIBLE = 0x0b,
171 EC_RESPONSE_TIME = 0x10,
172 EC_RESPONSE_WAIT = 0x11,
173 EC_RESPONSE_MORE = 0x12,
174 EC_RESPONSE_TRANSACTION = 0x13,
175 EC_RESPONSE_SUB_DEVICE = 0x14,
176 EC_RESPONSE_FORMAT = 0x15,
177 EC_RESPONSE_CHECKSUM = 0x16,
178 EC_RESPONSE_NONE = 0x18,
179 EC_RESPONSE_IDENTITY = 0x1a,
180 EC_RESPONSE_MUTE = 0x1b,
181 EC_RESPONSE_DISCOVERY = 0x1c,
182 EC_RESPONSE_UNEXPECTED = 0x1d,
183 EC_UNKNOWN_PID = 0x20,
184 EC_FORMAT_ERROR = 0x21,
185 EC_HARDWARE_FAULT = 0x22,
186 EC_PROXY_REJECT = 0x23,
187 EC_WRITE_PROTECT = 0x24,
188 EC_UNSUPPORTED_COMMAND_CLASS = 0x25,
189 EC_OUT_OF_RANGE = 0x26,
190 EC_BUFFER_FULL = 0x27,
191 EC_FRAME_OVERFLOW = 0x28,
192 EC_SUBDEVICE_UNKNOWN = 0x29,
193 EC_PROXY_BUFFER_FULL = 0x2a, // this isn't included in the docs
194 EC_ACTION_NOT_SUPPORTED = 0x2b, // this is a guess
195 EC_ENDPOINT_NUMBER_INVALID = 0x2c, // this is a guess
196 EC_INVALID_ENDPOINT_MODE = 0x2d, // this is a guess
197 EC_UNKNOWN_UID = 0x2e, // this is a guess
198 EC_UNKNOWN_SCOPE = 0x2f, // this is a guess
199 EC_INVALID_STATIC_CONFIG_TYPE = 0x30, // this is a guess
200 EC_INVALID_IPV4_ADDRESS = 0x31, // this is a guess
201 EC_INVALID_IPV6_ADDRESS = 0x32, // this is a guess
202 EC_INVALID_PORT = 0x33 // this is a guess
203 } dmx_tri_error_codes;
204 // TODO(Peter): try and test the guessed values
205
206 static const unsigned int DATA_OFFSET = 2; // first two bytes are CI & RC
207 static const uint8_t EXTENDED_COMMAND_LABEL = 88; // 'X'
208
209 // The ms delay between checking on the RDM discovery process
210 static const unsigned int RDM_STATUS_INTERVAL_MS = 100;
211};
212
213
214/*
215 * A DMX TRI Widget
216 */
217 class DmxTriWidget: public SerialWidgetInterface,
218 public ola::rdm::DiscoverableRDMControllerInterface {
219 public:
220 DmxTriWidget(ola::thread::SchedulerInterface *ss,
221 ola::io::ConnectedDescriptor *descriptor,
222 unsigned int queue_size = 20,
223 bool use_raw_rdm = false);
224 ~DmxTriWidget();
225 void UseRawRDM(bool use_raw_rdm) { m_impl->UseRawRDM(use_raw_rdm); }
226
227 void Stop() { m_impl->Stop(); }
228
229 bool SendDMX(const DmxBuffer &buffer) const {
230 return m_impl->SendDMX(buffer);
231 }
232
233 void SendRDMRequest(ola::rdm::RDMRequest *request,
234 ola::rdm::RDMCallback *on_complete) {
235 m_controller->SendRDMRequest(request, on_complete);
236 }
237
238 void RunFullDiscovery(ola::rdm::RDMDiscoveryCallback *callback) {
239 m_controller->RunFullDiscovery(callback);
240 }
241
242 void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback) {
243 m_controller->RunIncrementalDiscovery(callback);
244 }
245
246 ola::io::ConnectedDescriptor *GetDescriptor() const {
247 return m_impl->GetDescriptor();
248 }
249
250 private:
251 // we need to control the order of construction & destruction here so these
252 // are pointers.
253 DmxTriWidgetImpl *m_impl;
254 ola::rdm::DiscoverableQueueingRDMController *m_controller;
255
256 void ResumeRDMCommands() {
257 m_controller->Resume();
258 }
259};
260} // namespace usbpro
261} // namespace plugin
262} // namespace ola
263#endif // PLUGINS_USBPRO_DMXTRIWIDGET_H_
Callback.h
DmxBuffer.h
A class used to hold a single universe of DMX data.
QueueingRDMController.h
An RDM Controller that queues messages and only sends a single message at a time.
RDMControllerInterface.h
Definitions and Interfaces to implement an RDMController that sends a single message at a time.
UIDSet.h
A set of UIDs.
ola::DmxBuffer
Used to hold a single universe of DMX data.
Definition DmxBuffer.h:49
ola::io::ConnectedDescriptor
A BidirectionalFileDescriptor that also generates notifications when closed.
Definition Descriptor.h:283
ola::plugin::usbpro::DmxTriWidget::DmxTriWidget
DmxTriWidget(ola::thread::SchedulerInterface *ss, ola::io::ConnectedDescriptor *descriptor, unsigned int queue_size=20, bool use_raw_rdm=false)
Definition DmxTriWidget.cpp:1028
ola::plugin::usbpro::DmxTriWidget::RunIncrementalDiscovery
void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback)
Start an incremental discovery operation.
Definition DmxTriWidget.h:242
ola::plugin::usbpro::DmxTriWidget::SendRDMRequest
void SendRDMRequest(ola::rdm::RDMRequest *request, ola::rdm::RDMCallback *on_complete)
Send a RDM command.
Definition DmxTriWidget.h:233
ola::plugin::usbpro::DmxTriWidget::RunFullDiscovery
void RunFullDiscovery(ola::rdm::RDMDiscoveryCallback *callback)
Start a full discovery operation.
Definition DmxTriWidget.h:238
ola::plugin::usbpro::DmxTriWidgetImpl::Stop
void Stop()
Definition DmxTriWidget.cpp:96
ola::plugin::usbpro::DmxTriWidgetImpl::RunIncrementalDiscovery
void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback)
Definition DmxTriWidget.cpp:171
ola::plugin::usbpro::DmxTriWidgetImpl::SendRDMRequest
void SendRDMRequest(ola::rdm::RDMRequest *request, ola::rdm::RDMCallback *on_complete)
Send a RDM command.
Definition DmxTriWidget.cpp:136
ola::plugin::usbpro::DmxTriWidgetImpl::RunFullDiscovery
void RunFullDiscovery(ola::rdm::RDMDiscoveryCallback *callback)
Definition DmxTriWidget.cpp:162
ola::plugin::usbpro::DmxTriWidgetImpl::SendDMX
bool SendDMX(const DmxBuffer &buffer)
Definition DmxTriWidget.cpp:119
ola::rdm::DiscoverableQueueingRDMController
Definition QueueingRDMController.h:88
ola::rdm::DiscoverableRDMControllerInterface
The interface that can send RDM commands, as well as perform discovery operations.
Definition RDMControllerInterface.h:104
ola::rdm::QueueingRDMController::Resume
void Resume()
Definition QueueingRDMController.cpp:87
ola::rdm::RDMRequest
RDM Commands that represent requests (GET, SET or DISCOVER).
Definition RDMCommand.h:234
ola::thread::SchedulerInterface
Allows Callbacks to be scheduled to run after a specified interval.
Definition SchedulerInterface.h:46
ola::plugin::usbpro
Code for Enttec USB Pro devices and others using the same protocol.
ola::plugin
Code for supported devices and protocols.
ola::rdm::RDMStatusCode
RDMStatusCode
RDM Status Codes.
Definition RDMResponseCodes.h:45
ola::rdm::RDMCallback
ola::BaseCallback1< void, RDMReply * > RDMCallback
The callback run when a RDM request completes.
Definition RDMControllerInterface.h:52
ola::rdm::RDMDiscoveryCallback
ola::BaseCallback1< void, const ola::rdm::UIDSet & > RDMDiscoveryCallback
The callback run when a discovery operation completes.
Definition RDMControllerInterface.h:68
ola::thread::timeout_id
void * timeout_id
A timeout handle which can later be used to cancel a timeout.
Definition SchedulerInterface.h:34
ola
The namespace containing all OLA symbols.
Definition Credentials.cpp:44