X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=bindings%2Fcxx%2Fclasses.cpp;h=3e441f72252c2e4a34ebe30c303cd7a0e4b07a1c;hb=5faebab2903dc91949edc31f0a4b118d86090a30;hp=3e8acc0abb41d1a4558b117d0dc932f59e67eb95;hpb=9d229ecb9e301921284c6264ffc1d956572873df;p=libsigrok.git
diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp
index 3e8acc0a..3e441f72 100644
--- a/bindings/cxx/classes.cpp
+++ b/bindings/cxx/classes.cpp
@@ -17,7 +17,13 @@
* along with this program. If not, see .
*/
-#include "libsigrok/libsigrok.hpp"
+/* Needed for isascii(), as used in the GNU libstdc++ headers */
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600
+#endif
+
+#include
+#include
#include
#include
@@ -66,6 +72,50 @@ Error::~Error() throw()
{
}
+ResourceReader::~ResourceReader()
+{
+}
+
+SR_PRIV int ResourceReader::open_callback(struct sr_resource *res,
+ const char *name, void *cb_data)
+{
+ try {
+ auto *const reader = static_cast(cb_data);
+ reader->open(res, name);
+ } catch (const Error &err) {
+ return err.result;
+ } catch (...) {
+ return SR_ERR;
+ }
+ return SR_OK;
+}
+
+SR_PRIV int ResourceReader::close_callback(struct sr_resource *res, void *cb_data)
+{
+ try {
+ auto *const reader = static_cast(cb_data);
+ reader->close(res);
+ } catch (const Error &err) {
+ return err.result;
+ } catch (...) {
+ return SR_ERR;
+ }
+ return SR_OK;
+}
+
+SR_PRIV ssize_t ResourceReader::read_callback(const struct sr_resource *res,
+ void *buf, size_t count, void *cb_data)
+{
+ try {
+ auto *const reader = static_cast(cb_data);
+ return reader->read(res, buf, count);
+ } catch (const Error &err) {
+ return err.result;
+ } catch (...) {
+ return SR_ERR;
+ }
+}
+
shared_ptr Context::create()
{
return shared_ptr(new Context(), Context::Deleter());
@@ -77,7 +127,7 @@ Context::Context() :
{
check(sr_init(&_structure));
- struct sr_dev_driver **driver_list = sr_driver_list();
+ struct sr_dev_driver **driver_list = sr_driver_list(_structure);
if (driver_list)
for (int i = 0; driver_list[i]; i++)
_drivers[driver_list[i]->name] =
@@ -161,16 +211,6 @@ void Context::set_log_level(const LogLevel *level)
check(sr_log_loglevel_set(level->id()));
}
-string Context::log_domain()
-{
- return valid_string(sr_log_logdomain_get());
-}
-
-void Context::set_log_domain(string value)
-{
- check(sr_log_logdomain_set(value.c_str()));
-}
-
static int call_log_callback(void *cb_data, int loglevel, const char *format, va_list args)
{
va_list args_copy;
@@ -200,13 +240,26 @@ void Context::set_log_callback(LogCallbackFunction callback)
{
_log_callback = callback;
check(sr_log_callback_set(call_log_callback, &_log_callback));
-}
+}
void Context::set_log_callback_default()
{
check(sr_log_callback_set_default());
_log_callback = nullptr;
-}
+}
+
+void Context::set_resource_reader(ResourceReader *reader)
+{
+ if (reader) {
+ check(sr_resource_set_hooks(_structure,
+ &ResourceReader::open_callback,
+ &ResourceReader::close_callback,
+ &ResourceReader::read_callback, reader));
+ } else {
+ check(sr_resource_set_hooks(_structure,
+ nullptr, nullptr, nullptr, nullptr));
+ }
+}
shared_ptr Context::create_session()
{
@@ -214,6 +267,77 @@ shared_ptr Context::create_session()
new Session(shared_from_this()), Session::Deleter());
}
+shared_ptr Context::create_user_device(
+ string vendor, string model, string version)
+{
+ return shared_ptr(
+ new UserDevice(vendor, model, version), UserDevice::Deleter());
+}
+
+shared_ptr Context::create_header_packet(Glib::TimeVal start_time)
+{
+ auto header = g_new(struct sr_datafeed_header, 1);
+ header->feed_version = 1;
+ header->starttime.tv_sec = start_time.tv_sec;
+ header->starttime.tv_usec = start_time.tv_usec;
+ auto packet = g_new(struct sr_datafeed_packet, 1);
+ packet->type = SR_DF_HEADER;
+ packet->payload = header;
+ return shared_ptr(new Packet(nullptr, packet), Packet::Deleter());
+}
+
+shared_ptr Context::create_meta_packet(
+ map config)
+{
+ auto meta = g_new0(struct sr_datafeed_meta, 1);
+ for (auto input : config)
+ {
+ auto key = input.first;
+ auto value = input.second;
+ auto output = g_new(struct sr_config, 1);
+ output->key = key->id();
+ output->data = value.gobj();
+ g_variant_ref(output->data);
+ meta->config = g_slist_append(meta->config, output);
+ }
+ auto packet = g_new(struct sr_datafeed_packet, 1);
+ packet->type = SR_DF_META;
+ packet->payload = meta;
+ return shared_ptr(new Packet(nullptr, packet), Packet::Deleter());
+}
+
+shared_ptr Context::create_logic_packet(
+ void *data_pointer, size_t data_length, unsigned int unit_size)
+{
+ auto logic = g_new(struct sr_datafeed_logic, 1);
+ logic->length = data_length;
+ logic->unitsize = unit_size;
+ logic->data = data_pointer;
+ auto packet = g_new(struct sr_datafeed_packet, 1);
+ packet->type = SR_DF_LOGIC;
+ packet->payload = logic;
+ return shared_ptr(new Packet(nullptr, packet), Packet::Deleter());
+}
+
+shared_ptr Context::create_analog_old_packet(
+ vector > channels,
+ float *data_pointer, unsigned int num_samples, const Quantity *mq,
+ const Unit *unit, vector mqflags)
+{
+ auto analog = g_new0(struct sr_datafeed_analog_old, 1);
+ for (auto channel : channels)
+ analog->channels = g_slist_append(analog->channels, channel->_structure);
+ analog->num_samples = num_samples;
+ analog->mq = mq->id();
+ analog->unit = unit->id();
+ analog->mqflags = QuantityFlag::mask_from_flags(mqflags);
+ analog->data = data_pointer;
+ auto packet = g_new(struct sr_datafeed_packet, 1);
+ packet->type = SR_DF_ANALOG_OLD;
+ packet->payload = analog;
+ return shared_ptr(new Packet(nullptr, packet), Packet::Deleter());
+}
+
shared_ptr Context::load_session(string filename)
{
return shared_ptr(
@@ -247,6 +371,20 @@ shared_ptr Context::open_stream(string header)
new Input(shared_from_this(), input), Input::Deleter());
}
+map Context::serials(shared_ptr driver)
+{
+ GSList *serial_list = sr_serial_list(driver ? driver->_structure : NULL);
+ map serials;
+
+ for (GSList *serial = serial_list; serial; serial = serial->next) {
+ struct sr_serial_port *port = (sr_serial_port *) serial->data;
+ serials[string(port->name)] = string(port->description);
+ }
+
+ g_slist_free_full(serial_list, (GDestroyNotify)sr_serial_free);
+ return serials;
+}
+
Driver::Driver(struct sr_dev_driver *structure) :
ParentOwned(structure),
Configurable(structure, NULL, NULL),
@@ -522,6 +660,34 @@ shared_ptr HardwareDevice::driver()
return _driver;
}
+UserDevice::UserDevice(string vendor, string model, string version) :
+ UserOwned(sr_dev_inst_user_new(
+ vendor.c_str(), model.c_str(), version.c_str())),
+ Device(UserOwned::_structure)
+{
+}
+
+UserDevice::~UserDevice()
+{
+}
+
+shared_ptr UserDevice::get_shared_from_this()
+{
+ return static_pointer_cast(shared_from_this());
+}
+
+shared_ptr UserDevice::add_channel(unsigned int index,
+ const ChannelType *type, string name)
+{
+ check(sr_dev_inst_channel_add(Device::_structure,
+ index, type->id(), name.c_str()));
+ struct sr_channel *structure = (struct sr_channel *)
+ g_slist_last(sr_dev_inst_channels_get(Device::_structure))->data;
+ Channel *channel = new Channel(structure);
+ _channels[structure] = channel;
+ return get_channel(structure);
+}
+
Channel::Channel(struct sr_channel *structure) :
ParentOwned(structure),
_type(ChannelType::get(_structure->type))
@@ -539,8 +705,7 @@ string Channel::name()
void Channel::set_name(string name)
{
- check(sr_dev_channel_name_set(_parent->_structure,
- _structure->index, name.c_str()));
+ check(sr_dev_channel_name_set(_structure, name.c_str()));
}
const ChannelType *Channel::type()
@@ -555,7 +720,7 @@ bool Channel::enabled()
void Channel::set_enabled(bool value)
{
- check(sr_dev_channel_enable(_parent->_structure, _structure->index, value));
+ check(sr_dev_channel_enable(_structure, value));
}
unsigned int Channel::index()
@@ -707,55 +872,6 @@ void DatafeedCallbackData::run(const struct sr_dev_inst *sdi,
_callback(device, packet);
}
-SourceCallbackData::SourceCallbackData(shared_ptr source) :
- _source(source)
-{
-}
-
-bool SourceCallbackData::run(int revents)
-{
- return _source->_callback((Glib::IOCondition) revents);
-}
-
-shared_ptr EventSource::create(int fd, Glib::IOCondition events,
- int timeout, SourceCallbackFunction callback)
-{
- auto result = new EventSource(timeout, callback);
- result->_type = EventSource::SOURCE_FD;
- result->_fd = fd;
- result->_events = events;
- return shared_ptr(result, EventSource::Deleter());
-}
-
-shared_ptr EventSource::create(Glib::PollFD pollfd, int timeout,
- SourceCallbackFunction callback)
-{
- auto result = new EventSource(timeout, callback);
- result->_type = EventSource::SOURCE_POLLFD;
- result->_pollfd = pollfd;
- return shared_ptr(result, EventSource::Deleter());
-}
-
-shared_ptr EventSource::create(Glib::RefPtr channel,
- Glib::IOCondition events, int timeout, SourceCallbackFunction callback)
-{
- auto result = new EventSource(timeout, callback);
- result->_type = EventSource::SOURCE_IOCHANNEL;
- result->_channel = channel;
- result->_events = events;
- return shared_ptr(result, EventSource::Deleter());
-}
-
-EventSource::EventSource(int timeout, SourceCallbackFunction callback) :
- _timeout(timeout),
- _callback(callback)
-{
-}
-
-EventSource::~EventSource()
-{
-}
-
SessionDevice::SessionDevice(struct sr_dev_inst *structure) :
ParentOwned(structure),
Device(structure)
@@ -773,20 +889,18 @@ shared_ptr SessionDevice::get_shared_from_this()
Session::Session(shared_ptr context) :
UserOwned(_structure),
- _context(context),
- _saving(false)
+ _context(context)
{
- check(sr_session_new(&_structure));
+ check(sr_session_new(context->_structure, &_structure));
_context->_session = this;
}
Session::Session(shared_ptr context, string filename) :
UserOwned(_structure),
_context(context),
- _filename(filename),
- _saving(false)
+ _filename(filename)
{
- check(sr_session_load(filename.c_str(), &_structure));
+ check(sr_session_load(context->_structure, filename.c_str(), &_structure));
GSList *dev_list;
check(sr_session_dev_list(_structure, &dev_list));
for (GSList *dev = dev_list; dev; dev = dev->next)
@@ -804,9 +918,6 @@ Session::~Session()
for (auto callback : _datafeed_callbacks)
delete callback;
- for (auto entry : _source_callbacks)
- delete entry.second;
-
for (auto entry : _owned_devices)
delete entry.second;
}
@@ -862,91 +973,29 @@ void Session::stop()
check(sr_session_stop(_structure));
}
-void Session::begin_save(string filename)
+bool Session::is_running() const
{
- _saving = true;
- _save_initialized = false;
- _save_filename = filename;
- _save_samplerate = 0;
+ const int ret = sr_session_is_running(_structure);
+ if (ret < 0)
+ throw Error{ret};
+ return (ret != 0);
}
-void Session::append(shared_ptr packet)
+static void session_stopped_callback(void *data)
{
- if (!_saving)
- throw Error(SR_ERR);
-
- switch (packet->_structure->type)
- {
- case SR_DF_META:
- {
- auto meta = (const struct sr_datafeed_meta *)
- packet->_structure->payload;
-
- for (auto l = meta->config; l; l = l->next)
- {
- auto config = (struct sr_config *) l->data;
- if (config->key == SR_CONF_SAMPLERATE)
- _save_samplerate = g_variant_get_uint64(config->data);
- }
-
- break;
- }
- case SR_DF_LOGIC:
- {
- if (_save_samplerate == 0)
- {
- GVariant *samplerate;
-
- check(sr_config_get(sr_dev_inst_driver_get(packet->_device->_structure),
- packet->_device->_structure, NULL, SR_CONF_SAMPLERATE,
- &samplerate));
-
- _save_samplerate = g_variant_get_uint64(samplerate);
-
- g_variant_unref(samplerate);
- }
-
- if (!_save_initialized)
- {
- vector> save_channels;
-
- for (auto channel : packet->_device->channels())
- if (channel->_structure->enabled &&
- channel->_structure->type == SR_CHANNEL_LOGIC)
- save_channels.push_back(channel);
-
- auto channels = g_new(char *, save_channels.size());
-
- int i = 0;
- for (auto channel : save_channels)
- channels[i++] = channel->_structure->name;
- channels[i] = NULL;
-
- int ret = sr_session_save_init(_structure, _save_filename.c_str(),
- _save_samplerate, channels);
-
- g_free(channels);
-
- if (ret != SR_OK)
- throw Error(ret);
-
- _save_initialized = true;
- }
-
- auto logic = (const struct sr_datafeed_logic *)
- packet->_structure->payload;
-
- check(sr_session_append(_structure, _save_filename.c_str(),
- (uint8_t *) logic->data, logic->unitsize,
- logic->length / logic->unitsize));
- }
- }
+ auto *const callback = static_cast(data);
+ (*callback)();
}
-void Session::append(void *data, size_t length, unsigned int unit_size)
+void Session::set_stopped_callback(SessionStoppedCallback callback)
{
- check(sr_session_append(_structure, _save_filename.c_str(),
- (uint8_t *) data, unit_size, length));
+ _stopped_callback = move(callback);
+ if (_stopped_callback)
+ check(sr_session_stopped_callback_set(_structure,
+ &session_stopped_callback, &_stopped_callback));
+ else
+ check(sr_session_stopped_callback_set(_structure,
+ nullptr, nullptr));
}
static void datafeed_callback(const struct sr_dev_inst *sdi,
@@ -972,66 +1021,6 @@ void Session::remove_datafeed_callbacks(void)
_datafeed_callbacks.clear();
}
-static int source_callback(int fd, int revents, void *cb_data)
-{
- (void) fd;
- auto callback = (SourceCallbackData *) cb_data;
- return callback->run(revents);
-}
-
-void Session::add_source(shared_ptr source)
-{
- if (_source_callbacks.count(source) == 1)
- throw Error(SR_ERR_ARG);
-
- auto cb_data = new SourceCallbackData(source);
-
- switch (source->_type)
- {
- case EventSource::SOURCE_FD:
- check(sr_session_source_add(_structure, source->_fd, source->_events,
- source->_timeout, source_callback, cb_data));
- break;
- case EventSource::SOURCE_POLLFD:
- check(sr_session_source_add_pollfd(_structure,
- source->_pollfd.gobj(), source->_timeout, source_callback,
- cb_data));
- break;
- case EventSource::SOURCE_IOCHANNEL:
- check(sr_session_source_add_channel(_structure,
- source->_channel->gobj(), source->_events, source->_timeout,
- source_callback, cb_data));
- break;
- }
-
- _source_callbacks[source] = cb_data;
-}
-
-void Session::remove_source(shared_ptr source)
-{
- if (_source_callbacks.count(source) == 0)
- throw Error(SR_ERR_ARG);
-
- switch (source->_type)
- {
- case EventSource::SOURCE_FD:
- check(sr_session_source_remove(_structure, source->_fd));
- break;
- case EventSource::SOURCE_POLLFD:
- check(sr_session_source_remove_pollfd(_structure,
- source->_pollfd.gobj()));
- break;
- case EventSource::SOURCE_IOCHANNEL:
- check(sr_session_source_remove_channel(_structure,
- source->_channel->gobj()));
- break;
- }
-
- delete _source_callbacks[source];
-
- _source_callbacks.erase(source);
-}
-
shared_ptr Session::trigger()
{
return _trigger;
@@ -1039,7 +1028,11 @@ shared_ptr Session::trigger()
void Session::set_trigger(shared_ptr trigger)
{
- check(sr_session_trigger_set(_structure, trigger->_structure));
+ if (!trigger)
+ // Set NULL trigger, i.e. remove any trigger from the session.
+ check(sr_session_trigger_set(_structure, NULL));
+ else
+ check(sr_session_trigger_set(_structure, trigger->_structure));
_trigger = trigger;
}
@@ -1048,6 +1041,11 @@ string Session::filename()
return _filename;
}
+shared_ptr Session::context()
+{
+ return _context;
+}
+
Packet::Packet(shared_ptr device,
const struct sr_datafeed_packet *structure) :
UserOwned(structure),
@@ -1070,9 +1068,9 @@ Packet::Packet(shared_ptr device,
static_cast(
structure->payload));
break;
- case SR_DF_ANALOG:
- _payload = new Analog(
- static_cast(
+ case SR_DF_ANALOG_OLD:
+ _payload = new AnalogOld(
+ static_cast(
structure->payload));
break;
default:
@@ -1194,33 +1192,33 @@ unsigned int Logic::unit_size()
return _structure->unitsize;
}
-Analog::Analog(const struct sr_datafeed_analog *structure) :
+AnalogOld::AnalogOld(const struct sr_datafeed_analog_old *structure) :
ParentOwned(structure),
PacketPayload()
{
}
-Analog::~Analog()
+AnalogOld::~AnalogOld()
{
}
-shared_ptr Analog::get_shared_pointer(Packet *_parent)
+shared_ptr AnalogOld::get_shared_pointer(Packet *_parent)
{
return static_pointer_cast(
ParentOwned::get_shared_pointer(_parent));
}
-float *Analog::data_pointer()
+float *AnalogOld::data_pointer()
{
return _structure->data;
}
-unsigned int Analog::num_samples()
+unsigned int AnalogOld::num_samples()
{
return _structure->num_samples;
}
-vector> Analog::channels()
+vector> AnalogOld::channels()
{
vector> result;
for (auto l = _structure->channels; l; l = l->next)
@@ -1229,17 +1227,17 @@ vector> Analog::channels()
return result;
}
-const Quantity *Analog::mq()
+const Quantity *AnalogOld::mq()
{
return Quantity::get(_structure->mq);
}
-const Unit *Analog::unit()
+const Unit *AnalogOld::unit()
{
return Unit::get(_structure->unit);
}
-vector Analog::mq_flags()
+vector AnalogOld::mq_flags()
{
return QuantityFlag::flags_from_mask(_structure->mqflags);
}
@@ -1263,15 +1261,27 @@ string InputFormat::description()
return valid_string(sr_input_description_get(_structure));
}
+vector InputFormat::extensions()
+{
+ vector exts;
+ for (const char *const *e = sr_input_extensions_get(_structure);
+ e && *e; e++)
+ exts.push_back(*e);
+ return exts;
+}
+
map> InputFormat::options()
{
const struct sr_option **options = sr_input_options_get(_structure);
- auto option_array = shared_ptr(
- options, sr_input_options_free);
map> result;
- for (int i = 0; options[i]; i++)
- result[options[i]->id] = shared_ptr