]> sigrok.org Git - libsigrok.git/blob - bindings/cxx/include/libsigrok/libsigrok.hpp
bindings: Add Packet.get_type() method.
[libsigrok.git] / bindings / cxx / include / libsigrok / libsigrok.hpp
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
31 namespace sigrok
32 {
33
34 using namespace std;
35
36 /* Forward declarations */
37 class SR_API Error;
38 class SR_API Context;
39 class SR_API Driver;
40 class SR_API Device;
41 class SR_API HardwareDevice;
42 class SR_API Channel;
43 class SR_API EventSource;
44 class SR_API Session;
45 class SR_API ConfigKey;
46 class SR_API InputFormat;
47 class SR_API OutputFormat;
48 class SR_API LogLevel;
49 class SR_API ChannelGroup;
50 class SR_API Trigger;
51 class SR_API TriggerStage;
52 class SR_API TriggerMatch;
53 class SR_API TriggerMatchType;
54 class SR_API ChannelType;
55 class SR_API Packet;
56 class SR_API PacketPayload;
57 class SR_API PacketType;
58 class SR_API Quantity;
59 class SR_API Unit;
60 class SR_API QuantityFlag;
61 class SR_API InputFileDevice;
62 class SR_API Output;
63 class SR_API DataType;
64
65 /** Exception thrown when an error code is returned by any libsigrok call. */
66 class SR_API Error: public exception
67 {
68 public:
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. */
76 template <class Parent, typename Struct> class SR_API StructureWrapper :
77         public enable_shared_from_this<StructureWrapper<Parent, Struct> >
78 {
79 public:
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;
94 protected:
95         Struct *structure;
96
97         StructureWrapper<Parent, Struct>(Struct *structure) :
98                 structure(structure)
99         {
100         }
101 };
102
103 /** Type of log callback */
104 typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
105
106 /** Context */
107 class SR_API Context : public enable_shared_from_this<Context>
108 {
109 public:
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);
140 protected:
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 */
161 class SR_API Driver : public StructureWrapper<Context, struct sr_dev_driver>
162 {
163 public:
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 = {});
171 protected:
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. */
182 class SR_API Configurable
183 {
184 public:
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);
191 protected:
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) */
203 class SR_API Device :
204         public Configurable,
205         public StructureWrapper<Context, struct sr_dev_inst>
206 {
207 public:
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();
220 protected:
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) */
238 class SR_API HardwareDevice : public Device
239 {
240 public:
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();
245 protected:
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 */
255 class SR_API Channel : public StructureWrapper<Device, struct sr_channel>
256 {
257 public:
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);
268 protected:
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 */
279 class SR_API ChannelGroup :
280         public StructureWrapper<HardwareDevice, struct sr_channel_group>,
281         public Configurable
282 {
283 public:
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();
288 protected:
289         ChannelGroup(HardwareDevice *device, struct sr_channel_group *structure);
290         ~ChannelGroup();
291         vector<Channel *> channels;
292         friend class HardwareDevice;
293 };
294
295 /** Trigger */
296 class SR_API Trigger : public enable_shared_from_this<Trigger>
297 {
298 public:
299         string get_name();
300         vector<shared_ptr<TriggerStage> > get_stages();
301         shared_ptr<TriggerStage> add_stage();
302 protected:
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;
315         friend class Session;
316 };
317
318 /** Trigger stage */
319 class SR_API TriggerStage : public StructureWrapper<Trigger, struct sr_trigger_stage>
320 {
321 public:
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);
326 protected:
327         vector<TriggerMatch *> matches;
328         TriggerStage(struct sr_trigger_stage *structure);
329         ~TriggerStage();
330         friend class Trigger;
331 };
332
333 /** Trigger match */
334 class SR_API TriggerMatch : public StructureWrapper<TriggerStage, struct sr_trigger_match>
335 {
336 public:
337         shared_ptr<Channel> get_channel();
338         const TriggerMatchType *get_type();
339         float get_value();
340 protected:
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 */
348 typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
349         DatafeedCallbackFunction;
350
351 /** Data required for C callback function to call a C++ datafeed callback */
352 class SR_PRIV DatafeedCallbackData
353 {
354 public:
355         void run(const struct sr_dev_inst *sdi,
356                 const struct sr_datafeed_packet *pkt);
357 protected:
358         DatafeedCallbackFunction callback;
359         DatafeedCallbackData(Session *session,
360                 DatafeedCallbackFunction callback);
361         Session *session;
362         friend class Session;
363 };
364
365 /** Type of source callback */
366 typedef function<bool(Glib::IOCondition)>
367         SourceCallbackFunction;
368
369 /** Data required for C callback function to call a C++ source callback */
370 class SR_PRIV SourceCallbackData
371 {
372 public:
373         bool run(int revents);
374 protected:
375         SourceCallbackData(shared_ptr<EventSource> source);
376         shared_ptr<EventSource> source;
377         friend class Session;
378 };
379
380 /** Event source. */
381 class SR_API EventSource
382 {
383 public:
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);
394 protected:
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 */
420 class SR_API Session 
421 {
422 public:
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);
447         /** Get current trigger setting. */
448         shared_ptr<Trigger> get_trigger();
449         /** Set trigger setting. */
450         void set_trigger(shared_ptr<Trigger> trigger);
451 protected:
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;
464         shared_ptr<Trigger> trigger;
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 */
477 class SR_API Packet
478 {
479 public:
480         /** Type of this packet. */
481         const PacketType *get_type();
482         /** Payload of this packet. */
483         PacketPayload *get_payload();
484 protected:
485         Packet(const struct sr_datafeed_packet *structure);
486         ~Packet();
487         const struct sr_datafeed_packet *structure;
488         PacketPayload *payload;
489         /** Deleter needed to allow shared_ptr use with protected destructor. */
490         class Deleter
491         {
492         public:
493                 void operator()(Packet *packet) { delete packet; }
494         };
495         friend class Deleter;
496         friend class Session;
497         friend class Output;
498         friend class DatafeedCallbackData;
499 };
500
501 /** Abstract base class for datafeed packet payloads. */
502 class SR_API PacketPayload
503 {
504 protected:
505         PacketPayload();
506         virtual ~PacketPayload() = 0;
507         virtual void *get_data() = 0;
508         virtual size_t get_data_size() = 0;
509         friend class Packet;
510         friend class Output;
511 };
512
513 /** Logic data payload */
514 class SR_API Logic : public PacketPayload
515 {
516 protected:
517         Logic(const struct sr_datafeed_logic *structure);
518         ~Logic();
519         const struct sr_datafeed_logic *structure;
520         vector<uint8_t> data;
521         void *get_data();
522         size_t get_data_size();
523         friend class Packet;
524 };
525
526 /** Analog data payload */
527 class SR_API Analog : public PacketPayload
528 {
529 public:
530         /** Number of samples in this packet. */
531         unsigned int get_num_samples();
532         /** Measured quantity of the samples in this packet. */
533         const Quantity *get_mq();
534         /** Unit of the samples in this packet. */
535         const Unit *get_unit();
536         /** Measurement flags associated with the samples in this packet. */
537         vector<const QuantityFlag *> get_mq_flags();
538 protected:
539         Analog(const struct sr_datafeed_analog *structure);
540         ~Analog();
541         const struct sr_datafeed_analog *structure;
542         void *get_data();
543         size_t get_data_size();
544         friend class Packet;
545 };
546
547 /** Input format */
548 class SR_API InputFormat :
549         public StructureWrapper<Context, struct sr_input_format>
550 {
551 public:
552         /** Name of this input format. */
553         string get_name();
554         /** Description of this input format. */
555         string get_description();
556         /** Check whether a given file matches this input format. */
557         bool format_match(string filename);
558         /** Open a file using this input format. */
559         shared_ptr<InputFileDevice> open_file(string filename,
560                 map<string, string> options = {});
561 protected:
562         InputFormat(struct sr_input_format *structure);
563         ~InputFormat();
564         friend class Context;
565         friend class InputFileDevice;
566 };
567
568 /** Virtual device associated with an input file */
569 class SR_API InputFileDevice : public Device
570 {
571 public:
572         /** Load data from file. */
573         void load();
574 protected:
575         InputFileDevice(shared_ptr<InputFormat> format,
576                 struct sr_input *input, string filename);
577         ~InputFileDevice();
578         struct sr_input *input;
579         shared_ptr<InputFormat> format;
580         string filename;
581         /** Deleter needed to allow shared_ptr use with protected destructor. */
582         class Deleter
583         {
584         public:
585                 void operator()(InputFileDevice *device) { delete device; }
586         };
587         friend class Deleter;
588         friend class InputFormat;
589 };
590
591 /** Output format */
592 class SR_API OutputFormat :
593         public StructureWrapper<Context, struct sr_output_format>
594 {
595 public:
596         /** Name of this output format. */
597         string get_name();
598         /** Description of this output format. */
599         string get_description();
600         /** Create an output using this format. */
601         shared_ptr<Output> create_output(shared_ptr<Device> device, map<string, string> options = {});
602 protected:
603         OutputFormat(struct sr_output_format *structure);
604         ~OutputFormat();
605         friend class Context;
606         friend class Output;
607 };
608
609 /** Output instance (an output format applied to a device) */
610 class SR_API Output
611 {
612 public:
613         /** Update output with data from the given packet. */
614         string receive(shared_ptr<Packet> packet);
615 protected:
616         Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
617         Output(shared_ptr<OutputFormat> format,
618                 shared_ptr<Device> device, map<string, string> options);
619         ~Output();
620         struct sr_output *structure;
621         const shared_ptr<OutputFormat> format;
622         const shared_ptr<Device> device;
623         const map<string, string> options;
624         /** Deleter needed to allow shared_ptr use with protected destructor. */
625         class Deleter
626         {
627         public:
628                 void operator()(Output *output) { delete output; }
629         };
630         friend class Deleter;
631         friend class OutputFormat;
632 };
633
634 /** Base class for objects which wrap an enumeration value from libsigrok */
635 template <typename T> class SR_API EnumValue
636 {
637 public:
638         /** The enum constant associated with this value. */
639         T get_id() const { return id; }
640         /** The name associated with this value. */
641         string get_name() const { return name; }
642 protected:
643         EnumValue(T id, const char name[]) : id(id), name(name) {}
644         ~EnumValue() {}
645         const T id;
646         const string name;
647 };
648
649 #include "enums.hpp"
650
651 }
652
653 #endif // LIBSIGROK_HPP