Open Lighting Architecture  0.9.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OSCNode.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  * OSCNode.h
17  * A DMX orientated, C++ wrapper around liblo.
18  * Copyright (C) 2012 Simon Newton
19  */
20 
21 #ifndef PLUGINS_OSC_OSCNODE_H_
22 #define PLUGINS_OSC_OSCNODE_H_
23 
24 #include <lo/lo.h>
25 #include <ola/DmxBuffer.h>
26 #include <ola/ExportMap.h>
27 #include <ola/io/Descriptor.h>
28 #include <ola/io/SelectServerInterface.h>
30 #include <stdint.h>
31 #include <map>
32 #include <memory>
33 #include <string>
34 #include <vector>
35 #include "plugins/osc/OSCTarget.h"
36 
37 namespace ola {
38 namespace plugin {
39 namespace osc {
40 
69 class OSCNode {
70  public:
71  // The different data formats we can send in.
72  enum DataFormat {
73  FORMAT_BLOB,
74  FORMAT_INT_ARRAY,
75  FORMAT_INT_INDIVIDUAL,
76  FORMAT_FLOAT_ARRAY,
77  FORMAT_FLOAT_INDIVIDUAL,
78  };
79 
80  // The options for the OSCNode object.
81  struct OSCNodeOptions {
82  uint16_t listen_port; // UDP port to listen on
83 
84  OSCNodeOptions() : listen_port(DEFAULT_OSC_PORT) {}
85  };
86 
87  // The callback run when we receive new DMX data.
89 
91  ola::ExportMap *export_map,
92  const OSCNodeOptions &options);
93  ~OSCNode();
94 
95  bool Init();
96  void Stop();
97 
98  // Sending methods
99  void AddTarget(unsigned int group, const OSCTarget &target);
100  bool RemoveTarget(unsigned int group, const OSCTarget &target);
101  bool SendData(unsigned int group, DataFormat data_format,
102  const ola::DmxBuffer &data);
103 
104  // Receiving methods
105  bool RegisterAddress(const std::string &osc_address, DMXCallback *callback);
106 
107  // Called by the liblo handlers.
108  void SetUniverse(const std::string &osc_address, const uint8_t *data,
109  unsigned int size);
110  void SetSlot(const std::string &osc_address, uint16_t slot, uint8_t value);
111 
112  // The port OSC is listening on.
113  uint16_t ListeningPort() const;
114 
115  private:
116  class NodeOSCTarget {
117  public:
118  explicit NodeOSCTarget(const OSCTarget &target);
119  ~NodeOSCTarget();
120 
121  bool operator==(const NodeOSCTarget &other) const {
122  return (socket_address == other.socket_address &&
123  osc_address == other.osc_address);
124  }
125 
126  bool operator==(const OSCTarget &other) const {
127  return (socket_address == other.socket_address &&
128  osc_address == other.osc_address);
129  }
130 
131  ola::network::IPV4SocketAddress socket_address;
132  std::string osc_address;
133  lo_address liblo_address;
134 
135  private:
136  NodeOSCTarget(const NodeOSCTarget&);
137  NodeOSCTarget& operator=(const NodeOSCTarget&);
138  };
139 
140  typedef std::vector<NodeOSCTarget*> OSCTargetVector;
141 
142  struct OSCOutputGroup {
143  OSCTargetVector targets;
144  DmxBuffer dmx; // holds the last values.
145  };
146 
147  struct OSCInputGroup {
148  explicit OSCInputGroup(DMXCallback *callback) : callback(callback) {}
149 
150  DmxBuffer dmx;
151  std::auto_ptr<DMXCallback> callback;
152  };
153 
154  typedef std::map<unsigned int, OSCOutputGroup*> OutputGroupMap;
155  typedef std::map<std::string, OSCInputGroup*> InputUniverseMap;
156 
157  struct SlotMessage {
158  unsigned int slot;
159  lo_message message;
160  };
161 
163  const uint16_t m_listen_port;
164  std::auto_ptr<ola::io::UnmanagedFileDescriptor> m_descriptor;
165  lo_server m_osc_server;
166  OutputGroupMap m_output_map;
167  InputUniverseMap m_input_map;
168 
169  void DescriptorReady();
170  bool SendBlob(const DmxBuffer &data, const OSCTargetVector &targets);
171  bool SendIndividualFloats(const DmxBuffer &data,
172  OSCOutputGroup *group);
173  bool SendIndividualInts(const DmxBuffer &data,
174  OSCOutputGroup *group);
175  bool SendIntArray(const DmxBuffer &data,
176  const OSCTargetVector &targets);
177  bool SendFloatArray(const DmxBuffer &data,
178  const OSCTargetVector &targets);
179  bool SendMessageToTargets(lo_message message,
180  const OSCTargetVector &targets);
181  bool SendIndividualMessages(const DmxBuffer &data,
182  OSCOutputGroup *group,
183  const std::string &osc_type);
184 
185  static const uint16_t DEFAULT_OSC_PORT = 7770;
186  static const char OSC_PORT_VARIABLE[];
187 };
188 } // namespace osc
189 } // namespace plugin
190 } // namespace ola
191 #endif // PLUGINS_OSC_OSCNODE_H_