]> sigrok.org Git - libsigrok.git/blame - bindings/cxx/include/libsigrok/libsigrok.hpp
Add bindings for getting/setting session trigger.
[libsigrok.git] / bindings / cxx / include / libsigrok / libsigrok.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
20#ifndef LIBSIGROK_HPP
21#define LIBSIGROK_HPP
22
23#include "libsigrok/libsigrok.h"
24#include <glibmm-2.4/glibmm.h>
25
26#include <stdexcept>
27#include <memory>
28#include <vector>
29#include <map>
30
31namespace sigrok
32{
33
34using namespace std;
35
36/* Forward declarations */
37class SR_API Error;
38class SR_API Context;
39class SR_API Driver;
40class SR_API Device;
41class SR_API HardwareDevice;
42class SR_API Channel;
43class SR_API EventSource;
44class SR_API Session;
45class SR_API ConfigKey;
46class SR_API InputFormat;
47class SR_API OutputFormat;
48class SR_API LogLevel;
49class SR_API ChannelGroup;
50class SR_API Trigger;
51class SR_API TriggerStage;
52class SR_API TriggerMatch;
53class SR_API TriggerMatchType;
54class SR_API ChannelType;
55class SR_API Packet;
56class SR_API PacketPayload;
57class SR_API PacketType;
58class SR_API Quantity;
59class SR_API Unit;
60class SR_API QuantityFlag;
61class SR_API InputFileDevice;
62class SR_API Output;
63class SR_API DataType;
64
65/** Exception thrown when an error code is returned by any libsigrok call. */
66class SR_API Error: public exception
67{
68public:
69 Error(int result);
70 ~Error() throw();
71 const int result;
72 const char *what() const throw();
73};
74
75/** Base template for most classes which wrap a struct type from libsigrok. */
76template <class Parent, typename Struct> class SR_API StructureWrapper :
77 public enable_shared_from_this<StructureWrapper<Parent, Struct> >
78{
79public:
80 /** Parent object which owns this child object's underlying structure.
81
82 This shared pointer will be null when this child is unused, but
83 will be assigned to point to the parent before any shared pointer
84 to this child is handed out to the user.
85
86 When the reference count of this child falls to zero, this shared
87 pointer to its parent is reset by a custom deleter on the child's
88 shared pointer.
89
90 This strategy ensures that the destructors for both the child and
91 the parent are called at the correct time, i.e. only when all
92 references to both the parent and all its children are gone. */
93 shared_ptr<Parent> parent;
94protected:
95 Struct *structure;
96
97 StructureWrapper<Parent, Struct>(Struct *structure) :
98 structure(structure)
99 {
100 }
101};
102
103/** Type of log callback */
104typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
105
106/** Context */
107class SR_API Context : public enable_shared_from_this<Context>
108{
109public:
110 /** Create new context */
111 static shared_ptr<Context> create();
112 /** libsigrok package version. */
113 string get_package_version();
114 /** libsigrok library version. */
115 string get_lib_version();
116 /** Available hardware drivers, indexed by name. */
117 map<string, shared_ptr<Driver> > get_drivers();
118 /** Available input formats, indexed by name. */
119 map<string, shared_ptr<InputFormat> > get_input_formats();
120 /** Available output formats, indexed by name. */
121 map<string, shared_ptr<OutputFormat> > get_output_formats();
122 /** Current log level. */
123 const LogLevel *get_log_level();
124 /** Set the log level. */
125 void set_log_level(const LogLevel *level);
126 /** Current log domain. */
127 string get_log_domain();
128 /** Set the log domain. */
129 void set_log_domain(string value);
130 /** Set the log callback. */
131 void set_log_callback(LogCallbackFunction callback);
132 /** Set the log callback to the default handler. */
133 void set_log_callback_default();
134 /** Create a new session. */
135 shared_ptr<Session> create_session();
136 /** Load a saved session. */
137 shared_ptr<Session> load_session(string filename);
138 /** Create a new trigger. */
139 shared_ptr<Trigger> create_trigger(string name);
140protected:
141 struct sr_context *structure;
142 map<string, Driver *> drivers;
143 map<string, InputFormat *> input_formats;
144 map<string, OutputFormat *> output_formats;
145 Session *session;
146 LogCallbackFunction log_callback;
147 Context();
148 ~Context();
149 /** Deleter needed to allow shared_ptr use with protected destructor. */
150 class Deleter
151 {
152 public:
153 void operator()(Context *context) { delete context; }
154 };
155 friend class Deleter;
156 friend class Session;
157 friend class Driver;
158};
159
160/** Hardware driver */
161class SR_API Driver : public StructureWrapper<Context, struct sr_dev_driver>
162{
163public:
164 /** Name of this driver. */
165 string get_name();
166 /** Long name for this driver. */
167 string get_long_name();
168 /** Scan for devices and return a list of devices found. */
169 vector<shared_ptr<HardwareDevice> > scan(
170 map<const ConfigKey *, Glib::VariantBase> options = {});
171protected:
172 bool initialized;
173 vector<HardwareDevice *> devices;
174 Driver(struct sr_dev_driver *structure);
175 ~Driver();
176 friend class Context;
177 friend class HardwareDevice;
178 friend class ChannelGroup;
179};
180
181/** An object that can be configured. */
182class SR_API Configurable
183{
184public:
185 /** Read configuration for the given key. */
186 Glib::VariantBase config_get(const ConfigKey *key);
187 /** Set configuration for the given key to a specified value. */
188 void config_set(const ConfigKey *key, Glib::VariantBase value);
189 /** Enumerate available values for the given configuration key. */
190 Glib::VariantBase config_list(const ConfigKey *key);
191protected:
192 Configurable(
193 struct sr_dev_driver *driver,
194 struct sr_dev_inst *sdi,
195 struct sr_channel_group *channel_group);
196 virtual ~Configurable();
197 struct sr_dev_driver *config_driver;
198 struct sr_dev_inst *config_sdi;
199 struct sr_channel_group *config_channel_group;
200};
201
202/** Generic device (may be real or from an input file) */
203class SR_API Device :
204 public Configurable,
205 public StructureWrapper<Context, struct sr_dev_inst>
206{
207public:
208 /** Vendor name for this device. */
209 string get_vendor();
210 /** Model name for this device. */
211 string get_model();
212 /** Version string for this device. */
213 string get_version();
214 /** List of the channels available on this device. */
215 vector<shared_ptr<Channel> > get_channels();
216 /** Open device. */
217 void open();
218 /** Close device. */
219 void close();
220protected:
221 Device(struct sr_dev_inst *structure);
222 ~Device();
223 vector<Channel *> channels;
224 /** Deleter needed to allow shared_ptr use with protected destructor. */
225 class Deleter
226 {
227 public:
228 void operator()(Device *device) { delete device; }
229 };
230 friend class Deleter;
231 friend class Session;
232 friend class Channel;
233 friend class ChannelGroup;
234 friend class Output;
235};
236
237/** Hardware device (connected via a driver) */
238class SR_API HardwareDevice : public Device
239{
240public:
241 /** Driver providing this device. */
242 shared_ptr<Driver> get_driver();
243 /** Channel groups available on this device, indexed by name. */
244 map<string, shared_ptr<ChannelGroup> > get_channel_groups();
245protected:
246 HardwareDevice(Driver *driver, struct sr_dev_inst *structure);
247 ~HardwareDevice();
248 Driver *driver;
249 map<string, ChannelGroup *> channel_groups;
250 friend class Driver;
251 friend class ChannelGroup;
252};
253
254/** Channel */
255class SR_API Channel : public StructureWrapper<Device, struct sr_channel>
256{
257public:
258 /** Current name of this channel. */
259 string get_name();
260 /** Set the name of this channel. */
261 void set_name(string name);
262 /** Type of this channel. */
263 const ChannelType *get_type();
264 /** Enabled status of this channel. */
265 bool get_enabled();
266 /** Set the enabled status of this channel. */
267 void set_enabled(bool value);
268protected:
269 Channel(struct sr_channel *structure);
270 ~Channel();
271 const ChannelType * const type;
272 friend class Device;
273 friend class ChannelGroup;
274 friend class Session;
275 friend class TriggerStage;
276};
277
278/** Channel group */
279class SR_API ChannelGroup :
280 public StructureWrapper<HardwareDevice, struct sr_channel_group>,
281 public Configurable
282{
283public:
284 /** Name of this channel group. */
285 string get_name();
286 /** List of the channels in this group. */
287 vector<shared_ptr<Channel> > get_channels();
288protected:
289 ChannelGroup(HardwareDevice *device, struct sr_channel_group *structure);
290 ~ChannelGroup();
291 vector<Channel *> channels;
292 friend class HardwareDevice;
293};
294
295/** Trigger */
296class SR_API Trigger : public enable_shared_from_this<Trigger>
297{
298public:
299 string get_name();
300 vector<shared_ptr<TriggerStage> > get_stages();
301 shared_ptr<TriggerStage> add_stage();
302protected:
303 Trigger(shared_ptr<Context> context, string name);
304 ~Trigger();
305 struct sr_trigger *structure;
306 shared_ptr<Context> context;
307 vector<TriggerStage *> stages;
308 /** Deleter needed to allow shared_ptr use with protected destructor. */
309 class Deleter
310 {
311 public:
312 void operator()(Trigger *trigger) { delete trigger; }
313 };
314 friend class Context;
6fa0eb86 315 friend class Session;
c23c8659
ML
316};
317
318/** Trigger stage */
319class SR_API TriggerStage : public StructureWrapper<Trigger, struct sr_trigger_stage>
320{
321public:
322 int get_number();
323 vector<shared_ptr<TriggerMatch> > get_matches();
324 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type);
325 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
326protected:
327 vector<TriggerMatch *> matches;
328 TriggerStage(struct sr_trigger_stage *structure);
329 ~TriggerStage();
330 friend class Trigger;
331};
332
333/** Trigger match */
334class SR_API TriggerMatch : public StructureWrapper<TriggerStage, struct sr_trigger_match>
335{
336public:
337 shared_ptr<Channel> get_channel();
338 const TriggerMatchType *get_type();
339 float get_value();
340protected:
341 TriggerMatch(struct sr_trigger_match *structure, shared_ptr<Channel> channel);
342 ~TriggerMatch();
343 shared_ptr<Channel> channel;
344 friend class TriggerStage;
345};
346
347/** Type of datafeed callback */
348typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
349 DatafeedCallbackFunction;
350
351/** Data required for C callback function to call a C++ datafeed callback */
352class SR_PRIV DatafeedCallbackData
353{
354public:
355 void run(const struct sr_dev_inst *sdi,
356 const struct sr_datafeed_packet *pkt);
357protected:
358 DatafeedCallbackFunction callback;
359 DatafeedCallbackData(Session *session,
360 DatafeedCallbackFunction callback);
361 Session *session;
362 friend class Session;
363};
364
365/** Type of source callback */
366typedef function<bool(Glib::IOCondition)>
367 SourceCallbackFunction;
368
369/** Data required for C callback function to call a C++ source callback */
370class SR_PRIV SourceCallbackData
371{
372public:
373 bool run(int revents);
374protected:
375 SourceCallbackData(shared_ptr<EventSource> source);
376 shared_ptr<EventSource> source;
377 friend class Session;
378};
379
380/** Event source. */
381class SR_API EventSource
382{
383public:
384 /** Create an event source from a file descriptor. */
385 static shared_ptr<EventSource> create(int fd, Glib::IOCondition events,
386 int timeout, SourceCallbackFunction callback);
387 /** Create an event source from a Glib::PollFD */
388 static shared_ptr<EventSource> create(Glib::PollFD pollfd, int timeout,
389 SourceCallbackFunction callback);
390 /** Create an event source from a Glib::IOChannel */
391 static shared_ptr<EventSource> create(
392 Glib::RefPtr<Glib::IOChannel> channel, Glib::IOCondition events,
393 int timeout, SourceCallbackFunction callback);
394protected:
395 EventSource(int timeout, SourceCallbackFunction callback);
396 ~EventSource();
397 enum source_type {
398 SOURCE_FD,
399 SOURCE_POLLFD,
400 SOURCE_IOCHANNEL
401 } type;
402 int fd;
403 Glib::PollFD pollfd;
404 Glib::RefPtr<Glib::IOChannel> channel;
405 Glib::IOCondition events;
406 int timeout;
407 SourceCallbackFunction callback;
408 /** Deleter needed to allow shared_ptr use with protected destructor. */
409 class Deleter
410 {
411 public:
412 void operator()(EventSource *source) { delete source; }
413 };
414 friend class Deleter;
415 friend class Session;
416 friend class SourceCallbackData;
417};
418
419/** Session */
420class SR_API Session
421{
422public:
423 /** Add a device to this session. */
424 void add_device(shared_ptr<Device> device);
425 /** List devices attached to this session. */
426 vector<shared_ptr<Device> > get_devices();
427 /** Remove all devices from this session. */
428 void remove_devices();
429 /** Add a datafeed callback to this session. */
430 void add_datafeed_callback(DatafeedCallbackFunction callback);
431 /** Remove all datafeed callbacks from this session. */
432 void remove_datafeed_callbacks();
433 /** Add an event source. */
434 void add_source(shared_ptr<EventSource> source);
435 /** Remove an event source. */
436 void remove_source(shared_ptr<EventSource> source);
437 /** Start the session. */
438 void start();
439 /** Run the session event loop. */
440 void run();
441 /** Stop the session. */
442 void stop();
443 /** Begin saving session to a file. */
444 void begin_save(string filename);
445 /** Append a packet to the session file being saved. */
446 void append(shared_ptr<Device> device, shared_ptr<Packet> packet);
6fa0eb86
ML
447 /** Get current trigger setting. */
448 shared_ptr<Trigger> get_trigger();
449 /** Set trigger setting. */
450 void set_trigger(shared_ptr<Trigger> trigger);
c23c8659
ML
451protected:
452 Session(shared_ptr<Context> context);
453 Session(shared_ptr<Context> context, string filename);
454 ~Session();
455 struct sr_session *structure;
456 const shared_ptr<Context> context;
457 map<const struct sr_dev_inst *, shared_ptr<Device> > devices;
458 vector<DatafeedCallbackData *> datafeed_callbacks;
459 map<shared_ptr<EventSource>, SourceCallbackData *> source_callbacks;
460 bool saving;
461 bool save_initialized;
462 string save_filename;
463 uint64_t save_samplerate;
6fa0eb86 464 shared_ptr<Trigger> trigger;
c23c8659
ML
465 /** Deleter needed to allow shared_ptr use with protected destructor. */
466 class Deleter
467 {
468 public:
469 void operator()(Session *session) { delete session; }
470 };
471 friend class Deleter;
472 friend class Context;
473 friend class DatafeedCallbackData;
474};
475
476/** Datafeed packet */
477class SR_API Packet
478{
479public:
480 /** Payload of this packet. */
481 PacketPayload *get_payload();
482protected:
483 Packet(const struct sr_datafeed_packet *structure);
484 ~Packet();
485 const struct sr_datafeed_packet *structure;
486 PacketPayload *payload;
487 /** Deleter needed to allow shared_ptr use with protected destructor. */
488 class Deleter
489 {
490 public:
491 void operator()(Packet *packet) { delete packet; }
492 };
493 friend class Deleter;
494 friend class Session;
495 friend class Output;
496 friend class DatafeedCallbackData;
497};
498
499/** Abstract base class for datafeed packet payloads. */
500class SR_API PacketPayload
501{
502protected:
503 PacketPayload();
504 virtual ~PacketPayload() = 0;
505 virtual void *get_data() = 0;
506 virtual size_t get_data_size() = 0;
507 friend class Packet;
508 friend class Output;
509};
510
511/** Logic data payload */
512class SR_API Logic : public PacketPayload
513{
514protected:
515 Logic(const struct sr_datafeed_logic *structure);
516 ~Logic();
517 const struct sr_datafeed_logic *structure;
518 vector<uint8_t> data;
519 void *get_data();
520 size_t get_data_size();
521 friend class Packet;
522};
523
524/** Analog data payload */
525class SR_API Analog : public PacketPayload
526{
527public:
528 /** Number of samples in this packet. */
529 unsigned int get_num_samples();
530 /** Measured quantity of the samples in this packet. */
531 const Quantity *get_mq();
532 /** Unit of the samples in this packet. */
533 const Unit *get_unit();
534 /** Measurement flags associated with the samples in this packet. */
535 vector<const QuantityFlag *> get_mq_flags();
536protected:
537 Analog(const struct sr_datafeed_analog *structure);
538 ~Analog();
539 const struct sr_datafeed_analog *structure;
540 void *get_data();
541 size_t get_data_size();
542 friend class Packet;
543};
544
545/** Input format */
546class SR_API InputFormat :
547 public StructureWrapper<Context, struct sr_input_format>
548{
549public:
550 /** Name of this input format. */
551 string get_name();
552 /** Description of this input format. */
553 string get_description();
554 /** Check whether a given file matches this input format. */
555 bool format_match(string filename);
556 /** Open a file using this input format. */
557 shared_ptr<InputFileDevice> open_file(string filename,
558 map<string, string> options = {});
559protected:
560 InputFormat(struct sr_input_format *structure);
561 ~InputFormat();
562 friend class Context;
563 friend class InputFileDevice;
564};
565
566/** Virtual device associated with an input file */
567class SR_API InputFileDevice : public Device
568{
569public:
570 /** Load data from file. */
571 void load();
572protected:
573 InputFileDevice(shared_ptr<InputFormat> format,
574 struct sr_input *input, string filename);
575 ~InputFileDevice();
576 struct sr_input *input;
577 shared_ptr<InputFormat> format;
578 string filename;
579 /** Deleter needed to allow shared_ptr use with protected destructor. */
580 class Deleter
581 {
582 public:
583 void operator()(InputFileDevice *device) { delete device; }
584 };
585 friend class Deleter;
586 friend class InputFormat;
587};
588
589/** Output format */
590class SR_API OutputFormat :
591 public StructureWrapper<Context, struct sr_output_format>
592{
593public:
594 /** Name of this output format. */
595 string get_name();
596 /** Description of this output format. */
597 string get_description();
598 /** Create an output using this format. */
599 shared_ptr<Output> create_output(shared_ptr<Device> device, map<string, string> options = {});
600protected:
601 OutputFormat(struct sr_output_format *structure);
602 ~OutputFormat();
603 friend class Context;
604 friend class Output;
605};
606
607/** Output instance (an output format applied to a device) */
608class SR_API Output
609{
610public:
611 /** Update output with data from the given packet. */
612 string receive(shared_ptr<Packet> packet);
613protected:
614 Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
615 Output(shared_ptr<OutputFormat> format,
616 shared_ptr<Device> device, map<string, string> options);
617 ~Output();
618 struct sr_output *structure;
619 const shared_ptr<OutputFormat> format;
620 const shared_ptr<Device> device;
621 const map<string, string> options;
622 /** Deleter needed to allow shared_ptr use with protected destructor. */
623 class Deleter
624 {
625 public:
626 void operator()(Output *output) { delete output; }
627 };
628 friend class Deleter;
629 friend class OutputFormat;
630};
631
632/** Base class for objects which wrap an enumeration value from libsigrok */
633template <typename T> class SR_API EnumValue
634{
635public:
636 /** The enum constant associated with this value. */
637 T get_id() const { return id; }
638 /** The name associated with this value. */
639 string get_name() const { return name; }
640protected:
641 EnumValue(T id, const char name[]) : id(id), name(name) {}
642 ~EnumValue() {}
643 const T id;
644 const string name;
645};
646
647#include "enums.hpp"
648
649}
650
651#endif // LIBSIGROK_HPP