OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
serial_protocol.hpp
1#pragma once
3#include <ossia/detail/variant.hpp>
4#include <ossia/network/base/message_queue.hpp>
5#include <ossia/network/base/protocol.hpp>
6#include <ossia/network/context.hpp>
7#include <ossia/network/generic/wrapped_parameter.hpp>
8#include <ossia/network/sockets/cobs_framing.hpp>
9#include <ossia/network/sockets/fixed_length_framing.hpp>
10#include <ossia/network/sockets/line_framing.hpp>
11#include <ossia/network/sockets/no_framing.hpp>
12#include <ossia/network/sockets/serial_socket.hpp>
13#include <ossia/network/sockets/size_prefix_framing.hpp>
14#include <ossia/network/sockets/slip_framing.hpp>
15#include <ossia/network/sockets/stx_etx_framing.hpp>
16#include <ossia/network/sockets/var_size_prefix_framing.hpp>
17
18#include <ossia-qt/js_utilities.hpp>
19
20#include <boost/asio/error.hpp>
21#include <boost/asio/streambuf.hpp>
22
23#include <QObject>
24#include <QQmlComponent>
25#include <QSerialPort>
26#include <QThread>
27
28#include <span>
29#include <verdigris>
30
31class QQmlEngine;
32class QQmlComponent;
33
34namespace ossia
35{
36namespace net
37{
38struct serial_parameter_data_base
39{
40 serial_parameter_data_base() = default;
41 serial_parameter_data_base(const serial_parameter_data_base&) = default;
42 serial_parameter_data_base(serial_parameter_data_base&&) = default;
43 serial_parameter_data_base& operator=(const serial_parameter_data_base&) = default;
44 serial_parameter_data_base& operator=(serial_parameter_data_base&&) = default;
45 serial_parameter_data_base(const QJSValue& val)
46 {
47 request = val.property("request");
48 if(!request.isString() && !request.isCallable())
49 {
50 request = val.property("name");
51 }
52
53 if(val.hasProperty("osc_address"))
54 osc_address = val.property("osc_address").toString();
55 }
56
57 QJSValue request;
58 QString osc_address;
59};
60struct serial_parameter_data final
61 : public parameter_data
62 , public serial_parameter_data_base
63{
64 using base_data_type = serial_parameter_data_base;
65 serial_parameter_data() = default;
66 serial_parameter_data(const serial_parameter_data&) = default;
67 serial_parameter_data(serial_parameter_data&&) = default;
68 serial_parameter_data& operator=(const serial_parameter_data&) = default;
69 serial_parameter_data& operator=(serial_parameter_data&&) = default;
70
71 serial_parameter_data(const std::string& name)
72 : parameter_data{name}
73 {
74 }
75
76 serial_parameter_data(const QJSValue& val)
77 : parameter_data{ossia::qt::make_parameter_data(val)}
78 , serial_parameter_data_base{val}
79 {
80 }
81
82 bool valid() const noexcept
83 {
84 return request.isString() || request.isCallable() || type;
85 }
86};
87
88struct no_framing_socket : ossia::net::serial_socket<no_framing>
89{
90 using serial_socket::serial_socket;
91};
92struct size_framing_socket : ossia::net::serial_socket<size_prefix_framing>
93{
94 using serial_socket::serial_socket;
95};
96struct slip_framing_socket : ossia::net::serial_socket<slip_framing>
97{
98 using serial_socket::serial_socket;
99};
100struct line_framing_socket : ossia::net::serial_socket<line_framing>
101{
102 using serial_socket::serial_socket;
103};
104struct cobs_framing_socket : ossia::net::serial_socket<cobs_framing>
105{
106 using serial_socket::serial_socket;
107};
108struct stx_etx_framing_socket : ossia::net::serial_socket<stx_etx_framing>
109{
110 using serial_socket::serial_socket;
111};
112struct size_prefix_1byte_socket : ossia::net::serial_socket<size_prefix_1byte_framing>
113{
114 using serial_socket::serial_socket;
115};
116struct size_prefix_2byte_be_socket : ossia::net::serial_socket<size_prefix_2byte_be_framing>
117{
118 using serial_socket::serial_socket;
119};
120struct size_prefix_2byte_le_socket : ossia::net::serial_socket<size_prefix_2byte_le_framing>
121{
122 using serial_socket::serial_socket;
123};
124struct size_prefix_4byte_le_socket : ossia::net::serial_socket<size_prefix_4byte_le_framing>
125{
126 using serial_socket::serial_socket;
127};
128struct fixed_length_socket : ossia::net::serial_socket<fixed_length_framing>
129{
130 using serial_socket::serial_socket;
131};
132
133using framed_serial_socket = ossia::slow_variant<
134 no_framing_socket, size_framing_socket, slip_framing_socket, line_framing_socket,
135 cobs_framing_socket, stx_etx_framing_socket, size_prefix_1byte_socket,
136 size_prefix_2byte_be_socket, size_prefix_2byte_le_socket,
137 size_prefix_4byte_le_socket, fixed_length_socket>;
138
139struct serial_protocol_configuration
140{
141 ossia::net::framing framing;
142 std::string line_framing_delimiter;
143 std::size_t fixed_frame_size{64};
144
145 serial_configuration transport;
146};
147
148class OSSIA_EXPORT serial_wrapper final : public QObject
149{
150 W_OBJECT(serial_wrapper)
151
152public:
153 serial_wrapper(
154 const network_context_ptr& ctx,
155 const ossia::net::serial_protocol_configuration& port);
156 ~serial_wrapper() noexcept;
157
158 void write(QByteArray arg_1) E_SIGNAL(OSSIA_EXPORT, write, arg_1);
159 void read(QString txt, QByteArray raw) E_SIGNAL(OSSIA_EXPORT, read, txt, raw);
160
161 void on_write(const QByteArray& b) noexcept;
162 W_SLOT(on_write, (const QByteArray&))
163
164 void on_write(std::string_view b) noexcept;
165
166 void on_read(const QByteArray& arr);
167 W_SLOT(on_read)
168
169 void close();
170
171private:
172 framed_serial_socket make_socket(
173 const network_context_ptr& ctx,
174 const ossia::net::serial_protocol_configuration& port);
175 framed_serial_socket m_socket;
176 bool m_open{};
177};
178
179class serial_protocol;
180struct serial_protocol_object;
181
182using serial_parameter = wrapped_parameter<serial_parameter_data>;
183using serial_node = ossia::net::wrapped_node<serial_parameter_data, serial_parameter>;
184class OSSIA_EXPORT serial_protocol final
185 : public QObject
187{
188public:
189 // Param : the name of the serial port
190 serial_protocol(
191 const ossia::net::network_context_ptr&, const QByteArray& code,
192 const ossia::net::serial_configuration& bot);
193 ~serial_protocol() override;
194
195 bool pull(ossia::net::parameter_base&) override;
196 bool push(const ossia::net::parameter_base&, const ossia::value& v) override;
197 bool push_raw(const ossia::net::full_parameter_data& parameter_base) override;
198 bool observe(ossia::net::parameter_base&, bool) override;
199 bool update(ossia::net::node_base& node_base) override;
200
201 void set_device(ossia::net::device_base& dev) override;
202 void stop() override;
203
204 static serial_parameter_data read_data(const QJSValue& js) { return js; }
205
206 static serial_protocol_object load_serial_object_from_qml(
207 serial_protocol& proto, const ossia::net::network_context_ptr& ctx,
208 const ossia::net::serial_configuration& cfg);
209 void create(
210 const ossia::net::network_context_ptr&,
211 const ossia::net::serial_configuration& cfg);
212 void on_read(const QString& txt, const QByteArray&);
213 void do_write(const ossia::net::parameter_base&, const ossia::value& v);
214 void do_write_osc(const serial_parameter&, const ossia::value& v);
215 void do_write_osc_bundle(
216 std::span<std::pair<const serial_parameter*, const ossia::value*>> vec);
217 void do_write_osc_impl(
218 const serial_parameter& addr, const ossia::value& v, std::string& str);
219
220private:
221 void startup_engine();
222 void create_object(QQmlComponent::Status status);
223
224 ossia::net::network_context_ptr m_context;
225 ossia::net::serial_configuration m_cfg;
226
227 QQmlEngine* m_engine{};
228 QQmlComponent* m_component{};
229
230 ossia::net::device_base* m_device{};
231 QObject* m_object{};
232 QJSValue m_jsObj{};
233 QJSValue m_onTextMessage{};
234 QJSValue m_onBinaryMessage{};
235 QJSValue m_onRead{};
236 std::shared_ptr<serial_wrapper> m_port;
237 QByteArray m_code;
238
239 QObject* m_threadWorker{};
240 QThread m_thread{};
241
242 coalescing_queue m_queue;
243 std::optional<double> m_coalesce{};
244 bool m_osc{};
245};
246using serial_device = ossia::net::wrapped_device<serial_node, serial_protocol>;
247
248class OSSIA_EXPORT Serial : public QObject
249{
250};
251
252}
253}
Root of a device tree.
Definition ossia/network/base/device.hpp:58
The node_base class.
Definition node.hpp:48
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The protocol_base class.
Definition protocol.hpp:40
The value class.
Definition value.hpp:173
Definition git_info.h:7
Full information about a parameter.
Definition parameter_data.hpp:61