]> sigrok.org Git - libsigrok.git/blame - bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp
bindings/cxx: Increase compatibility for glibmm-2.68
[libsigrok.git] / bindings / cxx / include / libsigrokcxx / libsigrokcxx.hpp
CommitLineData
c23c8659
ML
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2013-2014 Martin Ling <martin-sigrok@earth.li>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
07443fd2
ML
20/**
21
22@mainpage API Reference
23
24Introduction
25------------
26
52ff4f6a
UH
27The libsigrokcxx API provides an object-oriented C++ interface to the
28functionality in libsigrok, including automatic memory and resource management.
07443fd2
ML
29
30It is built on top of the public libsigrok C API, and is designed to be used as
31a standalone alternative API. Programs should not mix usage of the C and C++
32APIs; the C++ interface code needs to have full control of all C API calls for
33resources to be managed correctly.
34
35Memory management
36-----------------
37
38All runtime objects created through the C++ API are passed and accessed via
39shared pointers, using the C++11 std::shared_ptr implementation. This means
40that a reference count is kept for each object.
41
42Shared pointers can be copied and assigned in a user's program, automatically
43updating their reference count and deleting objects when they are no longer in
44use. The C++ interface code also keeps track of internal dependencies between
45libsigrok resources, and ensures that objects are not prematurely deleted when
46their resources are in use by other objects.
47
52ff4f6a
UH
48This means that management of libsigrokcxx objects and their underlying
49libsigrok resources can be treated as fully automatic. As long as all shared
50pointers to objects are deleted or reassigned when no longer in use, all
51underlying resources will be released at the right time.
07443fd2
ML
52
53Getting started
54---------------
55
56Usage of the C++ API needs to begin with a call to sigrok::Context::create().
57This will create the global libsigrok context and returns a shared pointer to
58the sigrok::Context object. Methods on this object provide access to the
59hardware drivers, input and output formats supported by the library, as well
60as means of creating other objects such as sessions and triggers.
61
62Error handling
63--------------
64
65When any libsigrok C API call returns an error, a sigrok::Error exception is
66raised, which provides access to the error code and description.
67
68*/
69
1b40fdb8
UH
70#ifndef LIBSIGROKCXX_HPP
71#define LIBSIGROKCXX_HPP
c23c8659 72
8b2a1843 73#include <libsigrok/libsigrok.h>
cea8c312
DE
74
75/* Suppress warnings due to glibmm's use of std::auto_ptr<> in a public
76 * header file. To be removed once glibmm is fixed. */
77G_GNUC_BEGIN_IGNORE_DEPRECATIONS
e0e6aecc 78#include <glibmm.h>
cea8c312 79G_GNUC_END_IGNORE_DEPRECATIONS
c23c8659 80
5652085a 81#include <functional>
c23c8659
ML
82#include <stdexcept>
83#include <memory>
84#include <vector>
85#include <map>
4c7c4194 86#include <set>
c23c8659
ML
87
88namespace sigrok
89{
90
c23c8659
ML
91/* Forward declarations */
92class SR_API Error;
93class SR_API Context;
94class SR_API Driver;
95class SR_API Device;
96class SR_API HardwareDevice;
97class SR_API Channel;
c23c8659
ML
98class SR_API Session;
99class SR_API ConfigKey;
12f2f640 100class SR_API Capability;
c23c8659
ML
101class SR_API InputFormat;
102class SR_API OutputFormat;
3cd4b381 103class SR_API OutputFlag;
c23c8659
ML
104class SR_API LogLevel;
105class SR_API ChannelGroup;
106class SR_API Trigger;
107class SR_API TriggerStage;
108class SR_API TriggerMatch;
109class SR_API TriggerMatchType;
110class SR_API ChannelType;
111class SR_API Packet;
112class SR_API PacketPayload;
113class SR_API PacketType;
114class SR_API Quantity;
115class SR_API Unit;
116class SR_API QuantityFlag;
0cee3a3e 117class SR_API Rational;
ca3291e3
ML
118class SR_API Input;
119class SR_API InputDevice;
c23c8659
ML
120class SR_API Output;
121class SR_API DataType;
58aa1f83 122class SR_API Option;
9fa5b426 123class SR_API UserDevice;
c23c8659
ML
124
125/** Exception thrown when an error code is returned by any libsigrok call. */
6c6dd732 126class SR_API Error: public std::exception
c23c8659
ML
127{
128public:
6c11b496 129 explicit Error(int result);
15914cdb 130 ~Error() noexcept;
c23c8659 131 const int result;
15914cdb 132 const char *what() const noexcept;
c23c8659
ML
133};
134
541c855e 135/* Base template for classes whose resources are owned by a parent object. */
d5d7b09e 136template <class Class, class Parent>
541c855e 137class SR_API ParentOwned
c23c8659 138{
21d1bec6
DE
139private:
140 /* Weak pointer for shared_from_this() implementation. */
6c6dd732 141 std::weak_ptr<Class> _weak_this;
21d1bec6
DE
142
143 static void reset_parent(Class *object)
144 {
145 if (!object->_parent)
146 throw Error(SR_ERR_BUG);
147 object->_parent.reset();
148 }
149
7649683c 150protected:
07443fd2 151 /* Parent object which owns this child object's underlying structure.
c23c8659
ML
152
153 This shared pointer will be null when this child is unused, but
154 will be assigned to point to the parent before any shared pointer
155 to this child is handed out to the user.
156
157 When the reference count of this child falls to zero, this shared
158 pointer to its parent is reset by a custom deleter on the child's
159 shared pointer.
160
161 This strategy ensures that the destructors for both the child and
162 the parent are called at the correct time, i.e. only when all
163 references to both the parent and all its children are gone. */
6c6dd732 164 std::shared_ptr<Parent> _parent;
7649683c 165
d5d7b09e 166 ParentOwned() {}
0d0170ae 167
0d0170ae 168 /* Note, this implementation will create a new smart_ptr if none exists. */
6c6dd732 169 std::shared_ptr<Class> shared_from_this()
0d0170ae 170 {
6c6dd732 171 std::shared_ptr<Class> shared = _weak_this.lock();
0d0170ae 172
67b82fc9 173 if (!shared)
0d0170ae 174 {
67b82fc9 175 shared.reset(static_cast<Class *>(this), &reset_parent);
3b161085 176 _weak_this = shared;
0d0170ae
ML
177 }
178
179 return shared;
180 }
181
6c6dd732 182 std::shared_ptr<Class> share_owned_by(std::shared_ptr<Parent> parent)
7649683c 183 {
78132e2a
ML
184 if (!parent)
185 throw Error(SR_ERR_BUG);
3b161085 186 this->_parent = parent;
0d0170ae 187 return shared_from_this();
7649683c 188 }
0d0170ae 189
67b82fc9
DE
190public:
191 /* Get parent object that owns this object. */
6c6dd732 192 std::shared_ptr<Parent> parent()
7649683c 193 {
67b82fc9 194 return _parent;
7649683c 195 }
c23c8659
ML
196};
197
90e89c2a 198/* Base template for classes whose resources are owned by the user. */
d5d7b09e 199template <class Class>
6c6dd732 200class SR_API UserOwned : public std::enable_shared_from_this<Class>
90e89c2a 201{
90e89c2a 202protected:
d5d7b09e 203 UserOwned() {}
b4ed33a7 204
6c6dd732 205 std::shared_ptr<Class> shared_from_this()
67b82fc9 206 {
6c6dd732 207 auto shared = std::enable_shared_from_this<Class>::shared_from_this();
67b82fc9
DE
208 if (!shared)
209 throw Error(SR_ERR_BUG);
210 return shared;
211 }
90e89c2a
ML
212};
213
c23c8659 214/** Type of log callback */
6c6dd732 215typedef std::function<void(const LogLevel *, std::string message)> LogCallbackFunction;
c23c8659 216
e2eaf858
DE
217/** Resource reader delegate. */
218class SR_API ResourceReader
219{
220public:
221 ResourceReader() {}
222 virtual ~ResourceReader();
223private:
224 /** Resource open hook. */
6c6dd732 225 virtual void open(struct sr_resource *res, std::string name) = 0;
e2eaf858
DE
226 /** Resource close hook. */
227 virtual void close(struct sr_resource *res) = 0;
228 /** Resource read hook. */
229 virtual size_t read(const struct sr_resource *res, void *buf, size_t count) = 0;
230
231 static SR_PRIV int open_callback(struct sr_resource *res,
0ab8e5d2 232 const char *name, void *cb_data) noexcept;
e2eaf858 233 static SR_PRIV int close_callback(struct sr_resource *res,
0ab8e5d2 234 void *cb_data) noexcept;
32ba0d80 235 static SR_PRIV gssize read_callback(const struct sr_resource *res,
0ab8e5d2 236 void *buf, size_t count, void *cb_data) noexcept;
e2eaf858
DE
237 friend class Context;
238};
239
07443fd2 240/** The global libsigrok context */
d5d7b09e 241class SR_API Context : public UserOwned<Context>
c23c8659
ML
242{
243public:
244 /** Create new context */
6c6dd732 245 static std::shared_ptr<Context> create();
c23c8659 246 /** libsigrok package version. */
6c6dd732 247 static std::string package_version();
c23c8659 248 /** libsigrok library version. */
6c6dd732 249 static std::string lib_version();
c23c8659 250 /** Available hardware drivers, indexed by name. */
6c6dd732 251 std::map<std::string, std::shared_ptr<Driver> > drivers();
c23c8659 252 /** Available input formats, indexed by name. */
6c6dd732 253 std::map<std::string, std::shared_ptr<InputFormat> > input_formats();
092843eb 254 /** Lookup the responsible input module for an input file. */
6c6dd732 255 std::shared_ptr<InputFormat> input_format_match(std::string filename);
c23c8659 256 /** Available output formats, indexed by name. */
6c6dd732 257 std::map<std::string, std::shared_ptr<OutputFormat> > output_formats();
c23c8659 258 /** Current log level. */
15bebf57 259 const LogLevel *log_level() const;
b6f411ac
ML
260 /** Set the log level.
261 * @param level LogLevel to use. */
c23c8659 262 void set_log_level(const LogLevel *level);
b6f411ac
ML
263 /** Set the log callback.
264 * @param callback Callback of the form callback(LogLevel, string). */
c23c8659
ML
265 void set_log_callback(LogCallbackFunction callback);
266 /** Set the log callback to the default handler. */
267 void set_log_callback_default();
e2eaf858
DE
268 /** Install a delegate for reading resource files.
269 * @param reader The resource reader delegate, or nullptr to unset. */
270 void set_resource_reader(ResourceReader *reader);
c23c8659 271 /** Create a new session. */
6c6dd732 272 std::shared_ptr<Session> create_session();
9fa5b426 273 /** Create a new user device. */
6c6dd732
DA
274 std::shared_ptr<UserDevice> create_user_device(
275 std::string vendor, std::string model, std::string version);
304be4a7 276 /** Create a header packet. */
e446b3c4 277 std::shared_ptr<Packet> create_header_packet(Glib::DateTime start_time);
304be4a7 278 /** Create a meta packet. */
6c6dd732
DA
279 std::shared_ptr<Packet> create_meta_packet(
280 std::map<const ConfigKey *, Glib::VariantBase> config);
304be4a7 281 /** Create a logic packet. */
6c6dd732 282 std::shared_ptr<Packet> create_logic_packet(
304be4a7
ML
283 void *data_pointer, size_t data_length, unsigned int unit_size);
284 /** Create an analog packet. */
6c6dd732
DA
285 std::shared_ptr<Packet> create_analog_packet(
286 std::vector<std::shared_ptr<Channel> > channels,
895cbcdd 287 const float *data_pointer, unsigned int num_samples, const Quantity *mq,
6c6dd732 288 const Unit *unit, std::vector<const QuantityFlag *> mqflags);
a9ed2eb0 289 /** Create an end packet. */
6c6dd732 290 std::shared_ptr<Packet> create_end_packet();
b6f411ac
ML
291 /** Load a saved session.
292 * @param filename File name string. */
6c6dd732 293 std::shared_ptr<Session> load_session(std::string filename);
b6f411ac
ML
294 /** Create a new trigger.
295 * @param name Name string for new trigger. */
6c6dd732 296 std::shared_ptr<Trigger> create_trigger(std::string name);
ca3291e3
ML
297 /** Open an input file.
298 * @param filename File name string. */
6c6dd732 299 std::shared_ptr<Input> open_file(std::string filename);
ca3291e3
ML
300 /** Open an input stream based on header data.
301 * @param header Initial data from stream. */
6c6dd732
DA
302 std::shared_ptr<Input> open_stream(std::string header);
303 std::map<std::string, std::string> serials(std::shared_ptr<Driver> driver) const;
21d1bec6 304private:
d5d7b09e 305 struct sr_context *_structure;
6c6dd732
DA
306 std::map<std::string, std::unique_ptr<Driver> > _drivers;
307 std::map<std::string, std::unique_ptr<InputFormat> > _input_formats;
308 std::map<std::string, std::unique_ptr<OutputFormat> > _output_formats;
3b161085
ML
309 Session *_session;
310 LogCallbackFunction _log_callback;
c23c8659
ML
311 Context();
312 ~Context();
c23c8659
ML
313 friend class Session;
314 friend class Driver;
01451225 315 friend struct std::default_delete<Context>;
c23c8659
ML
316};
317
c23c8659
ML
318/** An object that can be configured. */
319class SR_API Configurable
320{
321public:
36bb818d 322 /** Supported configuration keys. */
6c6dd732 323 std::set<const ConfigKey *> config_keys() const;
b6f411ac
ML
324 /** Read configuration for the given key.
325 * @param key ConfigKey to read. */
15bebf57 326 Glib::VariantBase config_get(const ConfigKey *key) const;
b6f411ac
ML
327 /** Set configuration for the given key to a specified value.
328 * @param key ConfigKey to set.
329 * @param value Value to set. */
d370545d 330 void config_set(const ConfigKey *key, const Glib::VariantBase &value);
b6f411ac
ML
331 /** Enumerate available values for the given configuration key.
332 * @param key ConfigKey to enumerate values for. */
15bebf57 333 Glib::VariantContainerBase config_list(const ConfigKey *key) const;
36bb818d
ML
334 /** Enumerate configuration capabilities for the given configuration key.
335 * @param key ConfigKey to enumerate capabilities for. */
6c6dd732 336 std::set<const Capability *> config_capabilities(const ConfigKey *key) const;
36bb818d
ML
337 /** Check whether a configuration capability is supported for a given key.
338 * @param key ConfigKey to check.
e7eb2968 339 * @param capability Capability to check for. */
36bb818d 340 bool config_check(const ConfigKey *key, const Capability *capability) const;
c23c8659
ML
341protected:
342 Configurable(
343 struct sr_dev_driver *driver,
344 struct sr_dev_inst *sdi,
345 struct sr_channel_group *channel_group);
346 virtual ~Configurable();
347 struct sr_dev_driver *config_driver;
348 struct sr_dev_inst *config_sdi;
349 struct sr_channel_group *config_channel_group;
350};
351
59b74d28 352/** A hardware driver provided by the library */
36bb818d 353class SR_API Driver : public ParentOwned<Driver, Context>, public Configurable
59b74d28
ML
354{
355public:
356 /** Name of this driver. */
6c6dd732 357 std::string name() const;
59b74d28 358 /** Long name for this driver. */
6c6dd732 359 std::string long_name() const;
36bb818d 360 /** Scan options supported by this driver. */
6c6dd732 361 std::set<const ConfigKey *> scan_options() const;
59b74d28
ML
362 /** Scan for devices and return a list of devices found.
363 * @param options Mapping of (ConfigKey, value) pairs. */
6c6dd732
DA
364 std::vector<std::shared_ptr<HardwareDevice> > scan(std::map<const ConfigKey *, Glib::VariantBase>
365 options = std::map<const ConfigKey *, Glib::VariantBase>());
21d1bec6 366private:
d5d7b09e 367 struct sr_dev_driver *_structure;
3b161085 368 bool _initialized;
6c6dd732 369 std::vector<HardwareDevice *> _devices;
6c11b496 370 explicit Driver(struct sr_dev_driver *structure);
59b74d28
ML
371 ~Driver();
372 friend class Context;
373 friend class HardwareDevice;
374 friend class ChannelGroup;
01451225 375 friend struct std::default_delete<Driver>;
59b74d28
ML
376};
377
07443fd2 378/** A generic device, either hardware or virtual */
d01d2314 379class SR_API Device : public Configurable
c23c8659
ML
380{
381public:
382 /** Vendor name for this device. */
6c6dd732 383 std::string vendor() const;
c23c8659 384 /** Model name for this device. */
6c6dd732 385 std::string model() const;
c23c8659 386 /** Version string for this device. */
6c6dd732 387 std::string version() const;
d1075e5a 388 /** Serial number for this device. */
6c6dd732 389 std::string serial_number() const;
d1075e5a 390 /** Connection ID for this device. */
6c6dd732 391 std::string connection_id() const;
c23c8659 392 /** List of the channels available on this device. */
6c6dd732 393 std::vector<std::shared_ptr<Channel> > channels();
6be7a7f2 394 /** Channel groups available on this device, indexed by name. */
6c6dd732 395 std::map<std::string, std::shared_ptr<ChannelGroup> > channel_groups();
c23c8659
ML
396 /** Open device. */
397 void open();
398 /** Close device. */
399 void close();
400protected:
6c11b496 401 explicit Device(struct sr_dev_inst *structure);
c23c8659 402 ~Device();
6c6dd732
DA
403 virtual std::shared_ptr<Device> get_shared_from_this() = 0;
404 std::shared_ptr<Channel> get_channel(struct sr_channel *ptr);
21d1bec6 405
3b161085 406 struct sr_dev_inst *_structure;
6c6dd732 407 std::map<struct sr_channel *, std::unique_ptr<Channel> > _channels;
21d1bec6 408private:
6c6dd732 409 std::map<std::string, std::unique_ptr<ChannelGroup> > _channel_groups;
a98729a7 410
c23c8659
ML
411 friend class Session;
412 friend class Channel;
413 friend class ChannelGroup;
414 friend class Output;
dd13d47a 415 friend class Analog;
01451225 416 friend struct std::default_delete<Device>;
c23c8659
ML
417};
418
07443fd2 419/** A real hardware device, connected via a driver */
6e5240f4 420class SR_API HardwareDevice :
d5d7b09e 421 public UserOwned<HardwareDevice>,
6e5240f4 422 public Device
c23c8659
ML
423{
424public:
425 /** Driver providing this device. */
6c6dd732 426 std::shared_ptr<Driver> driver();
21d1bec6 427private:
6c6dd732 428 HardwareDevice(std::shared_ptr<Driver> driver, struct sr_dev_inst *structure);
c23c8659 429 ~HardwareDevice();
6c6dd732
DA
430 std::shared_ptr<Device> get_shared_from_this();
431 std::shared_ptr<Driver> _driver;
a98729a7 432
c23c8659
ML
433 friend class Driver;
434 friend class ChannelGroup;
01451225 435 friend struct std::default_delete<HardwareDevice>;
c23c8659
ML
436};
437
9fa5b426
ML
438/** A virtual device, created by the user */
439class SR_API UserDevice :
d5d7b09e 440 public UserOwned<UserDevice>,
9fa5b426
ML
441 public Device
442{
443public:
444 /** Add a new channel to this device. */
6c6dd732 445 std::shared_ptr<Channel> add_channel(unsigned int index, const ChannelType *type, std::string name);
21d1bec6 446private:
6c6dd732 447 UserDevice(std::string vendor, std::string model, std::string version);
9fa5b426 448 ~UserDevice();
6c6dd732 449 std::shared_ptr<Device> get_shared_from_this();
a98729a7 450
9fa5b426 451 friend class Context;
01451225 452 friend struct std::default_delete<UserDevice>;
9fa5b426
ML
453};
454
07443fd2 455/** A channel on a device */
bf52cc8c 456class SR_API Channel :
d5d7b09e 457 public ParentOwned<Channel, Device>
c23c8659
ML
458{
459public:
460 /** Current name of this channel. */
6c6dd732 461 std::string name() const;
b6f411ac
ML
462 /** Set the name of this channel. *
463 * @param name Name string to set. */
6c6dd732 464 void set_name(std::string name);
c23c8659 465 /** Type of this channel. */
15bebf57 466 const ChannelType *type() const;
c23c8659 467 /** Enabled status of this channel. */
15bebf57 468 bool enabled() const;
b6f411ac
ML
469 /** Set the enabled status of this channel.
470 * @param value Boolean value to set. */
c23c8659 471 void set_enabled(bool value);
06bd935e 472 /** Get the index number of this channel. */
15bebf57 473 unsigned int index() const;
21d1bec6 474private:
6c11b496 475 explicit Channel(struct sr_channel *structure);
c23c8659 476 ~Channel();
d5d7b09e 477 struct sr_channel *_structure;
3b161085 478 const ChannelType * const _type;
c23c8659 479 friend class Device;
9fa5b426 480 friend class UserDevice;
c23c8659
ML
481 friend class ChannelGroup;
482 friend class Session;
483 friend class TriggerStage;
304be4a7 484 friend class Context;
01451225 485 friend struct std::default_delete<Channel>;
c23c8659
ML
486};
487
07443fd2 488/** A group of channels on a device, which share some configuration */
c23c8659 489class SR_API ChannelGroup :
d5d7b09e 490 public ParentOwned<ChannelGroup, Device>,
c23c8659
ML
491 public Configurable
492{
493public:
494 /** Name of this channel group. */
6c6dd732 495 std::string name() const;
c23c8659 496 /** List of the channels in this group. */
6c6dd732 497 std::vector<std::shared_ptr<Channel> > channels();
21d1bec6 498private:
f17b4546 499 ChannelGroup(const Device *device, struct sr_channel_group *structure);
c23c8659 500 ~ChannelGroup();
6c6dd732 501 std::vector<Channel *> _channels;
6be7a7f2 502 friend class Device;
01451225 503 friend struct std::default_delete<ChannelGroup>;
c23c8659
ML
504};
505
07443fd2 506/** A trigger configuration */
d5d7b09e 507class SR_API Trigger : public UserOwned<Trigger>
c23c8659
ML
508{
509public:
b6f411ac 510 /** Name of this trigger configuration. */
6c6dd732 511 std::string name() const;
b6f411ac 512 /** List of the stages in this trigger. */
6c6dd732 513 std::vector<std::shared_ptr<TriggerStage> > stages();
b6f411ac 514 /** Add a new stage to this trigger. */
6c6dd732 515 std::shared_ptr<TriggerStage> add_stage();
21d1bec6 516private:
6c6dd732 517 Trigger(std::shared_ptr<Context> context, std::string name);
c23c8659 518 ~Trigger();
d5d7b09e 519 struct sr_trigger *_structure;
6c6dd732
DA
520 std::shared_ptr<Context> _context;
521 std::vector<std::unique_ptr<TriggerStage> > _stages;
c23c8659 522 friend class Context;
6fa0eb86 523 friend class Session;
01451225 524 friend struct std::default_delete<Trigger>;
c23c8659
ML
525};
526
07443fd2 527/** A stage in a trigger configuration */
bf52cc8c 528class SR_API TriggerStage :
d5d7b09e 529 public ParentOwned<TriggerStage, Trigger>
c23c8659
ML
530{
531public:
b6f411ac 532 /** Index number of this stage. */
15bebf57 533 int number() const;
b6f411ac 534 /** List of match conditions on this stage. */
6c6dd732 535 std::vector<std::shared_ptr<TriggerMatch> > matches();
b6f411ac
ML
536 /** Add a new match condition to this stage.
537 * @param channel Channel to match on.
538 * @param type TriggerMatchType to apply. */
6c6dd732 539 void add_match(std::shared_ptr<Channel> channel, const TriggerMatchType *type);
b6f411ac
ML
540 /** Add a new match condition to this stage.
541 * @param channel Channel to match on.
542 * @param type TriggerMatchType to apply.
543 * @param value Threshold value. */
6c6dd732 544 void add_match(std::shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
21d1bec6 545private:
d5d7b09e 546 struct sr_trigger_stage *_structure;
6c6dd732 547 std::vector<std::unique_ptr<TriggerMatch> > _matches;
6c11b496 548 explicit TriggerStage(struct sr_trigger_stage *structure);
c23c8659
ML
549 ~TriggerStage();
550 friend class Trigger;
01451225 551 friend struct std::default_delete<TriggerStage>;
c23c8659
ML
552};
553
07443fd2 554/** A match condition in a trigger configuration */
bf52cc8c 555class SR_API TriggerMatch :
d5d7b09e 556 public ParentOwned<TriggerMatch, TriggerStage>
c23c8659
ML
557{
558public:
b6f411ac 559 /** Channel this condition matches on. */
6c6dd732 560 std::shared_ptr<Channel> channel();
b6f411ac 561 /** Type of match. */
15bebf57 562 const TriggerMatchType *type() const;
b6f411ac 563 /** Threshold value. */
15bebf57 564 float value() const;
21d1bec6 565private:
6c6dd732 566 TriggerMatch(struct sr_trigger_match *structure, std::shared_ptr<Channel> channel);
c23c8659 567 ~TriggerMatch();
d5d7b09e 568 struct sr_trigger_match *_structure;
6c6dd732 569 std::shared_ptr<Channel> _channel;
c23c8659 570 friend class TriggerStage;
01451225 571 friend struct std::default_delete<TriggerMatch>;
c23c8659
ML
572};
573
f91cf612 574/** Type of session stopped callback */
6c6dd732 575typedef std::function<void()> SessionStoppedCallback;
f91cf612 576
c23c8659 577/** Type of datafeed callback */
6c6dd732 578typedef std::function<void(std::shared_ptr<Device>, std::shared_ptr<Packet>)>
c23c8659
ML
579 DatafeedCallbackFunction;
580
07443fd2 581/* Data required for C callback function to call a C++ datafeed callback */
c23c8659
ML
582class SR_PRIV DatafeedCallbackData
583{
584public:
585 void run(const struct sr_dev_inst *sdi,
586 const struct sr_datafeed_packet *pkt);
21d1bec6 587private:
3b161085 588 DatafeedCallbackFunction _callback;
c23c8659
ML
589 DatafeedCallbackData(Session *session,
590 DatafeedCallbackFunction callback);
3b161085 591 Session *_session;
c23c8659
ML
592 friend class Session;
593};
594
cac58676
ML
595/** A virtual device associated with a stored session */
596class SR_API SessionDevice :
d5d7b09e 597 public ParentOwned<SessionDevice, Session>,
cac58676
ML
598 public Device
599{
21d1bec6 600private:
6c11b496 601 explicit SessionDevice(struct sr_dev_inst *sdi);
cac58676 602 ~SessionDevice();
6c6dd732 603 std::shared_ptr<Device> get_shared_from_this();
a98729a7 604
cac58676 605 friend class Session;
01451225 606 friend struct std::default_delete<SessionDevice>;
cac58676
ML
607};
608
07443fd2 609/** A sigrok session */
d5d7b09e 610class SR_API Session : public UserOwned<Session>
c23c8659
ML
611{
612public:
b6f411ac
ML
613 /** Add a device to this session.
614 * @param device Device to add. */
6c6dd732 615 void add_device(std::shared_ptr<Device> device);
c23c8659 616 /** List devices attached to this session. */
6c6dd732 617 std::vector<std::shared_ptr<Device> > devices();
c23c8659
ML
618 /** Remove all devices from this session. */
619 void remove_devices();
b6f411ac
ML
620 /** Add a datafeed callback to this session.
621 * @param callback Callback of the form callback(Device, Packet). */
c23c8659
ML
622 void add_datafeed_callback(DatafeedCallbackFunction callback);
623 /** Remove all datafeed callbacks from this session. */
624 void remove_datafeed_callbacks();
c23c8659
ML
625 /** Start the session. */
626 void start();
627 /** Run the session event loop. */
628 void run();
629 /** Stop the session. */
630 void stop();
f91cf612
DE
631 /** Return whether the session is running. */
632 bool is_running() const;
633 /** Set callback to be invoked on session stop. */
634 void set_stopped_callback(SessionStoppedCallback callback);
6fa0eb86 635 /** Get current trigger setting. */
6c6dd732 636 std::shared_ptr<Trigger> trigger();
624d1610 637 /** Get the context. */
6c6dd732 638 std::shared_ptr<Context> context();
b6f411ac
ML
639 /** Set trigger setting.
640 * @param trigger Trigger object to use. */
6c6dd732 641 void set_trigger(std::shared_ptr<Trigger> trigger);
1411f7d8 642 /** Get filename this session was loaded from. */
6c6dd732 643 std::string filename() const;
21d1bec6 644private:
6c6dd732
DA
645 explicit Session(std::shared_ptr<Context> context);
646 Session(std::shared_ptr<Context> context, std::string filename);
c23c8659 647 ~Session();
6c6dd732 648 std::shared_ptr<Device> get_device(const struct sr_dev_inst *sdi);
d5d7b09e 649 struct sr_session *_structure;
6c6dd732
DA
650 const std::shared_ptr<Context> _context;
651 std::map<const struct sr_dev_inst *, std::unique_ptr<SessionDevice> > _owned_devices;
652 std::map<const struct sr_dev_inst *, std::shared_ptr<Device> > _other_devices;
653 std::vector<std::unique_ptr<DatafeedCallbackData> > _datafeed_callbacks;
f91cf612 654 SessionStoppedCallback _stopped_callback;
6c6dd732
DA
655 std::string _filename;
656 std::shared_ptr<Trigger> _trigger;
a98729a7 657
c23c8659
ML
658 friend class Context;
659 friend class DatafeedCallbackData;
98d39b91 660 friend class SessionDevice;
01451225 661 friend struct std::default_delete<Session>;
c23c8659
ML
662};
663
07443fd2 664/** A packet on the session datafeed */
d5d7b09e 665class SR_API Packet : public UserOwned<Packet>
c23c8659
ML
666{
667public:
90ba83f2 668 /** Type of this packet. */
15bebf57 669 const PacketType *type() const;
c23c8659 670 /** Payload of this packet. */
6c6dd732 671 std::shared_ptr<PacketPayload> payload();
21d1bec6 672private:
6c6dd732 673 Packet(std::shared_ptr<Device> device,
2928f47d 674 const struct sr_datafeed_packet *structure);
c23c8659 675 ~Packet();
d5d7b09e 676 const struct sr_datafeed_packet *_structure;
6c6dd732
DA
677 std::shared_ptr<Device> _device;
678 std::unique_ptr<PacketPayload> _payload;
a98729a7 679
c23c8659
ML
680 friend class Session;
681 friend class Output;
682 friend class DatafeedCallbackData;
2928f47d
ML
683 friend class Header;
684 friend class Meta;
685 friend class Logic;
dd13d47a 686 friend class Analog;
304be4a7 687 friend class Context;
01451225 688 friend struct std::default_delete<Packet>;
c23c8659
ML
689};
690
07443fd2 691/** Abstract base class for datafeed packet payloads */
c23c8659
ML
692class SR_API PacketPayload
693{
694protected:
695 PacketPayload();
696 virtual ~PacketPayload() = 0;
67b82fc9 697private:
6c6dd732 698 virtual std::shared_ptr<PacketPayload> share_owned_by(std::shared_ptr<Packet> parent) = 0;
21d1bec6 699
c23c8659
ML
700 friend class Packet;
701 friend class Output;
01451225 702 friend struct std::default_delete<PacketPayload>;
c23c8659
ML
703};
704
2928f47d 705/** Payload of a datafeed header packet */
4cd883a7 706class SR_API Header :
d5d7b09e 707 public ParentOwned<Header, Packet>,
4cd883a7 708 public PacketPayload
2928f47d
ML
709{
710public:
b6f411ac 711 /* Feed version number. */
15bebf57 712 int feed_version() const;
b6f411ac 713 /* Start time of this session. */
e446b3c4 714 Glib::DateTime start_time() const;
21d1bec6 715private:
6c11b496 716 explicit Header(const struct sr_datafeed_header *structure);
2928f47d 717 ~Header();
6c6dd732 718 std::shared_ptr<PacketPayload> share_owned_by(std::shared_ptr<Packet> parent);
d5d7b09e
DE
719
720 const struct sr_datafeed_header *_structure;
721
2928f47d
ML
722 friend class Packet;
723};
724
725/** Payload of a datafeed metadata packet */
4cd883a7 726class SR_API Meta :
d5d7b09e 727 public ParentOwned<Meta, Packet>,
4cd883a7 728 public PacketPayload
2928f47d
ML
729{
730public:
b6f411ac 731 /* Mapping of (ConfigKey, value) pairs. */
6c6dd732 732 std::map<const ConfigKey *, Glib::VariantBase> config() const;
21d1bec6 733private:
6c11b496 734 explicit Meta(const struct sr_datafeed_meta *structure);
2928f47d 735 ~Meta();
6c6dd732 736 std::shared_ptr<PacketPayload> share_owned_by(std::shared_ptr<Packet> parent);
d5d7b09e
DE
737
738 const struct sr_datafeed_meta *_structure;
6c6dd732 739 std::map<const ConfigKey *, Glib::VariantBase> _config;
d5d7b09e 740
2928f47d
ML
741 friend class Packet;
742};
743
07443fd2 744/** Payload of a datafeed packet with logic data */
4cd883a7 745class SR_API Logic :
d5d7b09e 746 public ParentOwned<Logic, Packet>,
4cd883a7 747 public PacketPayload
c23c8659 748{
2928f47d
ML
749public:
750 /* Pointer to data. */
3b161085 751 void *data_pointer();
2928f47d 752 /* Data length in bytes. */
15bebf57 753 size_t data_length() const;
2928f47d 754 /* Size of each sample in bytes. */
15bebf57 755 unsigned int unit_size() const;
21d1bec6 756private:
6c11b496 757 explicit Logic(const struct sr_datafeed_logic *structure);
c23c8659 758 ~Logic();
6c6dd732 759 std::shared_ptr<PacketPayload> share_owned_by(std::shared_ptr<Packet> parent);
d5d7b09e
DE
760
761 const struct sr_datafeed_logic *_structure;
762
c23c8659 763 friend class Packet;
6ad2fbaa
SA
764 friend class Analog;
765 friend struct std::default_delete<Logic>;
c23c8659
ML
766};
767
07443fd2 768/** Payload of a datafeed packet with analog data */
dd13d47a 769class SR_API Analog :
d5d7b09e 770 public ParentOwned<Analog, Packet>,
4cd883a7 771 public PacketPayload
c23c8659
ML
772{
773public:
2928f47d 774 /** Pointer to data. */
dd13d47a 775 void *data_pointer();
c5d081f7
SA
776 /**
777 * Fills dest pointer with the analog data converted to float.
778 * The pointer must have space for num_samples() floats.
779 */
780 void get_data_as_float(float *dest);
c23c8659 781 /** Number of samples in this packet. */
15bebf57 782 unsigned int num_samples() const;
2928f47d 783 /** Channels for which this packet contains data. */
6c6dd732 784 std::vector<std::shared_ptr<Channel> > channels();
0cee3a3e
SA
785 /** Size of a single sample in bytes. */
786 unsigned int unitsize() const;
787 /** Samples use a signed data type. */
788 bool is_signed() const;
789 /** Samples use float. */
790 bool is_float() const;
791 /** Samples are stored in big-endian order. */
792 bool is_bigendian() const;
793 /**
794 * Number of significant digits after the decimal point if positive,
795 * or number of non-significant digits before the decimal point if negative
796 * (refers to the value we actually read on the wire).
797 */
798 int digits() const;
799 /** TBD */
800 bool is_digits_decimal() const;
801 /** TBD */
6c6dd732 802 std::shared_ptr<Rational> scale();
0cee3a3e 803 /** TBD */
6c6dd732 804 std::shared_ptr<Rational> offset();
c23c8659 805 /** Measured quantity of the samples in this packet. */
15bebf57 806 const Quantity *mq() const;
c23c8659 807 /** Unit of the samples in this packet. */
15bebf57 808 const Unit *unit() const;
c23c8659 809 /** Measurement flags associated with the samples in this packet. */
6c6dd732 810 std::vector<const QuantityFlag *> mq_flags() const;
6ad2fbaa
SA
811 /**
812 * Provides a Logic packet that contains a conversion of the analog
813 * data using a simple threshold.
814 *
815 * @param threshold Threshold to use.
816 * @param data_ptr Pointer to num_samples() bytes where the logic
817 * samples are stored. When nullptr, memory for
818 * logic->data_pointer() will be allocated and must
819 * be freed by the caller.
820 */
6c6dd732 821 std::shared_ptr<Logic> get_logic_via_threshold(float threshold,
6ad2fbaa
SA
822 uint8_t *data_ptr=nullptr) const;
823 /**
824 * Provides a Logic packet that contains a conversion of the analog
825 * data using a Schmitt-Trigger.
826 *
827 * @param lo_thr Low threshold to use (anything below this is low).
828 * @param hi_thr High threshold to use (anything above this is high).
829 * @param state Points to a byte that contains the current state of the
830 * converter. For best results, set to value of logic
831 * sample n-1.
832 * @param data_ptr Pointer to num_samples() bytes where the logic
833 * samples are stored. When nullptr, memory for
834 * logic->data_pointer() will be allocated and must be
835 * freed by the caller.
836 */
6c6dd732 837 std::shared_ptr<Logic> get_logic_via_schmitt_trigger(float lo_thr,
6ad2fbaa 838 float hi_thr, uint8_t *state, uint8_t *data_ptr=nullptr) const;
21d1bec6 839private:
6c11b496 840 explicit Analog(const struct sr_datafeed_analog *structure);
dd13d47a 841 ~Analog();
6c6dd732 842 std::shared_ptr<PacketPayload> share_owned_by(std::shared_ptr<Packet> parent);
d5d7b09e
DE
843
844 const struct sr_datafeed_analog *_structure;
845
c23c8659
ML
846 friend class Packet;
847};
848
0cee3a3e
SA
849/** Number represented by a numerator/denominator integer pair */
850class SR_API Rational :
851 public ParentOwned<Rational, Analog>
852{
853public:
854 /** Numerator, i.e. the dividend. */
855 int64_t numerator() const;
856 /** Denominator, i.e. the divider. */
857 uint64_t denominator() const;
858 /** Actual (lossy) value. */
859 float value() const;
860private:
861 explicit Rational(const struct sr_rational *structure);
862 ~Rational();
6c6dd732 863 std::shared_ptr<Rational> share_owned_by(std::shared_ptr<Analog> parent);
0cee3a3e
SA
864
865 const struct sr_rational *_structure;
866
867 friend class Analog;
868 friend struct std::default_delete<Rational>;
869};
870
07443fd2 871/** An input format supported by the library */
c23c8659 872class SR_API InputFormat :
d5d7b09e 873 public ParentOwned<InputFormat, Context>
c23c8659
ML
874{
875public:
876 /** Name of this input format. */
6c6dd732 877 std::string name() const;
c23c8659 878 /** Description of this input format. */
6c6dd732 879 std::string description() const;
c7bc82ff 880 /** A list of preferred file name extensions for this file format.
e7eb2968 881 * @note This list is a recommendation only. */
6c6dd732 882 std::vector<std::string> extensions() const;
ca3291e3 883 /** Options supported by this input format. */
6c6dd732 884 std::map<std::string, std::shared_ptr<Option> > options();
ca3291e3
ML
885 /** Create an input using this input format.
886 * @param options Mapping of (option name, value) pairs. */
6c6dd732
DA
887 std::shared_ptr<Input> create_input(std::map<std::string, Glib::VariantBase>
888 options = std::map<std::string, Glib::VariantBase>());
21d1bec6 889private:
6c11b496 890 explicit InputFormat(const struct sr_input_module *structure);
c23c8659 891 ~InputFormat();
d5d7b09e
DE
892
893 const struct sr_input_module *_structure;
894
c23c8659 895 friend class Context;
ca3291e3 896 friend class InputDevice;
01451225 897 friend struct std::default_delete<InputFormat>;
c23c8659
ML
898};
899
ca3291e3 900/** An input instance (an input format applied to a file or stream) */
d5d7b09e 901class SR_API Input : public UserOwned<Input>
c23c8659
ML
902{
903public:
ca3291e3 904 /** Virtual device associated with this input. */
6c6dd732 905 std::shared_ptr<InputDevice> device();
ca3291e3 906 /** Send next stream data.
2b51d48b
ML
907 * @param data Next stream data.
908 * @param length Length of data. */
909 void send(void *data, size_t length);
9c51e8ec
ML
910 /** Signal end of input data. */
911 void end();
b6b4f03e 912 void reset();
21d1bec6 913private:
6c6dd732 914 Input(std::shared_ptr<Context> context, const struct sr_input *structure);
ca3291e3 915 ~Input();
d5d7b09e 916 const struct sr_input *_structure;
6c6dd732
DA
917 std::shared_ptr<Context> _context;
918 std::unique_ptr<InputDevice> _device;
a98729a7 919
ca3291e3 920 friend class Context;
c23c8659 921 friend class InputFormat;
01451225 922 friend struct std::default_delete<Input>;
c23c8659
ML
923};
924
ca3291e3 925/** A virtual device associated with an input */
6e5240f4 926class SR_API InputDevice :
d5d7b09e 927 public ParentOwned<InputDevice, Input>,
6e5240f4 928 public Device
ca3291e3 929{
21d1bec6 930private:
6c6dd732 931 InputDevice(std::shared_ptr<Input> input, struct sr_dev_inst *sdi);
ca3291e3 932 ~InputDevice();
6c6dd732
DA
933 std::shared_ptr<Device> get_shared_from_this();
934 std::shared_ptr<Input> _input;
ca3291e3 935 friend class Input;
01451225 936 friend struct std::default_delete<InputDevice>;
ca3291e3
ML
937};
938
58aa1f83 939/** An option used by an output format */
d5d7b09e 940class SR_API Option : public UserOwned<Option>
58aa1f83
ML
941{
942public:
943 /** Short name of this option suitable for command line usage. */
6c6dd732 944 std::string id() const;
58aa1f83 945 /** Short name of this option suitable for GUI usage. */
6c6dd732 946 std::string name() const;
58aa1f83 947 /** Description of this option in a sentence. */
6c6dd732 948 std::string description() const;
58aa1f83 949 /** Default value for this option. */
15bebf57 950 Glib::VariantBase default_value() const;
58aa1f83 951 /** Possible values for this option, if a limited set. */
6c6dd732 952 std::vector<Glib::VariantBase> values() const;
61a6d983 953 /** Parse a string argument into the appropriate type for this option. */
6c6dd732 954 Glib::VariantBase parse_string(std::string value);
21d1bec6 955private:
58aa1f83 956 Option(const struct sr_option *structure,
6c6dd732 957 std::shared_ptr<const struct sr_option *> structure_array);
58aa1f83 958 ~Option();
d5d7b09e 959 const struct sr_option *_structure;
6c6dd732 960 std::shared_ptr<const struct sr_option *> _structure_array;
a98729a7 961
43942280 962 friend class InputFormat;
58aa1f83 963 friend class OutputFormat;
01451225 964 friend struct std::default_delete<Option>;
58aa1f83
ML
965};
966
07443fd2 967/** An output format supported by the library */
c23c8659 968class SR_API OutputFormat :
d5d7b09e 969 public ParentOwned<OutputFormat, Context>
c23c8659
ML
970{
971public:
972 /** Name of this output format. */
6c6dd732 973 std::string name() const;
c23c8659 974 /** Description of this output format. */
6c6dd732 975 std::string description() const;
8a174d23 976 /** A list of preferred file name extensions for this file format.
e7eb2968 977 * @note This list is a recommendation only. */
6c6dd732 978 std::vector<std::string> extensions() const;
58aa1f83 979 /** Options supported by this output format. */
6c6dd732 980 std::map<std::string, std::shared_ptr<Option> > options();
b6f411ac
ML
981 /** Create an output using this format.
982 * @param device Device to output for.
983 * @param options Mapping of (option name, value) pairs. */
6c6dd732
DA
984 std::shared_ptr<Output> create_output(std::shared_ptr<Device> device,
985 std::map<std::string, Glib::VariantBase> options = std::map<std::string, Glib::VariantBase>());
81b3ce37
SA
986 /** Create an output using this format.
987 * @param filename Name of destination file.
988 * @param device Device to output for.
989 * @param options Mapping of (option name, value) pairs. */
6c6dd732
DA
990 std::shared_ptr<Output> create_output(std::string filename,
991 std::shared_ptr<Device> device,
992 std::map<std::string, Glib::VariantBase> options = std::map<std::string, Glib::VariantBase>());
3cd4b381
SA
993 /**
994 * Checks whether a given flag is set.
995 * @param flag Flag to check
996 * @return true if flag is set for this module
997 * @see sr_output_flags
998 */
15bebf57 999 bool test_flag(const OutputFlag *flag) const;
21d1bec6 1000private:
6c11b496 1001 explicit OutputFormat(const struct sr_output_module *structure);
c23c8659 1002 ~OutputFormat();
d5d7b09e
DE
1003
1004 const struct sr_output_module *_structure;
1005
c23c8659
ML
1006 friend class Context;
1007 friend class Output;
01451225 1008 friend struct std::default_delete<OutputFormat>;
c23c8659
ML
1009};
1010
07443fd2 1011/** An output instance (an output format applied to a device) */
d5d7b09e 1012class SR_API Output : public UserOwned<Output>
c23c8659
ML
1013{
1014public:
b6f411ac
ML
1015 /** Update output with data from the given packet.
1016 * @param packet Packet to handle. */
6c6dd732 1017 std::string receive(std::shared_ptr<Packet> packet);
ea7a83a4 1018 /** Output format in use for this output */
6c6dd732 1019 std::shared_ptr<OutputFormat> format();
21d1bec6 1020private:
6c6dd732
DA
1021 Output(std::shared_ptr<OutputFormat> format, std::shared_ptr<Device> device);
1022 Output(std::shared_ptr<OutputFormat> format,
1023 std::shared_ptr<Device> device, std::map<std::string, Glib::VariantBase> options);
1024 Output(std::string filename, std::shared_ptr<OutputFormat> format,
1025 std::shared_ptr<Device> device, std::map<std::string, Glib::VariantBase> options);
c23c8659 1026 ~Output();
d5d7b09e
DE
1027
1028 const struct sr_output *_structure;
6c6dd732
DA
1029 const std::shared_ptr<OutputFormat> _format;
1030 const std::shared_ptr<Device> _device;
1031 const std::map<std::string, Glib::VariantBase> _options;
d5d7b09e 1032
c23c8659 1033 friend class OutputFormat;
01451225 1034 friend struct std::default_delete<Output>;
c23c8659
ML
1035};
1036
1037/** Base class for objects which wrap an enumeration value from libsigrok */
9d229ecb 1038template <class Class, typename Enum> class SR_API EnumValue
c23c8659
ML
1039{
1040public:
9d229ecb
ML
1041 /** The integer constant associated with this value. */
1042 int id() const
1043 {
1044 return static_cast<int>(_id);
1045 }
c23c8659 1046 /** The name associated with this value. */
6c6dd732 1047 std::string name() const
9d229ecb
ML
1048 {
1049 return _name;
1050 }
1051 /** Get value associated with a given integer constant. */
1052 static const Class *get(int id)
1053 {
15bebf57
DE
1054 const auto pos = _values.find(static_cast<Enum>(id));
1055 if (pos == _values.end())
9d229ecb 1056 throw Error(SR_ERR_ARG);
15bebf57 1057 return pos->second;
9d229ecb
ML
1058 }
1059 /** Get possible values. */
1060 static std::vector<const Class *> values()
1061 {
1062 std::vector<const Class *> result;
1063 for (auto entry : _values)
1064 result.push_back(entry.second);
1065 return result;
1066 }
c23c8659 1067protected:
9d229ecb
ML
1068 EnumValue(Enum id, const char name[]) : _id(id), _name(name)
1069 {
1070 }
1071 ~EnumValue()
1072 {
1073 }
21d1bec6 1074private:
9d229ecb
ML
1075 static const std::map<const Enum, const Class * const> _values;
1076 const Enum _id;
6c6dd732 1077 const std::string _name;
c23c8659
ML
1078};
1079
c23c8659
ML
1080}
1081
ace872d5
ML
1082#include <libsigrokcxx/enums.hpp>
1083
1b40fdb8 1084#endif