* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "libsigrok/libsigrok.hpp"
+#include "libsigrokcxx/libsigrokcxx.hpp"
#include <sstream>
+#include <cmath>
namespace sigrok
{
new Session(shared_from_this()), Session::Deleter());
}
+shared_ptr<UserDevice> Context::create_user_device(
+ string vendor, string model, string version)
+{
+ return shared_ptr<UserDevice>(
+ new UserDevice(vendor, model, version), UserDevice::Deleter());
+}
+
+shared_ptr<Packet> 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<Packet>(new Packet(nullptr, packet), Packet::Deleter());
+}
+
+shared_ptr<Packet> Context::create_meta_packet(
+ map<const ConfigKey *, Glib::VariantBase> 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<Packet>(new Packet(nullptr, packet), Packet::Deleter());
+}
+
+shared_ptr<Packet> 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<Packet>(new Packet(nullptr, packet), Packet::Deleter());
+}
+
+shared_ptr<Packet> Context::create_analog_packet(
+ vector<shared_ptr<Channel> > channels,
+ float *data_pointer, unsigned int num_samples, const Quantity *mq,
+ const Unit *unit, vector<const QuantityFlag *> 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<Packet>(new Packet(nullptr, packet), Packet::Deleter());
+}
+
shared_ptr<Session> Context::load_session(string filename)
{
return shared_ptr<Session>(
new Input(shared_from_this(), input), Input::Deleter());
}
+map<string, string> Context::serials(shared_ptr<Driver> driver)
+{
+ GSList *serial_list = sr_serial_list(driver ? driver->_structure : NULL);
+ map<string, string> 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),
Driver::~Driver()
{
- for (auto device : _devices)
- delete device;
}
string Driver::name()
_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)
/* Free option list. */
g_slist_free_full(option_list, g_free);
+
/* Create device objects. */
+ vector<shared_ptr<HardwareDevice>> 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<HardwareDevice>(
+ 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<shared_ptr<HardwareDevice>> result;
- for (auto device : _devices)
- result.push_back(device->get_shared_pointer(_parent));
return result;
}
return Glib::VariantContainerBase(data);
}
-vector<const ConfigKey *> Configurable::config_keys(const ConfigKey *key)
+map<const ConfigKey *, set<Capability>> Configurable::config_keys(const ConfigKey *key)
{
GVariant *gvar_opts;
gsize num_opts;
- const int32_t *opts;
- vector<const ConfigKey *> result;
+ const uint32_t *opts;
+ map<const ConfigKey *, set<Capability>> 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<Capability> 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);
{
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;
}
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);
delete entry.second;
}
-string Device::description()
+string Device::vendor()
{
- ostringstream s;
-
- vector<string> 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<shared_ptr<Channel>> Device::channels()
{
vector<shared_ptr<Channel>> 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()));
check(sr_dev_close(_structure));
}
-HardwareDevice::HardwareDevice(Driver *driver, struct sr_dev_inst *structure) :
- ParentOwned(structure),
+HardwareDevice::HardwareDevice(shared_ptr<Driver> driver,
+ struct sr_dev_inst *structure) :
+ UserOwned(structure),
Device(structure),
_driver(driver)
{
shared_ptr<Driver> 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<Device> UserDevice::get_shared_from_this()
+{
+ return static_pointer_cast<Device>(shared_from_this());
+}
+
+shared_ptr<Channel> 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) :
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]);
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<Packet>(new Packet(device, pkt), Packet::Deleter());
_callback(device, packet);
}
Session::Session(shared_ptr<Context> context, string filename) :
UserOwned(_structure),
_context(context),
+ _filename(filename),
_saving(false)
{
check(sr_session_load(filename.c_str(), &_structure));
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<SessionDevice>(device,
- SessionDevice::Deleter());
+ _owned_devices[sdi] = new SessionDevice(sdi);
}
_context->_session = this;
}
for (auto entry : _source_callbacks)
delete entry.second;
+
+ for (auto entry : _owned_devices)
+ delete entry.second;
+}
+
+shared_ptr<Device> Session::get_device(const struct sr_dev_inst *sdi)
+{
+ if (_owned_devices.count(sdi))
+ return static_pointer_cast<Device>(
+ _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> device)
{
check(sr_session_dev_add(_structure, device->_structure));
- _devices[device->_structure] = device;
+ _other_devices[device->_structure] = device;
}
vector<shared_ptr<Device>> 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));
}
{
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));
void Session::set_trigger(shared_ptr<Trigger> 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<Context> Session::context()
+{
+ return _context;
+}
+
Packet::Packet(shared_ptr<Device> device,
const struct sr_datafeed_packet *structure) :
UserOwned(structure),
check(ret);
}
+void Input::end()
+{
+ check(sr_input_end(_structure));
+}
+
Input::~Input()
{
if (_device)
delete _device;
- check(sr_input_free(_structure));
+ sr_input_free(_structure);
}
InputDevice::InputDevice(shared_ptr<Input> input,