/* * This file is part of the DSLogic-gui project. * DSLogic-gui is based on PulseView. * * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk> * Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef DSLOGIC_PV_SIGSESSION_H #define DSLOGIC_PV_SIGSESSION_H #include <boost/function.hpp> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <boost/thread.hpp> #include <string> #include <utility> #include <map> #include <set> #include <string> #include <vector> #include <QObject> #include <QString> #include <QLine> #include <QVector> #include <QMap> #include <QVariant> #include <libsigrok4DSLogic/libsigrok.h> #include <libusb.h> struct srd_decoder; struct srd_channel; namespace pv { class DeviceManager; namespace data { class SignalData; class Analog; class AnalogSnapshot; class Dso; class DsoSnapshot; class Logic; class LogicSnapshot; class Group; class GroupSnapshot; } namespace device { class DevInst; } namespace view { class Signal; class GroupSignal; class DecodeTrace; } namespace decoder { class Decoder; class DecoderFactory; } class SigSession : public QObject { Q_OBJECT private: static const float Oversampling; public: enum capture_state { Init, Stopped, Running }; public: SigSession(DeviceManager &device_manager); ~SigSession(); boost::shared_ptr<device::DevInst> get_device() const; /** * Sets device instance that will be used in the next capture session. */ void set_device(boost::shared_ptr<device::DevInst> dev_inst) throw(QString); void set_file(const std::string &name) throw(QString); void save_file(const std::string &name); void set_default_device(); void release_device(device::DevInst *dev_inst); capture_state get_capture_state() const; void start_capture(bool instant, boost::function<void (const QString)> error_handler); void stop_capture(); std::set< boost::shared_ptr<data::SignalData> > get_data() const; std::vector< boost::shared_ptr<view::Signal> > get_signals(); std::vector< boost::shared_ptr<view::GroupSignal> > get_group_signals(); #ifdef ENABLE_DECODE bool add_decoder(srd_decoder *const dec); std::vector< boost::shared_ptr<view::DecodeTrace> > get_decode_signals() const; void remove_decode_signal(view::DecodeTrace *signal); void remove_decode_signal(int index); void rst_decoder(int index); void rst_decoder(view::DecodeTrace *signal); #endif void init_signals(); void add_group(); void del_group(); void* get_buf(int& unit_size, uint64_t& length); void start_hotplug_proc(boost::function<void (const QString)> error_handler); void stop_hotplug_proc(); void register_hotplug_callback(); void deregister_hotplug_callback(); void set_adv_trigger(bool adv_trigger); uint16_t get_dso_ch_num(); void set_sample_rate(uint64_t sample_rate); private: void set_capture_state(capture_state state); void read_sample_rate(const sr_dev_inst *const sdi); private: /** * Attempts to autodetect the format. Failing that * @param filename The filename of the input file. * @return A pointer to the 'struct sr_input_format' that should be * used, or NULL if no input format was selected or * auto-detected. */ static sr_input_format* determine_input_file_format( const std::string &filename); static sr_input* load_input_file_format( const std::string &filename, boost::function<void (const QString)> error_handler, sr_input_format *format = NULL); void sample_thread_proc(boost::shared_ptr<device::DevInst> dev_inst, boost::function<void (const QString)> error_handler); // data feed void feed_in_header(const sr_dev_inst *sdi); void feed_in_meta(const sr_dev_inst *sdi, const sr_datafeed_meta &meta); void feed_in_trigger(const ds_trigger_pos &trigger_pos); void feed_in_logic(const sr_datafeed_logic &logic); void feed_in_dso(const sr_datafeed_dso &dso); void feed_in_analog(const sr_datafeed_analog &analog); void data_feed_in(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet); static void data_feed_in_proc(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet, void *cb_data); void hotplug_proc(boost::function<void (const QString)> error_handler); static int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, libusb_hotplug_event event, void *user_data); private: DeviceManager &_device_manager; /** * The device instance that will be used in the next capture session. */ boost::shared_ptr<device::DevInst> _dev_inst; mutable boost::mutex _sampling_mutex; capture_state _capture_state; bool _instant; mutable boost::mutex _signals_mutex; std::vector< boost::shared_ptr<view::Signal> > _signals; std::vector< boost::shared_ptr<view::GroupSignal> > _group_traces; #ifdef ENABLE_DECODE std::vector< boost::shared_ptr<view::DecodeTrace> > _decode_traces; #endif mutable boost::mutex _data_mutex; boost::shared_ptr<data::Logic> _logic_data; boost::shared_ptr<data::LogicSnapshot> _cur_logic_snapshot; boost::shared_ptr<data::Dso> _dso_data; boost::shared_ptr<data::DsoSnapshot> _cur_dso_snapshot; boost::shared_ptr<data::Analog> _analog_data; boost::shared_ptr<data::AnalogSnapshot> _cur_analog_snapshot; boost::shared_ptr<data::Group> _group_data; boost::shared_ptr<data::GroupSnapshot> _cur_group_snapshot; int _group_cnt; std::auto_ptr<boost::thread> _sampling_thread; libusb_hotplug_callback_handle _hotplug_handle; std::auto_ptr<boost::thread> _hotplug; bool _hot_attach; bool _hot_detach; bool _adv_trigger; signals: void capture_state_changed(int state); void signals_changed(); void data_updated(); void sample_rate_changed(uint64_t sample_rate); void receive_data(quint64 length); void device_attach(); void device_detach(); void test_data_error(); void receive_trigger(quint64 trigger_pos); void dso_ch_changed(uint16_t num); void frame_began(); void data_received(); void frame_ended(); void device_setted(); public slots: void reload(); private: // TODO: This should not be necessary. Multiple concurrent // sessions should should be supported and it should be // possible to associate a pointer with a ds_session. static SigSession *_session; }; } // namespace pv #endif // DSLOGIC_PV_SIGSESSION_H