X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=bindings%2Fcxx%2Fclasses.cpp;h=357c9d6f3cbccac46f24a7d1c74025c525b40324;hb=81b3ce374c3b6d48e5ed321ac7a871ce4248a0bb;hp=ec9b6d8f289e8bddd5825fe3b3b33601951f066a;hpb=3b161085731fc6e86f7decedee34f55096282581;p=libsigrok.git diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index ec9b6d8f..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 { @@ -76,7 +77,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] = @@ -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( @@ -246,6 +318,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), @@ -255,8 +341,6 @@ Driver::Driver(struct sr_dev_driver *structure) : Driver::~Driver() { - for (auto device : _devices) - delete device; } string Driver::name() @@ -279,11 +363,6 @@ vector> Driver::scan( _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) @@ -302,20 +381,20 @@ vector> Driver::scan( /* 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; } @@ -358,22 +437,32 @@ Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) return Glib::VariantContainerBase(data); } -vector Configurable::config_keys(const ConfigKey *key) +map> Configurable::config_keys(const ConfigKey *key) { GVariant *gvar_opts; gsize num_opts; - const int32_t *opts; - vector result; + const uint32_t *opts; + map> result; check(sr_config_list( config_driver, config_sdi, config_channel_group, key->id(), &gvar_opts)); - opts = (const int32_t *) g_variant_get_fixed_array( - gvar_opts, &num_opts, sizeof(int32_t)); + opts = (const uint32_t *) g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(uint32_t)); for (gsize i = 0; i < num_opts; i++) - result.push_back(ConfigKey::get(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); @@ -385,18 +474,18 @@ bool Configurable::config_check(const ConfigKey *key, { GVariant *gvar_opts; gsize num_opts; - const int32_t *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 int32_t *) g_variant_get_fixed_array( - gvar_opts, &num_opts, sizeof(int32_t)); + 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] == key->id()) + if ((opts[i] & SR_CONF_MASK) == (uint32_t) key->id()) { g_variant_unref(gvar_opts); return true; @@ -409,16 +498,16 @@ bool Configurable::config_check(const ConfigKey *key, } Device::Device(struct sr_dev_inst *structure) : - Configurable(structure->driver, structure, NULL), + 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); } - 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); @@ -433,39 +522,35 @@ Device::~Device() delete entry.second; } -string Device::description() +string Device::vendor() { - ostringstream s; - - vector parts = - {vendor(), model(), 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::vendor() +string Device::version() { - return valid_string(_structure->vendor); + return valid_string(sr_dev_inst_version_get(_structure)); } -string Device::model() +string Device::serial_number() { - return valid_string(_structure->model); + return valid_string(sr_dev_inst_sernum_get(_structure)); } -string Device::version() +string Device::connection_id() { - return valid_string(_structure->version); + return valid_string(sr_dev_inst_connid_get(_structure)); } vector> Device::channels() { vector> result; - for (auto channel = _structure->channels; channel; channel = channel->next) + 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())); @@ -500,8 +585,9 @@ void Device::close() 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) { @@ -518,7 +604,35 @@ shared_ptr HardwareDevice::get_shared_from_this() 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) : @@ -538,8 +652,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() @@ -554,7 +667,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() @@ -565,7 +678,7 @@ unsigned int Channel::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]); @@ -701,7 +814,7 @@ DatafeedCallbackData::DatafeedCallbackData(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); } @@ -775,24 +888,23 @@ Session::Session(shared_ptr context) : _context(context), _saving(false) { - 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) { - 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) { auto sdi = (struct sr_dev_inst *) dev->data; - auto device = new SessionDevice(sdi); - _devices[sdi] = shared_ptr(device, - SessionDevice::Deleter()); + _owned_devices[sdi] = new SessionDevice(sdi); } _context->_session = this; } @@ -806,12 +918,26 @@ Session::~Session() 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; + _other_devices[device->_structure] = device; } vector> Session::devices() @@ -822,14 +948,14 @@ vector> Session::devices() 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(); + _other_devices.clear(); check(sr_session_dev_remove_all(_structure)); } @@ -883,7 +1009,7 @@ void Session::append(shared_ptr packet) { GVariant *samplerate; - check(sr_config_get(packet->_device->_structure->driver, + check(sr_config_get(sr_dev_inst_driver_get(packet->_device->_structure), packet->_device->_structure, NULL, SR_CONF_SAMPLERATE, &samplerate)); @@ -1025,10 +1151,24 @@ 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; } +string Session::filename() +{ + return _filename; +} + +shared_ptr Session::context() +{ + return _context; +} + Packet::Packet(shared_ptr device, const struct sr_datafeed_packet *structure) : UserOwned(structure), @@ -1244,15 +1384,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