Open Lighting Architecture  Latest Git
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
JaRuleWidgetPort.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  * JaRuleWidgetPort.h
17  * A Ja Rule widget port.
18  * Copyright (C) 2015 Simon Newton
19  */
20 
21 #ifndef LIBS_USB_JARULEWIDGETPORT_H_
22 #define LIBS_USB_JARULEWIDGETPORT_H_
23 
24 #include <libusb.h>
25 #include <ola/Callback.h>
26 #include <ola/io/ByteString.h>
27 #include <ola/thread/ExecutorInterface.h>
28 #include <ola/thread/Mutex.h>
29 #include <ola/util/SequenceNumber.h>
30 
31 #include <map>
32 #include <queue>
33 
34 #include "libs/usb/JaRulePortHandle.h"
35 #include "libs/usb/LibUsbAdaptor.h"
36 #include "libs/usb/JaRuleWidget.h"
37 
38 namespace ola {
39 namespace usb {
40 
48  public:
59  LibUsbAdaptor *adaptor,
60  libusb_device_handle *usb_handle,
61  uint8_t endpoint_number,
62  const ola::rdm::UID &uid,
63  uint8_t physical_port);
64 
69 
76 
81  void ReleasePort();
82 
86  void CancelAll();
87 
99  void SendCommand(CommandClass command,
100  const uint8_t *data,
101  unsigned int size,
102  CommandCompleteCallback *callback);
103 
108  void _OutTransferComplete();
109 
114  void _InTransferComplete();
115 
116  private:
117  // This must be a multiple of the USB packet size otherwise we can experience
118  // overflows. A message can be a maximum of 640 bytes, so we'll use 1k here
119  // to be safe.
120  enum { IN_BUFFER_SIZE = 1024 };
121  enum { OUT_BUFFER_SIZE = 1024 };
122 
123  // The arguments passed to the user supplied callback.
124  typedef struct {
125  USBCommandResult result;
126  JaRuleReturnCode return_code;
127  uint8_t status_flags;
128  const ola::io::ByteString payload;
129  } CallbackArgs;
130 
131  class PendingCommand {
132  public:
133  PendingCommand(CommandClass command,
134  CommandCompleteCallback *callback,
135  const ola::io::ByteString &payload)
136  : command(command),
137  callback(callback),
138  payload(payload) {
139  }
140 
141  CommandClass command;
142  CommandCompleteCallback *callback;
143  ola::io::ByteString payload;
144  TimeStamp out_time; // When this cmd was sent
145  };
146 
147  typedef std::map<uint8_t, PendingCommand*> PendingCommandMap;
148  typedef std::queue<PendingCommand*> CommandQueue;
149 
150  ola::Clock m_clock;
151  ola::thread::ExecutorInterface* const m_executor;
152  LibUsbAdaptor* const m_adaptor;
153  libusb_device_handle* const m_usb_handle;
154  const uint8_t m_endpoint_number;
155  const ola::rdm::UID m_uid;
156  const uint8_t m_physical_port;
157  JaRulePortHandle *m_handle; // NULL if the port isn't claimed
158 
160 
161  ola::thread::Mutex m_mutex;
162  CommandQueue m_queued_commands; // GUARDED_BY(m_mutex);
163  PendingCommandMap m_pending_commands; // GUARDED_BY(m_mutex);
164 
165  libusb_transfer *m_out_transfer; // GUARDED_BY(m_mutex);
166  bool m_out_in_progress; // GUARDED_BY(m_mutex);
167 
168  uint8_t m_in_buffer[IN_BUFFER_SIZE]; // GUARDED_BY(m_mutex);
169  libusb_transfer *m_in_transfer; // GUARDED_BY(m_mutex);
170  bool m_in_in_progress; // GUARDED_BY(m_mutex);
171 
172  void MaybeSendCommand(); // LOCK_REQUIRED(m_mutex);
173  bool SubmitInTransfer(); // LOCK_REQUIRED(m_mutex);
174  void HandleResponse(const uint8_t *data,
175  unsigned int size); // LOCK_REQUIRED(m_mutex);
176 
177  void ScheduleCallback(CommandCompleteCallback *callback,
178  USBCommandResult result,
179  JaRuleReturnCode return_code,
180  uint8_t status_flags,
181  const ola::io::ByteString &payload);
182  void RunCallback(CommandCompleteCallback *callback,
183  CallbackArgs args);
184 
185  static const uint8_t EOF_IDENTIFIER = 0xa5;
186  static const uint8_t SOF_IDENTIFIER = 0x5a;
187  static const unsigned int MAX_PAYLOAD_SIZE = 513;
188  static const unsigned int MIN_RESPONSE_SIZE = 9;
189  static const unsigned int USB_PACKET_SIZE = 64;
190  static const unsigned int MAX_IN_FLIGHT = 2;
191  static const unsigned int MAX_QUEUED_MESSAGES = 10;
192 
193  static const unsigned int ENDPOINT_TIMEOUT_MS = 1000;
194 
195  DISALLOW_COPY_AND_ASSIGN(JaRuleWidgetPort);
196 };
197 } // namespace usb
198 } // namespace ola
199 #endif // LIBS_USB_JARULEWIDGETPORT_H_
USBCommandResult
Indicates the eventual state of a Ja Rule command.
Definition: JaRuleConstants.h:53
void SendCommand(CommandClass command, const uint8_t *data, unsigned int size, CommandCompleteCallback *callback)
Send a command on this port.
Definition: JaRuleWidgetPort.cpp:188
void _OutTransferComplete()
Called by the libusb callback when the transfer completes or is cancelled.
Definition: JaRuleWidgetPort.cpp:247
Represents a DMX/RDM port on a Ja Rule device.
Definition: JaRulePortHandle.h:41
CommandClass
The Ja Rule command set.
Definition: JaRuleConstants.h:101
JaRuleWidgetPort(ola::thread::ExecutorInterface *executor, LibUsbAdaptor *adaptor, libusb_device_handle *usb_handle, uint8_t endpoint_number, const ola::rdm::UID &uid, uint8_t physical_port)
Create a new JaRuleWidgetPort.
Definition: JaRuleWidgetPort.cpp:68
Defer execution of a callback.
Definition: ExecutorInterface.h:35
JaRuleReturnCode
JaRule command return codes.
Definition: JaRuleConstants.h:133
The base class for all 4 argument callbacks.
Definition: Callback.h:3811
The internal model of a port on a JaRule device.
Definition: JaRuleWidgetPort.h:47
void CancelAll()
Cancel all commands for this port.
Definition: JaRuleWidgetPort.cpp:149
Used to get the current time.
Definition: Clock.h:233
void ReleasePort()
Release a handle to a port.
Definition: JaRuleWidgetPort.cpp:142
void _InTransferComplete()
Called by the libusb callback when the transfer completes or is cancelled.
Definition: JaRuleWidgetPort.cpp:263
JaRulePortHandle * ClaimPort()
Claim the handle to this port.
Definition: JaRuleWidgetPort.cpp:133
Represents a RDM UID.
Definition: UID.h:57
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
std::basic_string< uint8_t > ByteString
A contiguous block of uint8_t data.
Definition: ByteString.h:40
Represents a point in time with microsecond accuracy.
Definition: Clock.h:183
~JaRuleWidgetPort()
Destructor.
Definition: JaRuleWidgetPort.cpp:87
Definition: Mutex.h:41
Wraps calls to libusb so we can test the code.
Definition: LibUsbAdaptor.h:36