X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fsigsession.cpp;h=84c75896d42d01f60ee8e0cd1ef2e04b2d28d9f4;hb=4ce6b5e7eb467a2897e1fa0e05fd572a07d2592b;hp=9ff6efe4df6e5d00d00b21a5c41d68f0f4f79acc;hpb=c3a740dd5d095eb1cdf42e00df4d5a5c480ac5b3;p=pulseview.git diff --git a/pv/sigsession.cpp b/pv/sigsession.cpp index 9ff6efe4..84c75896 100644 --- a/pv/sigsession.cpp +++ b/pv/sigsession.cpp @@ -22,20 +22,20 @@ #include #endif -#include "sigsession.h" +#include "sigsession.hpp" -#include "devicemanager.h" +#include "devicemanager.hpp" -#include "data/analog.h" -#include "data/analogsnapshot.h" -#include "data/decoderstack.h" -#include "data/logic.h" -#include "data/logicsnapshot.h" -#include "data/decode/decoder.h" +#include "data/analog.hpp" +#include "data/analogsnapshot.hpp" +#include "data/decoderstack.hpp" +#include "data/logic.hpp" +#include "data/logicsnapshot.hpp" +#include "data/decode/decoder.hpp" -#include "view/analogsignal.h" -#include "view/decodetrace.h" -#include "view/logicsignal.h" +#include "view/analogsignal.hpp" +#include "view/decodetrace.hpp" +#include "view/logicsignal.hpp" #include #include @@ -47,12 +47,16 @@ #include +using boost::shared_lock; +using boost::shared_mutex; +using boost::unique_lock; + using std::dynamic_pointer_cast; using std::function; using std::lock_guard; -using std::mutex; using std::list; using std::map; +using std::mutex; using std::set; using std::shared_ptr; using std::string; @@ -78,41 +82,41 @@ using Glib::VariantBase; using Glib::Variant; namespace pv { -SigSession::SigSession(DeviceManager &device_manager) : - _device_manager(device_manager), - _session(device_manager.context()->create_session()), - _capture_state(Stopped) +Session::Session(DeviceManager &device_manager) : + device_manager_(device_manager), + session_(device_manager.context()->create_session()), + capture_state_(Stopped) { set_default_device(); } -SigSession::~SigSession() +Session::~Session() { // Stop and join to the thread stop_capture(); } -DeviceManager& SigSession::device_manager() +DeviceManager& Session::device_manager() { - return _device_manager; + return device_manager_; } -const DeviceManager& SigSession::device_manager() const +const DeviceManager& Session::device_manager() const { - return _device_manager; + return device_manager_; } -const shared_ptr& SigSession::session() const +const shared_ptr& Session::session() const { - return _session; + return session_; } -shared_ptr SigSession::device() const +shared_ptr Session::device() const { - return _device; + return device_; } -void SigSession::set_device(shared_ptr device) +void Session::set_device(shared_ptr device) { // Ensure we are not capturing before setting the device stop_capture(); @@ -120,55 +124,66 @@ void SigSession::set_device(shared_ptr device) // Are we setting a session device? auto session_device = dynamic_pointer_cast(device); // Did we have a session device selected previously? - auto prev_session_device = dynamic_pointer_cast(_device); + auto prev_session_device = dynamic_pointer_cast(device_); - if (_device) { - _session->remove_datafeed_callbacks(); + if (device_) { + session_->remove_datafeed_callbacks(); if (!prev_session_device) { - _device->close(); - _session->remove_devices(); + device_->close(); + session_->remove_devices(); } } if (session_device) - _session = session_device->parent(); + session_ = session_device->parent(); - _device = device; - _decode_traces.clear(); + decode_traces_.clear(); if (device) { if (!session_device) { - _session = _device_manager.context()->create_session(); - device->open(); - _session->add_device(device); + session_ = device_manager_.context()->create_session(); + + try { + device->open(); + } catch(const sigrok::Error &e) { + throw QString(e.what()); + } + + session_->add_device(device); } - _session->add_datafeed_callback([=] + + device_ = device; + session_->add_datafeed_callback([=] (shared_ptr device, shared_ptr packet) { data_feed_in(device, packet); }); update_signals(device); - } + } else + device_ = nullptr; + + device_selected(); } -void SigSession::set_file(const string &name) +void Session::set_file(const string &name) { - _session = _device_manager.context()->load_session(name); - _device = _session->devices()[0]; - _decode_traces.clear(); - _session->add_datafeed_callback([=] + session_ = device_manager_.context()->load_session(name); + device_ = session_->devices()[0]; + decode_traces_.clear(); + session_->add_datafeed_callback([=] (shared_ptr device, shared_ptr packet) { data_feed_in(device, packet); }); - _device_manager.update_display_name(_device); - update_signals(_device); + device_manager_.update_display_name(device_); + update_signals(device_); + device_selected(); } -void SigSession::set_default_device() +void Session::set_default_device() { shared_ptr default_device; const list< shared_ptr > &devices = - _device_manager.devices(); + device_manager_.devices(); if (!devices.empty()) { // Fall back to the first device in the list. @@ -185,24 +200,24 @@ void SigSession::set_default_device() } } -SigSession::capture_state SigSession::get_capture_state() const +Session::capture_state Session::get_capture_state() const { - lock_guard lock(_sampling_mutex); - return _capture_state; + lock_guard lock(sampling_mutex_); + return capture_state_; } -void SigSession::start_capture(function error_handler) +void Session::start_capture(function error_handler) { stop_capture(); // Check that a device instance has been selected. - if (!_device) { + if (!device_) { qDebug() << "No device selected"; return; } // Check that at least one channel is enabled - auto channels = _device->channels(); + auto channels = device_->channels(); bool enabled = std::any_of(channels.begin(), channels.end(), [](shared_ptr channel) { return channel->enabled(); }); @@ -212,26 +227,26 @@ void SigSession::start_capture(function error_handler) } // Begin the session - _sampling_thread = std::thread( - &SigSession::sample_thread_proc, this, _device, + sampling_thread_ = std::thread( + &Session::sample_thread_proc, this, device_, error_handler); } -void SigSession::stop_capture() +void Session::stop_capture() { if (get_capture_state() != Stopped) - _session->stop(); + session_->stop(); // Check that sampling stopped - if (_sampling_thread.joinable()) - _sampling_thread.join(); + if (sampling_thread_.joinable()) + sampling_thread_.join(); } -set< shared_ptr > SigSession::get_data() const +set< shared_ptr > Session::get_data() const { - lock_guard lock(_signals_mutex); + shared_lock lock(signals_mutex_); set< shared_ptr > data; - for (const shared_ptr sig : _signals) { + for (const shared_ptr sig : signals_) { assert(sig); data.insert(sig->data()); } @@ -239,25 +254,25 @@ set< shared_ptr > SigSession::get_data() const return data; } -mutex& SigSession::signals_mutex() const +boost::shared_mutex& Session::signals_mutex() const { - return _signals_mutex; + return signals_mutex_; } -const vector< shared_ptr >& SigSession::signals() const +const vector< shared_ptr >& Session::signals() const { - return _signals; + return signals_; } #ifdef ENABLE_DECODE -bool SigSession::add_decoder(srd_decoder *const dec) +bool Session::add_decoder(srd_decoder *const dec) { map > channels; shared_ptr decoder_stack; try { - lock_guard lock(_signals_mutex); + lock_guard lock(signals_mutex_); // Create the decoder decoder_stack = shared_ptr( @@ -272,7 +287,7 @@ bool SigSession::add_decoder(srd_decoder *const dec) // Auto select the initial channels for (const srd_channel *pdch : all_channels) - for (shared_ptr s : _signals) + for (shared_ptr s : signals_) { shared_ptr l = dynamic_pointer_cast(s); @@ -290,8 +305,8 @@ bool SigSession::add_decoder(srd_decoder *const dec) // Create the decode signal shared_ptr d( new view::DecodeTrace(*this, decoder_stack, - _decode_traces.size())); - _decode_traces.push_back(d); + decode_traces_.size())); + decode_traces_.push_back(d); } catch(std::runtime_error e) { @@ -306,40 +321,40 @@ bool SigSession::add_decoder(srd_decoder *const dec) return true; } -vector< shared_ptr > SigSession::get_decode_signals() const +vector< shared_ptr > Session::get_decode_signals() const { - lock_guard lock(_signals_mutex); - return _decode_traces; + shared_lock lock(signals_mutex_); + return decode_traces_; } -void SigSession::remove_decode_signal(view::DecodeTrace *signal) +void Session::remove_decode_signal(view::DecodeTrace *signal) { - for (auto i = _decode_traces.begin(); i != _decode_traces.end(); i++) + for (auto i = decode_traces_.begin(); i != decode_traces_.end(); i++) if ((*i).get() == signal) { - _decode_traces.erase(i); + decode_traces_.erase(i); signals_changed(); return; } } #endif -void SigSession::set_capture_state(capture_state state) +void Session::set_capture_state(capture_state state) { - lock_guard lock(_sampling_mutex); - const bool changed = _capture_state != state; - _capture_state = state; + lock_guard lock(sampling_mutex_); + const bool changed = capture_state_ != state; + capture_state_ = state; if(changed) capture_state_changed(state); } -void SigSession::update_signals(shared_ptr device) +void Session::update_signals(shared_ptr device) { assert(device); - assert(_capture_state == Stopped); + assert(capture_state_ == Stopped); // Clear the decode traces - _decode_traces.clear(); + decode_traces_.clear(); // Detect what data types we will receive auto channels = device->channels(); @@ -350,21 +365,21 @@ void SigSession::update_signals(shared_ptr device) // Create data containers for the logic data snapshots { - lock_guard data_lock(_data_mutex); + lock_guard data_lock(data_mutex_); - _logic_data.reset(); + logic_data_.reset(); if (logic_channel_count != 0) { - _logic_data.reset(new data::Logic( + logic_data_.reset(new data::Logic( logic_channel_count)); - assert(_logic_data); + assert(logic_data_); } } // Make the Signals list { - lock_guard lock(_signals_mutex); + unique_lock lock(signals_mutex_); - _signals.clear(); + signals_.clear(); for (auto channel : device->channels()) { shared_ptr signal; @@ -373,7 +388,7 @@ void SigSession::update_signals(shared_ptr device) case SR_CHANNEL_LOGIC: signal = shared_ptr( new view::LogicSignal(*this, device, - channel, _logic_data)); + channel, logic_data_)); break; case SR_CHANNEL_ANALOG: @@ -392,7 +407,7 @@ void SigSession::update_signals(shared_ptr device) } assert(signal); - _signals.push_back(signal); + signals_.push_back(signal); } } @@ -400,11 +415,11 @@ void SigSession::update_signals(shared_ptr device) signals_changed(); } -shared_ptr SigSession::signal_from_channel( +shared_ptr Session::signal_from_channel( shared_ptr channel) const { - lock_guard lock(_signals_mutex); - for (shared_ptr sig : _signals) { + lock_guard lock(signals_mutex_); + for (shared_ptr sig : signals_) { assert(sig); if (sig->channel() == channel) return sig; @@ -412,10 +427,14 @@ shared_ptr SigSession::signal_from_channel( return shared_ptr(); } -void SigSession::read_sample_rate(shared_ptr device) +void Session::read_sample_rate(shared_ptr device) { - uint64_t sample_rate = VariantBase::cast_dynamic>( - device->config_get(ConfigKey::SAMPLERATE)).get(); + const auto keys = device_->config_keys(ConfigKey::DEVICE_OPTIONS); + const auto iter = keys.find(ConfigKey::SAMPLERATE); + const uint64_t sample_rate = (iter != keys.end() && + (*iter).second.find(sigrok::GET) != (*iter).second.end()) ? + VariantBase::cast_dynamic>( + device->config_get(ConfigKey::SAMPLERATE)).get() : 0; // Set the sample rate of all data const set< shared_ptr > data_set = get_data(); @@ -425,7 +444,7 @@ void SigSession::read_sample_rate(shared_ptr device) } } -void SigSession::sample_thread_proc(shared_ptr device, +void Session::sample_thread_proc(shared_ptr device, function error_handler) { assert(device); @@ -434,32 +453,32 @@ void SigSession::sample_thread_proc(shared_ptr device, read_sample_rate(device); try { - _session->start(); + session_->start(); } catch(Error e) { error_handler(e.what()); return; } - set_capture_state(_session->trigger() ? + set_capture_state(session_->trigger() ? AwaitingTrigger : Running); - _session->run(); + session_->run(); set_capture_state(Stopped); // Confirm that SR_DF_END was received - if (_cur_logic_snapshot) + if (cur_logic_snapshot_) { qDebug("SR_DF_END was not received."); assert(0); } } -void SigSession::feed_in_header(shared_ptr device) +void Session::feed_in_header(shared_ptr device) { read_sample_rate(device); } -void SigSession::feed_in_meta(shared_ptr device, +void Session::feed_in_meta(shared_ptr device, shared_ptr meta) { (void)device; @@ -478,40 +497,41 @@ void SigSession::feed_in_meta(shared_ptr device, signals_changed(); } -void SigSession::feed_in_frame_begin() +void Session::feed_in_frame_begin() { - if (_cur_logic_snapshot || !_cur_analog_snapshots.empty()) + if (cur_logic_snapshot_ || !cur_analog_snapshots_.empty()) frame_began(); } -void SigSession::feed_in_logic(shared_ptr logic) +void Session::feed_in_logic(shared_ptr logic) { - lock_guard lock(_data_mutex); + lock_guard lock(data_mutex_); - if (!_logic_data) + if (!logic_data_) { qDebug() << "Unexpected logic packet"; return; } - if (!_cur_logic_snapshot) + if (!cur_logic_snapshot_) { // This could be the first packet after a trigger set_capture_state(Running); // Get sample limit. - uint64_t sample_limit; - try { - sample_limit = VariantBase::cast_dynamic>( - _device->config_get(ConfigKey::LIMIT_SAMPLES)).get(); - } catch (Error) { - sample_limit = 0; - } + const auto keys = device_->config_keys( + ConfigKey::DEVICE_OPTIONS); + const auto iter = keys.find(ConfigKey::LIMIT_SAMPLES); + const uint64_t sample_limit = (iter != keys.end() && + (*iter).second.find(sigrok::GET) != + (*iter).second.end()) ? + VariantBase::cast_dynamic>( + device_->config_get(ConfigKey::LIMIT_SAMPLES)).get() : 0; // Create a new data snapshot - _cur_logic_snapshot = shared_ptr( + cur_logic_snapshot_ = shared_ptr( new data::LogicSnapshot(logic, sample_limit)); - _logic_data->push_snapshot(_cur_logic_snapshot); + logic_data_->push_snapshot(cur_logic_snapshot_); // @todo Putting this here means that only listeners querying // for logic will be notified. Currently the only user of @@ -522,15 +542,15 @@ void SigSession::feed_in_logic(shared_ptr logic) else { // Append to the existing data snapshot - _cur_logic_snapshot->append_payload(logic); + cur_logic_snapshot_->append_payload(logic); } data_received(); } -void SigSession::feed_in_analog(shared_ptr analog) +void Session::feed_in_analog(shared_ptr analog) { - lock_guard lock(_data_mutex); + lock_guard lock(data_mutex_); const vector> channels = analog->channels(); const unsigned int channel_count = channels.size(); @@ -544,8 +564,8 @@ void SigSession::feed_in_analog(shared_ptr analog) // Try to get the snapshot of the channel const map< shared_ptr, shared_ptr >:: - iterator iter = _cur_analog_snapshots.find(channel); - if (iter != _cur_analog_snapshots.end()) + iterator iter = cur_analog_snapshots_.find(channel); + if (iter != cur_analog_snapshots_.end()) snapshot = (*iter).second; else { @@ -558,7 +578,7 @@ void SigSession::feed_in_analog(shared_ptr analog) uint64_t sample_limit; try { sample_limit = VariantBase::cast_dynamic>( - _device->config_get(ConfigKey::LIMIT_SAMPLES)).get(); + device_->config_get(ConfigKey::LIMIT_SAMPLES)).get(); } catch (Error) { sample_limit = 0; } @@ -566,7 +586,7 @@ void SigSession::feed_in_analog(shared_ptr analog) // Create a snapshot, keep it in the maps of channels snapshot = shared_ptr( new data::AnalogSnapshot(sample_limit)); - _cur_analog_snapshots[channel] = snapshot; + cur_analog_snapshots_[channel] = snapshot; // Find the annalog data associated with the channel shared_ptr sig = @@ -596,7 +616,7 @@ void SigSession::feed_in_analog(shared_ptr analog) data_received(); } -void SigSession::data_feed_in(shared_ptr device, shared_ptr packet) +void Session::data_feed_in(shared_ptr device, shared_ptr packet) { assert(device); assert(packet); @@ -625,9 +645,9 @@ void SigSession::data_feed_in(shared_ptr device, shared_ptr pack case SR_DF_END: { { - lock_guard lock(_data_mutex); - _cur_logic_snapshot.reset(); - _cur_analog_snapshots.clear(); + lock_guard lock(data_mutex_); + cur_logic_snapshot_.reset(); + cur_analog_snapshots_.clear(); } frame_ended(); break;