* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* Needed for isascii(), as used in the GNU libstdc++ headers */
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600
+#endif
+
#include <config.h>
#include <libsigrokcxx/libsigrokcxx.hpp>
{
}
+ResourceReader::~ResourceReader()
+{
+}
+
+SR_PRIV int ResourceReader::open_callback(struct sr_resource *res,
+ const char *name, void *cb_data)
+{
+ try {
+ auto *const reader = static_cast<ResourceReader*>(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<ResourceReader*>(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<ResourceReader*>(cb_data);
+ return reader->read(res, buf, count);
+ } catch (const Error &err) {
+ return err.result;
+ } catch (...) {
+ return SR_ERR;
+ }
+}
+
shared_ptr<Context> Context::create()
{
return shared_ptr<Context>(new Context(), Context::Deleter());
{
_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<Session> Context::create_session()
{
const Unit *unit, vector<const QuantityFlag *> mqflags)
{
auto analog = g_new0(struct sr_datafeed_analog, 1);
+ auto meaning = g_new0(struct sr_analog_meaning, 1);
+
+ analog->meaning = meaning;
+
for (auto channel : channels)
- analog->channels = g_slist_append(analog->channels, channel->_structure);
+ meaning->channels = g_slist_append(meaning->channels, channel->_structure);
analog->num_samples = num_samples;
- analog->mq = mq->id();
- analog->unit = unit->id();
- analog->mqflags = QuantityFlag::mask_from_flags(mqflags);
+ meaning->mq = (sr_mq)mq->id();
+ meaning->unit = (sr_unit)unit->id();
+ meaning->mqflags = (sr_mqflag)QuantityFlag::mask_from_flags(mqflags);
analog->data = data_pointer;
auto packet = g_new(struct sr_datafeed_packet, 1);
packet->type = SR_DF_ANALOG;
_callback(device, packet);
}
-SourceCallbackData::SourceCallbackData(shared_ptr<EventSource> source) :
- _source(source)
-{
-}
-
-bool SourceCallbackData::run(int revents)
-{
- return _source->_callback((Glib::IOCondition) revents);
-}
-
-shared_ptr<EventSource> 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<EventSource>(result, EventSource::Deleter());
-}
-
-shared_ptr<EventSource> 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<EventSource>(result, EventSource::Deleter());
-}
-
-shared_ptr<EventSource> EventSource::create(Glib::RefPtr<Glib::IOChannel> 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<EventSource>(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)
Session::Session(shared_ptr<Context> context) :
UserOwned(_structure),
- _context(context),
- _saving(false)
+ _context(context)
{
check(sr_session_new(context->_structure, &_structure));
_context->_session = this;
Session::Session(shared_ptr<Context> context, string filename) :
UserOwned(_structure),
_context(context),
- _filename(filename),
- _saving(false)
+ _filename(filename)
{
check(sr_session_load(context->_structure, filename.c_str(), &_structure));
GSList *dev_list;
for (auto callback : _datafeed_callbacks)
delete callback;
- for (auto entry : _source_callbacks)
- delete entry.second;
-
for (auto entry : _owned_devices)
delete entry.second;
}
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> 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<shared_ptr<Channel>> 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<SessionStoppedCallback*>(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,
_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<EventSource> 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<EventSource> 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<Trigger> Session::trigger()
{
return _trigger;
ParentOwned::get_shared_pointer(_parent));
}
-float *Analog::data_pointer()
+void *Analog::data_pointer()
{
return _structure->data;
}
vector<shared_ptr<Channel>> Analog::channels()
{
vector<shared_ptr<Channel>> result;
- for (auto l = _structure->channels; l; l = l->next)
+ for (auto l = _structure->meaning->channels; l; l = l->next)
result.push_back(_parent->_device->get_channel(
(struct sr_channel *)l->data));
return result;
const Quantity *Analog::mq()
{
- return Quantity::get(_structure->mq);
+ return Quantity::get(_structure->meaning->mq);
}
const Unit *Analog::unit()
{
- return Unit::get(_structure->unit);
+ return Unit::get(_structure->meaning->unit);
}
vector<const QuantityFlag *> Analog::mq_flags()
{
- return QuantityFlag::flags_from_mask(_structure->mqflags);
+ return QuantityFlag::flags_from_mask(_structure->meaning->mqflags);
}
InputFormat::InputFormat(const struct sr_input_module *structure) :