X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=bindings%2Fcxx%2Fclasses.cpp;h=357c9d6f3cbccac46f24a7d1c74025c525b40324;hb=81b3ce374c3b6d48e5ed321ac7a871ce4248a0bb;hp=525e046ddcc168fad28e599345bef3c9e7d53ac7;hpb=90e89c2a42ec085658f6c99656195ee4866e34c8;p=libsigrok.git diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index 525e046d..357c9d6f 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -17,9 +17,10 @@ * along with this program. If not, see . */ -#include "libsigrok/libsigrok.hpp" +#include "libsigrokcxx/libsigrokcxx.hpp" #include +#include namespace sigrok { @@ -71,42 +72,42 @@ shared_ptr Context::create() } Context::Context() : - UserOwned(structure), - session(NULL) + UserOwned(_structure), + _session(NULL) { - check(sr_init(&structure)); + 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] = + _drivers[driver_list[i]->name] = new Driver(driver_list[i]); const struct sr_input_module **input_list = sr_input_list(); if (input_list) for (int i = 0; input_list[i]; i++) - input_formats[sr_input_id_get(input_list[i])] = + _input_formats[sr_input_id_get(input_list[i])] = new InputFormat(input_list[i]); const struct sr_output_module **output_list = sr_output_list(); if (output_list) for (int i = 0; output_list[i]; i++) - output_formats[sr_output_id_get(output_list[i])] = + _output_formats[sr_output_id_get(output_list[i])] = new OutputFormat(output_list[i]); } -string Context::get_package_version() +string Context::package_version() { return sr_package_version_string_get(); } -string Context::get_lib_version() +string Context::lib_version() { return sr_lib_version_string_get(); } -map> Context::get_drivers() +map> Context::drivers() { map> result; - for (auto entry: drivers) + for (auto entry: _drivers) { auto name = entry.first; auto driver = entry.second; @@ -115,10 +116,10 @@ map> Context::get_drivers() return result; } -map> Context::get_input_formats() +map> Context::input_formats() { map> result; - for (auto entry: input_formats) + for (auto entry: _input_formats) { auto name = entry.first; auto input_format = entry.second; @@ -127,10 +128,10 @@ map> Context::get_input_formats() return result; } -map> Context::get_output_formats() +map> Context::output_formats() { map> result; - for (auto entry: output_formats) + for (auto entry: _output_formats) { auto name = entry.first; auto output_format = entry.second; @@ -141,26 +142,26 @@ map> Context::get_output_formats() Context::~Context() { - for (auto entry : drivers) + for (auto entry : _drivers) delete entry.second; - for (auto entry : input_formats) + for (auto entry : _input_formats) delete entry.second; - for (auto entry : output_formats) + for (auto entry : _output_formats) delete entry.second; - check(sr_exit(structure)); + check(sr_exit(_structure)); } -const LogLevel *Context::get_log_level() +const LogLevel *Context::log_level() { return LogLevel::get(sr_log_loglevel_get()); } void Context::set_log_level(const LogLevel *level) { - check(sr_log_loglevel_set(level->get_id())); + check(sr_log_loglevel_set(level->id())); } -string Context::get_log_domain() +string Context::log_domain() { return valid_string(sr_log_logdomain_get()); } @@ -197,14 +198,14 @@ static int call_log_callback(void *cb_data, int loglevel, const char *format, va void Context::set_log_callback(LogCallbackFunction callback) { - log_callback = callback; - check(sr_log_callback_set(call_log_callback, &log_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; + _log_callback = nullptr; } shared_ptr Context::create_session() @@ -213,6 +214,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_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, 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; + packet->payload = analog; + return shared_ptr(new Packet(nullptr, packet), Packet::Deleter()); +} + shared_ptr Context::load_session(string filename) { return shared_ptr( @@ -229,7 +301,7 @@ shared_ptr Context::open_file(string filename) { const struct sr_input *input; - check( sr_input_scan_file(filename.c_str(), &input)); + check(sr_input_scan_file(filename.c_str(), &input)); return shared_ptr( new Input(shared_from_this(), input), Input::Deleter()); } @@ -246,43 +318,51 @@ 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), - initialized(false) + Configurable(structure, NULL, NULL), + _initialized(false) { } Driver::~Driver() { - for (auto device : devices) - delete device; } -string Driver::get_name() +string Driver::name() { - return valid_string(structure->name); + return valid_string(_structure->name); } -string Driver::get_long_name() +string Driver::long_name() { - return valid_string(structure->longname); + return valid_string(_structure->longname); } vector> Driver::scan( map options) { /* Initialise the driver if not yet done. */ - if (!initialized) + if (!_initialized) { - check(sr_driver_init(parent->structure, structure)); - initialized = true; + check(sr_driver_init(_parent->_structure, _structure)); + _initialized = true; } - /* Clear all existing instances. */ - for (auto device : devices) - delete device; - devices.clear(); - /* Translate scan options to GSList of struct sr_config pointers. */ GSList *option_list = NULL; for (auto entry : options) @@ -290,31 +370,31 @@ vector> Driver::scan( auto key = entry.first; auto value = entry.second; auto config = g_new(struct sr_config, 1); - config->key = key->get_id(); + config->key = key->id(); config->data = value.gobj(); option_list = g_slist_append(option_list, config); } /* Run scan. */ - GSList *device_list = sr_driver_scan(structure, option_list); + GSList *device_list = sr_driver_scan(_structure, option_list); /* Free option list. */ g_slist_free_full(option_list, g_free); + /* Create device objects. */ + vector> result; for (GSList *device = device_list; device; device = device->next) { auto sdi = (struct sr_dev_inst *) device->data; - devices.push_back(new HardwareDevice(this, sdi)); + result.push_back(shared_ptr( + new HardwareDevice(shared_from_this(), sdi), + HardwareDevice::Deleter())); } /* Free GSList returned from scan. */ g_slist_free(device_list); - /* Create list of shared pointers to device instances for return. */ - vector> result; - for (auto device : devices) - result.push_back(device->get_shared_pointer(parent)); return result; } @@ -337,7 +417,7 @@ Glib::VariantBase Configurable::config_get(const ConfigKey *key) GVariant *data; check(sr_config_get( config_driver, config_sdi, config_channel_group, - key->get_id(), &data)); + key->id(), &data)); return Glib::VariantBase(data); } @@ -345,7 +425,7 @@ void Configurable::config_set(const ConfigKey *key, Glib::VariantBase value) { check(sr_config_set( config_sdi, config_channel_group, - key->get_id(), value.gobj())); + key->id(), value.gobj())); } Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) @@ -353,82 +433,140 @@ Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) GVariant *data; check(sr_config_list( config_driver, config_sdi, config_channel_group, - key->get_id(), &data)); + key->id(), &data)); return Glib::VariantContainerBase(data); } +map> Configurable::config_keys(const ConfigKey *key) +{ + GVariant *gvar_opts; + gsize num_opts; + const uint32_t *opts; + map> result; + + check(sr_config_list( + config_driver, config_sdi, config_channel_group, + key->id(), &gvar_opts)); + + opts = (const uint32_t *) g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(uint32_t)); + + for (gsize i = 0; i < num_opts; i++) + { + auto key = ConfigKey::get(opts[i] & SR_CONF_MASK); + set capabilities; + if (opts[i] & SR_CONF_GET) + capabilities.insert(GET); + if (opts[i] & SR_CONF_SET) + capabilities.insert(SET); + if (opts[i] & SR_CONF_LIST) + capabilities.insert(LIST); + result[key] = capabilities; + } + + g_variant_unref(gvar_opts); + + return result; +} + +bool Configurable::config_check(const ConfigKey *key, + const ConfigKey *index_key) +{ + GVariant *gvar_opts; + gsize num_opts; + const uint32_t *opts; + + if (sr_config_list(config_driver, config_sdi, config_channel_group, + index_key->id(), &gvar_opts) != SR_OK) + return false; + + opts = (const uint32_t *) g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(uint32_t)); + + for (gsize i = 0; i < num_opts; i++) + { + if ((opts[i] & SR_CONF_MASK) == (uint32_t) key->id()) + { + g_variant_unref(gvar_opts); + return true; + } + } + + g_variant_unref(gvar_opts); + + return false; +} + Device::Device(struct sr_dev_inst *structure) : - Configurable(structure->driver, structure, NULL), - structure(structure) + Configurable(sr_dev_inst_driver_get(structure), structure, NULL), + _structure(structure) { - for (GSList *entry = structure->channels; entry; entry = entry->next) + for (GSList *entry = sr_dev_inst_channels_get(structure); entry; entry = entry->next) { auto channel = (struct sr_channel *) entry->data; - channels[channel] = new Channel(channel); + _channels[channel] = new Channel(channel); } - for (GSList *entry = structure->channel_groups; entry; entry = entry->next) + for (GSList *entry = sr_dev_inst_channel_groups_get(structure); entry; entry = entry->next) { auto group = (struct sr_channel_group *) entry->data; - channel_groups[group->name] = new ChannelGroup(this, group); + _channel_groups[group->name] = new ChannelGroup(this, group); } } Device::~Device() { - for (auto entry : channels) + for (auto entry : _channels) delete entry.second; - for (auto entry : channel_groups) + for (auto entry : _channel_groups) delete entry.second; } -string Device::get_description() +string Device::vendor() { - ostringstream s; - - vector parts = - {get_vendor(), get_model(), get_version()}; - - for (string part : parts) - if (part.length() > 0) - s << part; + return valid_string(sr_dev_inst_vendor_get(_structure)); +} - return s.str(); +string Device::model() +{ + return valid_string(sr_dev_inst_model_get(_structure)); } -string Device::get_vendor() +string Device::version() { - return valid_string(structure->vendor); + return valid_string(sr_dev_inst_version_get(_structure)); } -string Device::get_model() +string Device::serial_number() { - return valid_string(structure->model); + return valid_string(sr_dev_inst_sernum_get(_structure)); } -string Device::get_version() +string Device::connection_id() { - return valid_string(structure->version); + return valid_string(sr_dev_inst_connid_get(_structure)); } -vector> Device::get_channels() +vector> Device::channels() { vector> result; - for (auto entry : channels) - result.push_back(entry.second->get_shared_pointer(get_shared_from_this())); + for (auto channel = sr_dev_inst_channels_get(_structure); channel; channel = channel->next) + result.push_back( + _channels[(struct sr_channel *) channel->data]->get_shared_pointer( + get_shared_from_this())); return result; } shared_ptr Device::get_channel(struct sr_channel *ptr) { - return channels[ptr]->get_shared_pointer(get_shared_from_this()); + return _channels[ptr]->get_shared_pointer(get_shared_from_this()); } map> -Device::get_channel_groups() +Device::channel_groups() { map> result; - for (auto entry: channel_groups) + for (auto entry: _channel_groups) { auto name = entry.first; auto channel_group = entry.second; @@ -439,18 +577,19 @@ Device::get_channel_groups() void Device::open() { - check(sr_dev_open(structure)); + check(sr_dev_open(_structure)); } void Device::close() { - check(sr_dev_close(structure)); + check(sr_dev_close(_structure)); } -HardwareDevice::HardwareDevice(Driver *driver, struct sr_dev_inst *structure) : - ParentOwned(structure), +HardwareDevice::HardwareDevice(shared_ptr driver, + struct sr_dev_inst *structure) : + UserOwned(structure), Device(structure), - driver(driver) + _driver(driver) { } @@ -463,14 +602,42 @@ shared_ptr HardwareDevice::get_shared_from_this() return static_pointer_cast(shared_from_this()); } -shared_ptr HardwareDevice::get_driver() +shared_ptr HardwareDevice::driver() { - return driver->get_shared_pointer(parent); + 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)) + _type(ChannelType::get(_structure->type)) { } @@ -478,95 +645,96 @@ Channel::~Channel() { } -string Channel::get_name() +string Channel::name() { - return valid_string(structure->name); + return valid_string(_structure->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::get_type() +const ChannelType *Channel::type() { - return ChannelType::get(structure->type); + return ChannelType::get(_structure->type); } -bool Channel::get_enabled() +bool Channel::enabled() { - return structure->enabled; + return _structure->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::get_index() +unsigned int Channel::index() { - return structure->index; + return _structure->index; } ChannelGroup::ChannelGroup(Device *device, struct sr_channel_group *structure) : ParentOwned(structure), - Configurable(device->structure->driver, device->structure, structure) + Configurable(sr_dev_inst_driver_get(device->_structure), device->_structure, structure) { for (GSList *entry = structure->channels; entry; entry = entry->next) - channels.push_back(device->channels[(struct sr_channel *)entry->data]); + _channels.push_back(device->_channels[(struct sr_channel *)entry->data]); } ChannelGroup::~ChannelGroup() { } -string ChannelGroup::get_name() +string ChannelGroup::name() { - return valid_string(structure->name); + return valid_string(_structure->name); } -vector> ChannelGroup::get_channels() +vector> ChannelGroup::channels() { vector> result; - for (auto channel : channels) - result.push_back(channel->get_shared_pointer(parent)); + for (auto channel : _channels) + result.push_back(channel->get_shared_pointer(_parent)); return result; } Trigger::Trigger(shared_ptr context, string name) : UserOwned(sr_trigger_new(name.c_str())), - context(context) + _context(context) { - for (auto stage = structure->stages; stage; stage = stage->next) - stages.push_back(new TriggerStage((struct sr_trigger_stage *) stage->data)); + for (auto stage = _structure->stages; stage; stage = stage->next) + _stages.push_back( + new TriggerStage((struct sr_trigger_stage *) stage->data)); } Trigger::~Trigger() { - for (auto stage: stages) + for (auto stage: _stages) delete stage; - sr_trigger_free(structure); + sr_trigger_free(_structure); } -string Trigger::get_name() +string Trigger::name() { - return structure->name; + return _structure->name; } -vector> Trigger::get_stages() +vector> Trigger::stages() { vector> result; - for (auto stage : stages) + for (auto stage : _stages) result.push_back(stage->get_shared_pointer(this)); return result; } shared_ptr Trigger::add_stage() { - auto stage = new TriggerStage(sr_trigger_stage_add(structure)); - stages.push_back(stage); + auto stage = new TriggerStage(sr_trigger_stage_add(_structure)); + _stages.push_back(stage); return stage->get_shared_pointer(this); } @@ -577,37 +745,43 @@ TriggerStage::TriggerStage(struct sr_trigger_stage *structure) : TriggerStage::~TriggerStage() { - for (auto match : matches) + for (auto match : _matches) delete match; } -int TriggerStage::get_number() +int TriggerStage::number() { - return structure->stage; + return _structure->stage; } -vector> TriggerStage::get_matches() +vector> TriggerStage::matches() { vector> result; - for (auto match : matches) + for (auto match : _matches) result.push_back(match->get_shared_pointer(this)); return result; } -void TriggerStage::add_match(shared_ptr channel, const TriggerMatchType *type, float value) +void TriggerStage::add_match(shared_ptr channel, + const TriggerMatchType *type, float value) { - check(sr_trigger_match_add(structure, channel->structure, type->get_id(), value)); - matches.push_back(new TriggerMatch( - (struct sr_trigger_match *) g_slist_last(structure->matches)->data, channel)); + check(sr_trigger_match_add(_structure, + channel->_structure, type->id(), value)); + _matches.push_back(new TriggerMatch( + (struct sr_trigger_match *) g_slist_last( + _structure->matches)->data, channel)); } -void TriggerStage::add_match(shared_ptr channel, const TriggerMatchType *type) +void TriggerStage::add_match(shared_ptr channel, + const TriggerMatchType *type) { add_match(channel, type, NAN); } -TriggerMatch::TriggerMatch(struct sr_trigger_match *structure, shared_ptr channel) : - ParentOwned(structure), channel(channel) +TriggerMatch::TriggerMatch(struct sr_trigger_match *structure, + shared_ptr channel) : + ParentOwned(structure), + _channel(channel) { } @@ -615,52 +789,53 @@ TriggerMatch::~TriggerMatch() { } -shared_ptr TriggerMatch::get_channel() +shared_ptr TriggerMatch::channel() { - return channel; + return _channel; } -const TriggerMatchType *TriggerMatch::get_type() +const TriggerMatchType *TriggerMatch::type() { - return TriggerMatchType::get(structure->match); + return TriggerMatchType::get(_structure->match); } -float TriggerMatch::get_value() +float TriggerMatch::value() { - return structure->value; + return _structure->value; } DatafeedCallbackData::DatafeedCallbackData(Session *session, DatafeedCallbackFunction callback) : - callback(callback), session(session) + _callback(callback), + _session(session) { } void DatafeedCallbackData::run(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *pkt) { - auto device = session->devices[sdi]; + auto device = _session->get_device(sdi); auto packet = shared_ptr(new Packet(device, pkt), Packet::Deleter()); - callback(device, packet); + _callback(device, packet); } SourceCallbackData::SourceCallbackData(shared_ptr source) : - source(source) + _source(source) { } bool SourceCallbackData::run(int revents) { - return source->callback((Glib::IOCondition) 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; + result->_type = EventSource::SOURCE_FD; + result->_fd = fd; + result->_events = events; return shared_ptr(result, EventSource::Deleter()); } @@ -668,8 +843,8 @@ 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; + result->_type = EventSource::SOURCE_POLLFD; + result->_pollfd = pollfd; return shared_ptr(result, EventSource::Deleter()); } @@ -677,14 +852,15 @@ shared_ptr EventSource::create(Glib::RefPtr channe Glib::IOCondition events, int timeout, SourceCallbackFunction callback) { auto result = new EventSource(timeout, callback); - result->type = EventSource::SOURCE_IOCHANNEL; - result->channel = channel; - result->events = events; + 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) + _timeout(timeout), + _callback(callback) { } @@ -692,148 +868,187 @@ EventSource::~EventSource() { } +SessionDevice::SessionDevice(struct sr_dev_inst *structure) : + ParentOwned(structure), + Device(structure) +{ +} + +SessionDevice::~SessionDevice() +{ +} + +shared_ptr SessionDevice::get_shared_from_this() +{ + return static_pointer_cast(shared_from_this()); +} + Session::Session(shared_ptr context) : - UserOwned(structure), - context(context), saving(false) + UserOwned(_structure), + _context(context), + _saving(false) { - check(sr_session_new(&structure)); - context->session = this; + check(sr_session_new(context->_structure, &_structure)); + _context->_session = this; } Session::Session(shared_ptr context, string filename) : - UserOwned(structure), - context(context), saving(false) + UserOwned(_structure), + _context(context), + _filename(filename), + _saving(false) { - check(sr_session_load(filename.c_str(), &structure)); - context->session = this; + 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) + { + auto sdi = (struct sr_dev_inst *) dev->data; + _owned_devices[sdi] = new SessionDevice(sdi); + } + _context->_session = this; } Session::~Session() { - check(sr_session_destroy(structure)); + check(sr_session_destroy(_structure)); - for (auto callback : datafeed_callbacks) + for (auto callback : _datafeed_callbacks) delete callback; - for (auto entry : source_callbacks) + for (auto entry : _source_callbacks) + delete entry.second; + + for (auto entry : _owned_devices) delete entry.second; } +shared_ptr Session::get_device(const struct sr_dev_inst *sdi) +{ + if (_owned_devices.count(sdi)) + return static_pointer_cast( + _owned_devices[sdi]->get_shared_pointer(this)); + else if (_other_devices.count(sdi)) + return _other_devices[sdi]; + else + throw Error(SR_ERR_BUG); +} + void Session::add_device(shared_ptr device) { - check(sr_session_dev_add(structure, device->structure)); - devices[device->structure] = device; + check(sr_session_dev_add(_structure, device->_structure)); + _other_devices[device->_structure] = device; } -vector> Session::get_devices() +vector> Session::devices() { GSList *dev_list; - check(sr_session_dev_list(structure, &dev_list)); + check(sr_session_dev_list(_structure, &dev_list)); vector> result; for (GSList *dev = dev_list; dev; dev = dev->next) { auto sdi = (struct sr_dev_inst *) dev->data; - result.push_back(devices[sdi]); + result.push_back(get_device(sdi)); } return result; } void Session::remove_devices() { - devices.clear(); - check(sr_session_dev_remove_all(structure)); + _other_devices.clear(); + check(sr_session_dev_remove_all(_structure)); } void Session::start() { - check(sr_session_start(structure)); + check(sr_session_start(_structure)); } void Session::run() { - check(sr_session_run(structure)); + check(sr_session_run(_structure)); } void Session::stop() { - check(sr_session_stop(structure)); + check(sr_session_stop(_structure)); } void Session::begin_save(string filename) { - saving = true; - save_initialized = false; - save_filename = filename; - save_samplerate = 0; + _saving = true; + _save_initialized = false; + _save_filename = filename; + _save_samplerate = 0; } void Session::append(shared_ptr packet) { - if (!saving) + if (!_saving) throw Error(SR_ERR); - switch (packet->structure->type) + switch (packet->_structure->type) { case SR_DF_META: { auto meta = (const struct sr_datafeed_meta *) - packet->structure->payload; + 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); + _save_samplerate = g_variant_get_uint64(config->data); } break; } case SR_DF_LOGIC: { - if (save_samplerate == 0) + if (_save_samplerate == 0) { GVariant *samplerate; - check(sr_config_get(packet->device->structure->driver, - packet->device->structure, NULL, SR_CONF_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); + _save_samplerate = g_variant_get_uint64(samplerate); g_variant_unref(samplerate); } - if (!save_initialized) + if (!_save_initialized) { vector> save_channels; - for (auto channel : packet->device->get_channels()) - if (channel->structure->enabled && - channel->structure->type == SR_CHANNEL_LOGIC) + 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++] = channel->_structure->name; channels[i] = NULL; - int ret = sr_session_save_init(structure, save_filename.c_str(), - save_samplerate, channels); + 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; + _save_initialized = true; } auto logic = (const struct sr_datafeed_logic *) - packet->structure->payload; + packet->_structure->payload; - check(sr_session_append(structure, save_filename.c_str(), + check(sr_session_append(_structure, _save_filename.c_str(), (uint8_t *) logic->data, logic->unitsize, logic->length / logic->unitsize)); } @@ -842,7 +1057,7 @@ void Session::append(shared_ptr packet) void Session::append(void *data, size_t length, unsigned int unit_size) { - check(sr_session_append(structure, save_filename.c_str(), + check(sr_session_append(_structure, _save_filename.c_str(), (uint8_t *) data, unit_size, length)); } @@ -856,16 +1071,17 @@ static void datafeed_callback(const struct sr_dev_inst *sdi, void Session::add_datafeed_callback(DatafeedCallbackFunction callback) { auto cb_data = new DatafeedCallbackData(this, callback); - check(sr_session_datafeed_callback_add(structure, datafeed_callback, cb_data)); - datafeed_callbacks.push_back(cb_data); + check(sr_session_datafeed_callback_add(_structure, + datafeed_callback, cb_data)); + _datafeed_callbacks.push_back(cb_data); } void Session::remove_datafeed_callbacks(void) { - check(sr_session_datafeed_callback_remove_all(structure)); - for (auto callback : datafeed_callbacks) + check(sr_session_datafeed_callback_remove_all(_structure)); + for (auto callback : _datafeed_callbacks) delete callback; - datafeed_callbacks.clear(); + _datafeed_callbacks.clear(); } static int source_callback(int fd, int revents, void *cb_data) @@ -877,116 +1093,130 @@ static int source_callback(int fd, int revents, void *cb_data) void Session::add_source(shared_ptr source) { - if (source_callbacks.count(source) == 1) + if (_source_callbacks.count(source) == 1) throw Error(SR_ERR_ARG); auto cb_data = new SourceCallbackData(source); - switch (source->type) + switch (source->_type) { case EventSource::SOURCE_FD: - check(sr_session_source_add(structure, source->fd, source->events, - source->timeout, source_callback, cb_data)); + 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, + 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, + check(sr_session_source_add_channel(_structure, + source->_channel->gobj(), source->_events, source->_timeout, source_callback, cb_data)); break; } - source_callbacks[source] = cb_data; + _source_callbacks[source] = cb_data; } void Session::remove_source(shared_ptr source) { - if (source_callbacks.count(source) == 0) + if (_source_callbacks.count(source) == 0) throw Error(SR_ERR_ARG); - switch (source->type) + switch (source->_type) { case EventSource::SOURCE_FD: - check(sr_session_source_remove(structure, 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())); + 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())); + check(sr_session_source_remove_channel(_structure, + source->_channel->gobj())); break; } - delete source_callbacks[source]; + delete _source_callbacks[source]; - source_callbacks.erase(source); + _source_callbacks.erase(source); } -shared_ptr Session::get_trigger() +shared_ptr Session::trigger() { - return trigger; + return _trigger; } void Session::set_trigger(shared_ptr trigger) { - check(sr_session_trigger_set(structure, trigger->structure)); - this->trigger = trigger; + 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; +} + +string Session::filename() +{ + return _filename; +} + +shared_ptr Session::context() +{ + return _context; } Packet::Packet(shared_ptr device, const struct sr_datafeed_packet *structure) : UserOwned(structure), - device(device) + _device(device) { switch (structure->type) { case SR_DF_HEADER: - payload = new Header( + _payload = new Header( static_cast( structure->payload)); break; case SR_DF_META: - payload = new Meta( + _payload = new Meta( static_cast( structure->payload)); break; case SR_DF_LOGIC: - payload = new Logic( + _payload = new Logic( static_cast( structure->payload)); break; case SR_DF_ANALOG: - payload = new Analog( + _payload = new Analog( static_cast( structure->payload)); break; default: - payload = nullptr; + _payload = nullptr; break; } } Packet::~Packet() { - if (payload) - delete payload; + if (_payload) + delete _payload; } -const PacketType *Packet::get_type() +const PacketType *Packet::type() { - return PacketType::get(structure->type); + return PacketType::get(_structure->type); } -shared_ptr Packet::get_payload() +shared_ptr Packet::payload() { - if (payload) - return payload->get_shared_pointer(this); + if (_payload) + return _payload->get_shared_pointer(this); else throw Error(SR_ERR_NA); } @@ -1009,21 +1239,22 @@ Header::~Header() { } -shared_ptr Header::get_shared_pointer(Packet *parent) +shared_ptr Header::get_shared_pointer(Packet *_parent) { - return static_pointer_cast(get_shared_pointer(parent)); + return static_pointer_cast( + ParentOwned::get_shared_pointer(_parent)); } -int Header::get_feed_version() +int Header::feed_version() { - return structure->feed_version; + return _structure->feed_version; } -Glib::TimeVal Header::get_start_time() +Glib::TimeVal Header::start_time() { return Glib::TimeVal( - structure->starttime.tv_sec, - structure->starttime.tv_usec); + _structure->starttime.tv_sec, + _structure->starttime.tv_usec); } Meta::Meta(const struct sr_datafeed_meta *structure) : @@ -1036,15 +1267,16 @@ Meta::~Meta() { } -shared_ptr Meta::get_shared_pointer(Packet *parent) +shared_ptr Meta::get_shared_pointer(Packet *_parent) { - return static_pointer_cast(get_shared_pointer(parent)); + return static_pointer_cast( + ParentOwned::get_shared_pointer(_parent)); } -map Meta::get_config() +map Meta::config() { map result; - for (auto l = structure->config; l; l = l->next) + for (auto l = _structure->config; l; l = l->next) { auto config = (struct sr_config *) l->data; result[ConfigKey::get(config->key)] = Glib::VariantBase(config->data); @@ -1062,24 +1294,25 @@ Logic::~Logic() { } -shared_ptr Logic::get_shared_pointer(Packet *parent) +shared_ptr Logic::get_shared_pointer(Packet *_parent) { - return static_pointer_cast(get_shared_pointer(parent)); + return static_pointer_cast( + ParentOwned::get_shared_pointer(_parent)); } -void *Logic::get_data_pointer() +void *Logic::data_pointer() { - return structure->data; + return _structure->data; } -size_t Logic::get_data_length() +size_t Logic::data_length() { - return structure->length; + return _structure->length; } -unsigned int Logic::get_unit_size() +unsigned int Logic::unit_size() { - return structure->unitsize; + return _structure->unitsize; } Analog::Analog(const struct sr_datafeed_analog *structure) : @@ -1092,43 +1325,44 @@ Analog::~Analog() { } -shared_ptr Analog::get_shared_pointer(Packet *parent) +shared_ptr Analog::get_shared_pointer(Packet *_parent) { - return static_pointer_cast(get_shared_pointer(parent)); + return static_pointer_cast( + ParentOwned::get_shared_pointer(_parent)); } -float *Analog::get_data_pointer() +float *Analog::data_pointer() { - return structure->data; + return _structure->data; } -unsigned int Analog::get_num_samples() +unsigned int Analog::num_samples() { - return structure->num_samples; + return _structure->num_samples; } -vector> Analog::get_channels() +vector> Analog::channels() { vector> result; - for (auto l = structure->channels; l; l = l->next) - result.push_back(parent->device->get_channel( + for (auto l = _structure->channels; l; l = l->next) + result.push_back(_parent->_device->get_channel( (struct sr_channel *)l->data)); return result; } -const Quantity *Analog::get_mq() +const Quantity *Analog::mq() { - return Quantity::get(structure->mq); + return Quantity::get(_structure->mq); } -const Unit *Analog::get_unit() +const Unit *Analog::unit() { - return Unit::get(structure->unit); + return Unit::get(_structure->unit); } -vector Analog::get_mq_flags() +vector Analog::mq_flags() { - return QuantityFlag::flags_from_mask(structure->mqflags); + return QuantityFlag::flags_from_mask(_structure->mqflags); } InputFormat::InputFormat(const struct sr_input_module *structure) : @@ -1140,78 +1374,95 @@ InputFormat::~InputFormat() { } -string InputFormat::get_name() +string InputFormat::name() +{ + return valid_string(sr_input_id_get(_structure)); +} + +string InputFormat::description() { - return valid_string(sr_input_id_get(structure)); + return valid_string(sr_input_description_get(_structure)); } -string InputFormat::get_description() +vector InputFormat::extensions() { - return valid_string(sr_input_description_get(structure)); + vector exts; + for (const char *const *e = sr_input_extensions_get(_structure); + e && *e; e++) + exts.push_back(*e); + return exts; } -map> InputFormat::get_options() +map> InputFormat::options() { - const struct sr_option **options = sr_input_options_get(structure); - auto option_array = shared_ptr( - options, sr_input_options_free); + const struct sr_option **options = sr_input_options_get(_structure); map> result; - for (int i = 0; options[i]; i++) - result[options[i]->id] = shared_ptr