2
0
forked from Ivasoft/DSView

Code refactoring 23

This commit is contained in:
dreamsourcelabTAI
2022-09-29 15:50:37 +08:00
parent 365dc84b7e
commit ceab0fd772
21 changed files with 1414 additions and 987 deletions

View File

@@ -87,7 +87,7 @@ bool AppControl::Init()
QString dir = GetDecodeScriptDir();
strcpy(path, dir.toUtf8().data());
dsv_info("decode script path: \"%s\"", dir.toUtf8().data());
dsv_info("decode script files directory: \"%s\"", dir.toUtf8().data());
// Initialise libsigrokdecode
if (srd_init(path) != SRD_OK)

View File

@@ -88,13 +88,14 @@ private:
void changeEvent(QEvent *event);
void retranslateUi();
void reStyle();
protected:
int get_protocol_index_by_id(QString id);
static QString parse_protocol_id(const char *id);
int get_output_protocol_by_id(QString id);
private:
static int decoder_name_cmp(const void *a, const void *b);
void resize_table_view(data::DecoderModel *decoder_model);
static bool protocol_sort_callback(const DecoderInfoItem *o1, const DecoderInfoItem *o2);
//IProtocolItemLayerCallback
void OnProtocolSetting(void *handle);
void OnProtocolDelete(void *handle);
@@ -104,8 +105,7 @@ private:
void BeginEditKeyword();
//ISearchItemClick
void OnItemClick(void *sender, void *data_handle);
void OnItemClick(void *sender, void *data_handle);
signals:
void protocol_updated();
@@ -128,11 +128,6 @@ private slots:
void search_changed();
void search_update();
void show_protocol_select();
private:
static int decoder_name_cmp(const void *a, const void *b);
void resize_table_view(data::DecoderModel *decoder_model);
static bool protocol_sort_callback(const DecoderInfoItem *o1, const DecoderInfoItem *o2);
private:
SigSession *_session;

View File

@@ -102,16 +102,16 @@
namespace pv
{
MainWindow::MainWindow(QWidget *parent)
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
{
_msg = NULL;
_session = AppControl::Instance()->GetSession();
_session->set_callback(this);
_device_agent = _session->get_device();
_session->add_msg_listener(this);
_is_auto_switch_device = false;
setup_ui();
@@ -231,7 +231,7 @@ namespace pv
retranslateUi();
// event
// event
connect(&_event, SIGNAL(session_error()), this, SLOT(on_session_error()));
connect(&_event, SIGNAL(signals_changed()), this, SLOT(on_signals_changed()));
connect(&_event, SIGNAL(receive_trigger(quint64)), this, SLOT(on_receive_trigger(quint64)));
@@ -278,20 +278,24 @@ namespace pv
connect(_dso_trigger_widget, SIGNAL(set_trig_pos(int)), _view, SLOT(set_trig_pos(int)));
_logo_bar->set_mainform_callback(this);
// Try load from file.
QString ldFileName(AppControl::Instance()->_open_file_name.c_str());
if (ldFileName != ""){
if (QFile::exists(ldFileName)){
if (ldFileName != "")
{
if (QFile::exists(ldFileName))
{
dsv_info("auto load file:%s", ldFileName.toUtf8().data());
on_load_file(ldFileName);
}
else{
else
{
dsv_err("file is not exists:%s", ldFileName.toUtf8().data());
MsgBox::Show(tr("Open file error!"), ldFileName, NULL);
}
}
else{
else
{
_session->set_default_device();
}
}
@@ -306,7 +310,7 @@ namespace pv
}
void MainWindow::on_load_file(QString file_name)
{
{
try
{
if (strncmp(_device_agent->name().toUtf8(), "virtual", 7))
@@ -321,15 +325,15 @@ namespace pv
}
void MainWindow::show_error(QString error)
{
{
MsgBox::Show(NULL, error.toStdString().c_str(), this);
}
void MainWindow::repeat_resume()
{
// while (_view->session().is_running_status())
// QCoreApplication::processEvents();
// _session->stop_capture();
// while (_view->session().is_running_status())
// QCoreApplication::processEvents();
// _session->stop_capture();
}
void MainWindow::session_error()
@@ -346,19 +350,20 @@ namespace pv
switch (_session->get_error())
{
case SigSession::Hw_err:
case SigSession::Hw_err:
_session->stop_capture();
title = tr("Hardware Operation Failed");
details = tr("Please replug device to refresh hardware configuration!");
break;
case SigSession::Malloc_err:
case SigSession::Malloc_err:
_session->stop_capture();
title = tr("Malloc Error");
details = tr("Memory is not enough for this sample!\nPlease reduce the sample depth!");
break;
case SigSession::Test_data_err:
case SigSession::Test_data_err:
_session->stop_capture();
_sampling_bar->update_view_status();
update_toolbar_view_status();
title = tr("Data Error");
error_pattern = _session->get_error_pattern();
@@ -379,7 +384,7 @@ namespace pv
details = tr("the content of received packet are not expected!");
_session->refresh(0);
break;
case SigSession::Data_overflow:
case SigSession::Data_overflow:
_session->stop_capture();
title = tr("Data Overflow");
details = tr("USB bandwidth can not support current sample rate! \nPlease reduce the sample rate!");
@@ -391,7 +396,7 @@ namespace pv
}
dialogs::DSMessageBox msg(this);
connect(_session->device_event_object(), SIGNAL(device_updated()), &msg, SLOT(accept()));
QFont font("Monaco");
@@ -561,6 +566,8 @@ namespace pv
bool MainWindow::on_load_session(QString name)
{
QFile sessionFile(name);
bool bDone;
if (!sessionFile.open(QIODevice::ReadOnly))
{
dsv_warn("%s", "Warning: Couldn't open session file!");
@@ -570,53 +577,60 @@ namespace pv
QString sessionData = QString::fromUtf8(sessionFile.readAll());
QJsonDocument sessionDoc = QJsonDocument::fromJson(sessionData.toUtf8());
return load_session_json(sessionDoc, false);
_protocol_widget->del_all_protocol();
return load_session_json(sessionDoc, bDone);
}
bool MainWindow::load_session_json(QJsonDocument json, bool file_dev, bool bDecoder)
bool MainWindow::load_session_json(QJsonDocument json, bool &haveDecoder)
{
haveDecoder = false;
QJsonObject sessionObj = json.object();
int mode = _device_agent->get_work_mode();
// check session file version
if (!sessionObj.contains("Version")){
if (!sessionObj.contains("Version"))
{
dsv_dbg("%s", "session file version is not exists!");
return false;
}
if (sessionObj["Version"].toInt() < BASE_SESSION_VERSION){
if (sessionObj["Version"].toInt() < BASE_SESSION_VERSION)
{
dsv_err("%s", "session file version is error!");
return false;
}
// old version(<= 1.1.2), restore the language
if (sessionObj["Version"].toInt() == BASE_SESSION_VERSION){
if (sessionObj["Version"].toInt() == BASE_SESSION_VERSION)
{
switchLanguage(sessionObj["Language"].toInt());
}
// check device and mode
if ((!file_dev && strcmp(_device_agent->driver_name().toLocal8Bit().data(), sessionObj["Device"].toString().toUtf8()) != 0) ||
mode != sessionObj["DeviceMode"].toDouble()) {
MsgBox::Show(NULL, tr("Session File is not compatible with current device or mode!"), this);
return false;
}
// clear decoders
if (mode == LOGIC && !file_dev)
if (_device_agent->is_hardware())
{
_protocol_widget->del_all_protocol();
QString driverName = _device_agent->driver_name();
QString sessionDevice = sessionObj["Device"].toString();
int sessionMode = sessionObj["DeviceMode"].toInt();
// check device and mode
if (driverName != sessionDevice || mode != sessionMode)
{
MsgBox::Show(NULL, tr("Session File is not compatible with current device or mode!"), this);
return false;
}
}
// load device settings
GVariant *gvar_opts = _device_agent->get_config_list(NULL, SR_CONF_DEVICE_SESSIONS);
gsize num_opts;
if (gvar_opts != NULL) {
if (gvar_opts != NULL)
{
const int *const options = (const int32_t *)g_variant_get_fixed_array(
gvar_opts, &num_opts, sizeof(int32_t));
for (unsigned int i = 0; i < num_opts; i++)
for (unsigned int i = 0; i < num_opts; i++)
{
const struct sr_config_info *const info = _device_agent->get_config_info(options[i]);
@@ -624,33 +638,32 @@ namespace pv
continue;
if (info->datatype == SR_T_BOOL)
_device_agent->set_config(NULL, NULL, info->key
,g_variant_new_boolean(sessionObj[info->name].toDouble()));
_device_agent->set_config(NULL, NULL, info->key, g_variant_new_boolean(sessionObj[info->name].toDouble()));
else if (info->datatype == SR_T_UINT64)
_device_agent->set_config(NULL, NULL, info->key
,g_variant_new_uint64(sessionObj[info->name].toString().toULongLong()));
_device_agent->set_config(NULL, NULL, info->key, g_variant_new_uint64(sessionObj[info->name].toString().toULongLong()));
else if (info->datatype == SR_T_UINT8)
_device_agent->set_config(NULL, NULL, info->key
,g_variant_new_byte(sessionObj[info->name].toString().toUInt()));
_device_agent->set_config(NULL, NULL, info->key, g_variant_new_byte(sessionObj[info->name].toString().toUInt()));
else if (info->datatype == SR_T_FLOAT)
_device_agent->set_config(NULL, NULL, info->key
,g_variant_new_double(sessionObj[info->name].toDouble()));
_device_agent->set_config(NULL, NULL, info->key, g_variant_new_double(sessionObj[info->name].toDouble()));
else if (info->datatype == SR_T_CHAR)
_device_agent->set_config(NULL, NULL, info->key
,g_variant_new_string(sessionObj[info->name].toString().toUtf8()));
_device_agent->set_config(NULL, NULL, info->key, g_variant_new_string(sessionObj[info->name].toString().toUtf8()));
}
}
// load channel settings
if (file_dev && mode == DSO) {
for (const GSList *l = _device_agent->get_channels(); l; l = l->next) {
sr_channel *const probe = (sr_channel*)l->data;
if (mode == DSO)
{
for (const GSList *l = _device_agent->get_channels(); l; l = l->next)
{
sr_channel *const probe = (sr_channel *)l->data;
assert(probe);
for (const QJsonValue &value : sessionObj["channel"].toArray()) {
for (const QJsonValue &value : sessionObj["channel"].toArray())
{
QJsonObject obj = value.toObject();
if ((strcmp(probe->name, g_strdup(obj["name"].toString().toStdString().c_str())) == 0) &&
(probe->type == obj["type"].toDouble())) {
(probe->type == obj["type"].toDouble()))
{
probe->vdiv = obj["vdiv"].toDouble();
probe->coupling = obj["coupling"].toDouble();
probe->vfactor = obj["vfactor"].toDouble();
@@ -663,16 +676,20 @@ namespace pv
}
}
}
else {
for (const GSList *l = _device_agent->get_channels(); l; l = l->next) {
sr_channel *const probe = (sr_channel*)l->data;
else
{
for (const GSList *l = _device_agent->get_channels(); l; l = l->next)
{
sr_channel *const probe = (sr_channel *)l->data;
assert(probe);
bool isEnabled = false;
for (const QJsonValue &value : sessionObj["channel"].toArray()) {
for (const QJsonValue &value : sessionObj["channel"].toArray())
{
QJsonObject obj = value.toObject();
if ((probe->index == obj["index"].toDouble()) &&
(probe->type == obj["type"].toDouble())) {
(probe->type == obj["type"].toDouble()))
{
isEnabled = true;
probe->enabled = obj["enabled"].toBool();
probe->name = g_strdup(obj["name"].toString().toStdString().c_str());
@@ -695,17 +712,22 @@ namespace pv
_session->reload();
// load signal setting
if (file_dev && mode == DSO) {
if (mode == DSO)
{
for(auto &s : _session->get_signals()) {
for (const QJsonValue &value : sessionObj["channel"].toArray()) {
for (auto &s : _session->get_signals())
{
for (const QJsonValue &value : sessionObj["channel"].toArray())
{
QJsonObject obj = value.toObject();
if ((strcmp(s->get_name().toStdString().c_str(), g_strdup(obj["name"].toString().toStdString().c_str())) == 0) &&
(s->get_type() == obj["type"].toDouble())) {
(s->get_type() == obj["type"].toDouble()))
{
s->set_colour(QColor(obj["colour"].toString()));
view::DsoSignal *dsoSig = NULL;
if ((dsoSig = dynamic_cast<view::DsoSignal*>(s))) {
if ((dsoSig = dynamic_cast<view::DsoSignal *>(s)))
{
dsoSig->load_settings();
dsoSig->set_zero_ratio(obj["zeroPos"].toDouble());
dsoSig->set_trig_ratio(obj["trigValue"].toDouble());
@@ -715,23 +737,29 @@ namespace pv
}
}
}
}
else {
for(auto &s : _session->get_signals()) {
for (const QJsonValue &value : sessionObj["channel"].toArray()) {
}
else
{
for (auto &s : _session->get_signals())
{
for (const QJsonValue &value : sessionObj["channel"].toArray())
{
QJsonObject obj = value.toObject();
if ((s->get_index() == obj["index"].toDouble()) &&
(s->get_type() == obj["type"].toDouble())) {
(s->get_type() == obj["type"].toDouble()))
{
s->set_colour(QColor(obj["colour"].toString()));
s->set_name(g_strdup(obj["name"].toString().toUtf8().data()));
view::LogicSignal *logicSig = NULL;
if ((logicSig = dynamic_cast<view::LogicSignal*>(s))) {
if ((logicSig = dynamic_cast<view::LogicSignal *>(s)))
{
logicSig->set_trig(obj["strigger"].toDouble());
}
view::DsoSignal *dsoSig = NULL;
if ((dsoSig = dynamic_cast<view::DsoSignal*>(s))) {
if ((dsoSig = dynamic_cast<view::DsoSignal *>(s)))
{
dsoSig->load_settings();
dsoSig->set_zero_ratio(obj["zeroPos"].toDouble());
dsoSig->set_trig_ratio(obj["trigValue"].toDouble());
@@ -739,7 +767,8 @@ namespace pv
}
view::AnalogSignal *analogSig = NULL;
if ((analogSig = dynamic_cast<view::AnalogSignal*>(s))) {
if ((analogSig = dynamic_cast<view::AnalogSignal *>(s)))
{
analogSig->set_zero_ratio(obj["zeroPos"].toDouble());
analogSig->commit_settings();
}
@@ -756,20 +785,27 @@ namespace pv
_view->header_updated();
// load trigger settings
if (sessionObj.contains("trigger")) {
if (sessionObj.contains("trigger"))
{
_trigger_widget->set_session(sessionObj["trigger"].toObject());
}
on_trigger(false);
// load decoders
if (bDecoder && sessionObj.contains("decoder")) {
StoreSession ss(_session);
ss.load_decoders(_protocol_widget, sessionObj["decoder"].toArray());
if (sessionObj.contains("decoder"))
{
QJsonArray deArray = sessionObj["decoder"].toArray();
if (deArray.empty() == false)
{
haveDecoder = true;
StoreSession ss(_session);
ss.load_decoders(_protocol_widget, deArray);
}
}
// load measure
if (sessionObj.contains("measure")) {
if (sessionObj.contains("measure"))
{
_view->get_viewstatus()->load_session(sessionObj["measure"].toArray());
}
@@ -1171,7 +1207,6 @@ namespace pv
}
/*------------------on event end-------*/
void MainWindow::signals_changed()
{
@@ -1259,24 +1294,27 @@ namespace pv
void MainWindow::check_usb_device_speed()
{
// USB device speed check
if (_device_agent->is_hardware()) {
// USB device speed check
if (_device_agent->is_hardware())
{
int usb_speed = LIBUSB_SPEED_HIGH;
GVariant *gvar = _device_agent->get_config(NULL, NULL, SR_CONF_USB_SPEED);
if (gvar != NULL) {
if (gvar != NULL)
{
usb_speed = g_variant_get_int32(gvar);
g_variant_unref(gvar);
}
bool usb30_support = false;
gvar = _device_agent->get_config(NULL, NULL, SR_CONF_USB30_SUPPORT);
if (gvar != NULL) {
if (gvar != NULL)
{
usb30_support = g_variant_get_boolean(gvar);
g_variant_unref(gvar);
if (usb30_support && usb_speed == LIBUSB_SPEED_HIGH)
show_error(tr("Plug it into a USB 2.0 port will seriously affect its performance."
"Please replug it into a USB 3.0 port."));
"Please replug it into a USB 3.0 port."));
}
}
}
@@ -1292,40 +1330,45 @@ namespace pv
}
void MainWindow::reset_all_view()
{
{
_sampling_bar->reload();
_view->status_clear();
_view->reload();
_view->set_device();
_trigger_widget->init();
_trigger_widget->init();
_trigger_widget->device_updated();
_trig_bar->reload();
_trig_bar->restore_status();
_trig_bar->restore_status();
_dso_trigger_widget->init();
_measure_widget->reload();
}
bool MainWindow::confirm_to_store_data()
{
if (_session->have_hardware_data()){
return MsgBox::Confirm(tr("Save captured data?"));
}
if (_session->have_hardware_data())
{
return MsgBox::Confirm(tr("Save captured data?"));
}
return false;
}
void MainWindow::check_session_file_version()
{
auto device_agent = _session->get_device();
if (device_agent->is_file() && device_agent->is_new_device()){
if (device_agent->get_work_mode() == LOGIC){
GVariant* gvar = device_agent->get_config(NULL, NULL, SR_CONF_FILE_VERSION);
if (gvar != NULL) {
if (device_agent->is_file() && device_agent->is_new_device())
{
if (device_agent->get_work_mode() == LOGIC)
{
GVariant *gvar = device_agent->get_config(NULL, NULL, SR_CONF_FILE_VERSION);
if (gvar != NULL)
{
int16_t version = g_variant_get_int16(gvar);
g_variant_unref(gvar);
if (version == 1) {
if (version == 1)
{
show_error(tr("Current loading file has an old format. "
"This will lead to a slow loading speed. "
"Please resave it after loaded."));
"This will lead to a slow loading speed. "
"Please resave it after loaded."));
}
}
}
@@ -1334,43 +1377,43 @@ namespace pv
void MainWindow::load_device_config()
{
int lang = AppConfig::Instance()._frameOptions.language;
QString name = _device_agent->name();
int mode = _device_agent->get_work_mode();
int lang = AppConfig::Instance()._frameOptions.language;
QString name = _device_agent->name();
int mode = _device_agent->get_work_mode();
if (_device_agent->is_hardware())
{
if (_device_agent->is_hardware())
{
#if QT_VERSION >= 0x050400
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
#else
QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
#endif
if (dir.exists())
{
QString str = dir.absolutePath() + "/";
QString lang_name = ".ses" + QString::number(lang);
QString ses_name = str +
name +
QString::number(mode) +
lang_name + ".dsc";
on_load_session(ses_name);
}
}
else
{
QDir dir(GetResourceDir());
if (dir.exists())
{
QString str = dir.absolutePath() + "/";
QString ses_name = str +
name +
QString::number(mode) +
".dsc";
if (QFileInfo(ses_name).exists())
on_load_session(ses_name);
}
}
if (dir.exists())
{
QString str = dir.absolutePath() + "/";
QString lang_name = ".ses" + QString::number(lang);
QString ses_name = str +
name +
QString::number(mode) +
lang_name + ".dsc";
on_load_session(ses_name);
}
}
else
{
QDir dir(GetResourceDir());
if (dir.exists())
{
QString str = dir.absolutePath() + "/";
QString ses_name = str +
name +
QString::number(mode) +
".dsc";
if (QFileInfo(ses_name).exists())
on_load_session(ses_name);
}
}
}
QJsonDocument MainWindow::get_session_json_from_file(QString file)
@@ -1378,6 +1421,11 @@ namespace pv
QJsonDocument sessionDoc;
QJsonParseError error;
if (file == ""){
dsv_err("%s", "File name is empty.");
assert(false);
}
auto f_name = path::ConvertPath(file);
ZipReader rd(f_name.c_str());
auto *data = rd.GetInnterFileData("session");
@@ -1406,6 +1454,11 @@ namespace pv
QJsonArray dec_array;
QJsonParseError error;
if (file == ""){
dsv_err("%s", "File name is empty.");
assert(false);
}
/* read "decoders" */
auto f_name = path::ConvertPath(file);
ZipReader rd(f_name.c_str());
@@ -1431,12 +1484,19 @@ namespace pv
return dec_array;
}
void MainWindow::update_toolbar_view_status()
{
_sampling_bar->update_view_status();
_file_bar->update_view_status();
_trig_bar->update_view_status();
}
void MainWindow::OnMessage(int msg)
{
switch (msg)
{
case DSV_MSG_DEVICE_LIST_UPDATED:
_sampling_bar->update_device_list();
case DSV_MSG_DEVICE_LIST_UPDATED:
_sampling_bar->update_device_list();
break;
case DSV_MSG_START_COLLECT_WORK_PREV:
@@ -1445,16 +1505,12 @@ namespace pv
break;
case DSV_MSG_START_COLLECT_WORK:
_sampling_bar->update_view_status();
_file_bar->update_view_status();
_trig_bar->update_view_status();
update_toolbar_view_status();
break;
case DSV_MSG_END_COLLECT_WORK:
_session->device_event_object()->device_updated();
_sampling_bar->update_view_status();
_file_bar->update_view_status();
_trig_bar->update_view_status();
update_toolbar_view_status();
break;
case DSV_MSG_CURRENT_DEVICE_CHANGE_PREV:
@@ -1463,31 +1519,38 @@ namespace pv
break;
case DSV_MSG_CURRENT_DEVICE_CHANGED:
{
if (_msg != NULL){
{
if (_msg != NULL)
{
_msg->close();
_msg = NULL;
}
load_device_config();
_protocol_widget->del_all_protocol();
load_device_config();
_sampling_bar->update_device_list();
reset_all_view();
reset_all_view();
_logo_bar->dsl_connected(_session->get_device()->is_hardware());
_file_bar->update_view_status();
if (_device_agent->is_file()){
check_session_file_version();
StoreSession ss(_session);
// load decoder
bool bFlag = ss.load_decoders(_protocol_widget
,get_decoder_json_from_file(_device_agent->path()));
update_toolbar_view_status();
if (_device_agent->is_file())
{
check_session_file_version();
bool bDoneDecoder = false;
// load session
load_session_json(get_session_json_from_file(_device_agent->path()), true, !bFlag);
load_session_json(get_session_json_from_file(_device_agent->path()), bDoneDecoder);
if (!bDoneDecoder)
{
StoreSession ss(_session);
QJsonArray deArray = get_decoder_json_from_file(_device_agent->path());
ss.load_decoders(_protocol_widget, deArray);
}
_session->start_capture(true);
}
}
break;
}
}
break;
case DSV_MSG_DEVICE_OPTIONS_UPDATED:
_trigger_widget->device_updated();
@@ -1502,52 +1565,59 @@ namespace pv
case DSV_MSG_DEVICE_MODE_CHANGED:
_sampling_bar->update_sample_rate_selector();
_sampling_bar->update_view_status();
_view->mode_changed();
reset_all_view();
update_toolbar_view_status();
break;
case DSV_MSG_NEW_USB_DEVICE:
if (confirm_to_store_data()){
if (confirm_to_store_data())
{
_is_auto_switch_device = true;
on_save();
}
else{
else
{
_session->set_default_device();
check_usb_device_speed();
}
check_usb_device_speed();
}
break;
case DSV_MSG_CURRENT_DEVICE_DETACHED:
// Save current config, and switch to the last device.
_session->device_event_object()->device_updated();
session_save();
session_save();
_view->hide_calibration();
if (confirm_to_store_data()){
if (confirm_to_store_data())
{
_is_auto_switch_device = true;
on_save();
}
else{
else
{
_session->set_default_device();
}
}
break;
case DSV_MSG_SAVE_COMPLETE:
if (_is_auto_switch_device){
if (_is_auto_switch_device)
{
_is_auto_switch_device = false;
_session->set_default_device();
if (_session->get_device()->is_new_device())
check_usb_device_speed();
}
else{
else
{
ds_device_handle devh = _sampling_bar->get_next_device_handle();
if (devh != NULL_HANDLE){
if (devh != NULL_HANDLE)
{
dsv_info("%s", "Auto switch to the selected device.");
_session->set_device(devh);
}
}
}
break;
}
}
}
} // namespace pv

View File

@@ -94,7 +94,7 @@ private:
void setup_ui();
void retranslateUi();
bool eventFilter(QObject *object, QEvent *event);
bool load_session_json(QJsonDocument json, bool file_dev,bool bDecoder=true);
bool load_session_json(QJsonDocument json, bool &haveDecoder);
public slots:
void switchTheme(QString style);
@@ -143,6 +143,7 @@ private:
void check_usb_device_speed();
void reset_all_view();
bool confirm_to_store_data();
void update_toolbar_view_status();
private:
//ISessionCallback

View File

@@ -81,10 +81,10 @@ namespace pv
_is_working = false;
_is_repeat_mode = false;
_is_saving = false;
_device_status = ST_INIT;
_device_status = ST_INIT;
_noData_cnt = 0;
_data_lock = false;
_data_updated = false;
_data_updated = false;
this->add_msg_listener(this);
@@ -187,15 +187,13 @@ namespace pv
{
assert(!_is_saving);
assert(!_is_working);
assert(_callback);
_callback->trigger_message(DSV_MSG_CURRENT_DEVICE_CHANGE_PREV);
// Release the old device.
_device_agent.release();
if (_callback != NULL)
{
_callback->trigger_message(DSV_MSG_CURRENT_DEVICE_CHANGE_PREV);
}
if (ds_active_device(dev_handle) != SR_OK)
{
dsv_err("%s", "Switch device error!");
@@ -203,18 +201,19 @@ namespace pv
}
_device_agent.update();
_device_status = ST_INIT;
init_signals();
RELEASE_ARRAY(_group_traces);
clear_all_decoder();
if (_device_agent.is_file())
dsv_info("%s\"%s\"", "Switch to file: ", _device_agent.name().toUtf8().data());
else
dsv_info("%s\"%s\"", "Switch to device: ", _device_agent.name().toUtf8().data());
_device_status = ST_INIT;
RELEASE_ARRAY(_group_traces);
clear_all_decoder();
init_signals();
_cur_snap_samplerate = _device_agent.get_sample_rate();
_cur_samplelimits = _device_agent.get_sample_limit();
@@ -480,7 +479,7 @@ namespace pv
return false;
}
// stop all decode tasks
// Clear the previous decoder tasks.
int run_dex = 0;
clear_all_decode_task(run_dex);
@@ -516,12 +515,15 @@ namespace pv
dsv_info("%s", "Stop collect.");
if (!_is_working)
return;
if (_bClose)
{
_is_working = false;
exit_capture();
return;
}
//_feed_timer
bool wait_upload = false;
if (!_is_repeat_mode)
{
@@ -532,6 +534,7 @@ namespace pv
g_variant_unref(gvar);
}
}
if (!wait_upload)
{
_is_working = false;
@@ -548,12 +551,11 @@ namespace pv
{
_is_instant = false;
_feed_timer.Stop();
//_feed_timer
_feed_timer.Stop();
if (_device_agent.is_collecting())
{
_device_agent.stop();
}
}
bool SigSession::get_capture_status(bool &triggered, int &progress)
@@ -612,7 +614,7 @@ namespace pv
return;
if (_data_updated)
{
{
data_updated();
_data_updated = false;
_noData_cnt = 0;
@@ -722,13 +724,9 @@ namespace pv
_analog_data->clear();
_group_data->clear();
// Clear the decode traces
clear_all_decoder();
// Detect what data types we will receive
if (_device_agent.have_instance())
{
for (const GSList *l = _device_agent.get_channels(); l; l = l->next)
{
const sr_channel *const probe = (const sr_channel *)l->data;
@@ -1173,8 +1171,6 @@ namespace pv
ds_lock_guard lock(_data_mutex);
// dsv_info("%s", "Receive data.");
if (_data_lock && packet->type != SR_DF_END)
return;
@@ -1767,7 +1763,11 @@ namespace pv
return;
_bClose = true;
exit_capture();
// Stop decode thread.
clear_all_decoder(false);
stop_capture();
// TODO: This should not be necessary
_session = NULL;
@@ -1810,6 +1810,9 @@ namespace pv
void SigSession::clear_all_decoder(bool bUpdateView)
{
if (_decode_traces.empty())
return;
// create the wait task deque
int dex = -1;
clear_all_decode_task(dex);
@@ -1830,28 +1833,23 @@ namespace pv
}
_decode_traces.clear();
// wait thread end
if (_decode_thread.joinable())
{
_decode_thread.join();
}
if (!is_closed() && bUpdateView)
{
if (!_bClose && bUpdateView)
signals_changed();
}
}
void SigSession::clear_all_decode_task(int &runningDex)
{
std::lock_guard<std::mutex> lock(_decode_task_mutex);
// remove wait task
for (auto trace : _decode_tasks)
if (true)
{
trace->decoder()->stop_decode_work(); // set decode proc stop flag
std::lock_guard<std::mutex> lock(_decode_task_mutex);
// remove wait task
for (auto trace : _decode_tasks)
{
trace->decoder()->stop_decode_work(); // set decode proc stop flag
}
_decode_tasks.clear();
}
_decode_tasks.clear();
// make sure the running task can stop
runningDex = -1;
@@ -1865,6 +1863,10 @@ namespace pv
}
dex++;
}
// Wait the thread end.
if (_decode_thread.joinable())
_decode_thread.join();
}
view::DecodeTrace *SigSession::get_decoder_trace(int index)
@@ -1962,9 +1964,7 @@ namespace pv
case DS_EV_DEVICE_STOPPED:
_device_status = ST_STOPPED;
// Confirm that SR_DF_END was received
if (!_logic_data->snapshot()->last_ended()
|| !_dso_data->snapshot()->last_ended()
|| !_analog_data->snapshot()->last_ended())
if (!_logic_data->snapshot()->last_ended() || !_dso_data->snapshot()->last_ended() || !_analog_data->snapshot()->last_ended())
{
dsv_err("%s", "Error!The data is not completed.");
assert(false);
@@ -2011,7 +2011,7 @@ namespace pv
if (DS_EV_NEW_DEVICE_ATTACH == event)
_callback->trigger_message(DSV_MSG_NEW_USB_DEVICE);
else
_callback->trigger_message(DSV_MSG_CURRENT_DEVICE_DETACHED);
_callback->trigger_message(DSV_MSG_CURRENT_DEVICE_DETACHED);
}
break;
@@ -2073,7 +2073,7 @@ namespace pv
void SigSession::DeviceConfigChanged()
{
//Nonthing.
// Nonthing.
}
bool SigSession::switch_work_mode(int mode)
@@ -2081,18 +2081,17 @@ namespace pv
assert(!_is_working);
if (_device_agent.get_work_mode() != mode)
{
{
GVariant *val = g_variant_new_int16(mode);
_device_agent.set_config(NULL
,NULL
,SR_CONF_DEVICE_MODE
,val);
_device_agent.set_config(NULL, NULL, SR_CONF_DEVICE_MODE, val);
clear_all_decoder();
init_signals();
dsv_info("%s", "Work mode is changed.");
broadcast_msg(DSV_MSG_DEVICE_MODE_CHANGED);
return true;
}
return false;
}
return false;
}
} // namespace pv

View File

@@ -314,7 +314,7 @@ private:
void add_decode_task(view::DecodeTrace *trace);
void remove_decode_task(view::DecodeTrace *trace);
void clear_all_decode_task(int &runningDex);
void clear_all_decode_task(int &runningDex);
view::DecodeTrace* get_decoder_trace(int index);
void decode_task_proc();

View File

@@ -970,7 +970,7 @@ bool StoreSession::json_decoders(QJsonArray &array)
return true;
}
bool StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array)
bool StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray &dec_array)
{
if (_session->get_device()->get_work_mode() != LOGIC)
{
@@ -978,8 +978,8 @@ bool StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra
return false;
}
if (dec_array.empty()){
dsv_info("%s", "StoreSession::load_decoders(), json object is array empty.");
if (dec_array.isEmpty()){
dsv_info("%s", "StoreSession::load_decoders(), json object array is empty.");
return false;
}

View File

@@ -80,7 +80,7 @@ private:
public:
bool json_decoders(QJsonArray &array);
bool load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array);
bool load_decoders(dock::ProtocolDock *widget, QJsonArray &dec_array);
QString MakeSaveFile(bool bDlg);
QString MakeExportFile(bool bDlg);

View File

@@ -176,7 +176,7 @@ namespace pv
bool is_working = _session->is_working();
if (_session->is_instant())
if (_is_run_as_instant)
{
if (bDev && mode == DSO)
_instant_button.setText(is_working ? tr("Stop") : tr("Single"));
@@ -1128,6 +1128,7 @@ namespace pv
void SamplingBar::update_view_status()
{
int bEnable = _session->is_working() == false;
int mode = _session->get_device()->get_work_mode();
_device_type.setEnabled(bEnable);
_configure_button.setEnabled(bEnable);
@@ -1137,16 +1138,20 @@ namespace pv
_mode_button.setEnabled(bEnable);
_configure_button.setEnabled(bEnable);
_device_selector.setEnabled(bEnable);
_sample_count.setEnabled(bEnable);
if (_session->get_device()->get_work_mode() == DSO){
if (_session->get_device()->is_file()){
_sample_rate.setEnabled(false);
_sample_count.setEnabled(false);
}
else if (mode == DSO){
_sample_rate.setEnabled(false);
_sample_count.setEnabled(bEnable);
}
else{
_sample_rate.setEnabled(bEnable);
_sample_count.setEnabled(bEnable);
}
if (_session->is_working()){
_run_stop_button.setEnabled(_is_run_as_instant ? false : true);
_instant_button.setEnabled(_is_run_as_instant ? true : false);

View File

@@ -42,8 +42,7 @@
*/
/** @private */
SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type,
gboolean enabled, const char *name)
SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type, gboolean enabled, const char *name)
{
struct sr_channel *probe;
@@ -52,6 +51,11 @@ SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type,
return NULL;
}
probe->trigger = NULL;
probe->name = NULL;
probe->map_unit = NULL;
probe->vga_ptr = NULL;
probe->index = index;
probe->type = type;
probe->enabled = enabled;
@@ -167,8 +171,8 @@ SR_PRIV int sr_dev_trigger_set(const struct sr_dev_inst *sdi, uint16_t probenum,
probe = l->data;
if (probe->index == probenum) {
/* If the probe already has a trigger, kill it first. */
g_free(probe->trigger);
probe->trigger = g_strdup(trigger);
g_safe_free(probe->trigger);
probe->trigger = g_strdup(trigger);
ret = SR_OK;
break;
}
@@ -178,7 +182,7 @@ SR_PRIV int sr_dev_trigger_set(const struct sr_dev_inst *sdi, uint16_t probenum,
}
/** @private */
SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status,
SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int status,
const char *vendor, const char *model, const char *version)
{
struct sr_dev_inst *sdi;
@@ -189,17 +193,26 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status,
}
sdi->driver = NULL;
sdi->mode = mode;
sdi->name[0] = '\0';
sdi->status = status;
sdi->vendor = vendor ? g_strdup(vendor) : NULL;
sdi->version = version ? g_strdup(version) : NULL;
sdi->channels = NULL;
sdi->conn = NULL;
sdi->priv = NULL;
sdi->vendor = NULL;
sdi->version = NULL;
sdi->path = NULL;
sdi->mode = mode;
sdi->name[0] = '\0';
sdi->status = status;
sdi->handle = (ds_device_handle)sdi;
sdi->dev_type = DEV_TYPE_UNKOWN;
if (vendor != NULL){
sdi->vendor = g_strdup(vendor);
}
if (version != NULL){
sdi->version = g_strdup(version);
}
if (model && *model){
strncpy(sdi->name, model, sizeof(sdi->name));
}
@@ -215,30 +228,27 @@ SR_PRIV void sr_dev_probes_free(struct sr_dev_inst *sdi)
for (l = sdi->channels; l; l = l->next) {
probe = l->data;
g_free(probe->name);
g_free(probe->trigger);
if (probe->vga_ptr)
g_free(probe->vga_ptr);
g_safe_free(probe->name);
g_safe_free(probe->trigger);
g_safe_free(probe->vga_ptr);
g_free(probe);
}
sdi->channels = NULL;
g_safe_free_list(sdi->channels);
}
SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi)
{
struct sr_channel *probe;
GSList *l;
if (sdi == NULL)
return;
for (l = sdi->channels; l; l = l->next) {
probe = l->data;
g_free(probe->name);
g_free(probe);
}
sr_dev_probes_free(sdi);
g_safe_free(sdi->conn);
g_safe_free(sdi->priv);
g_safe_free(sdi->vendor);
g_safe_free(sdi->version);
g_safe_free(sdi->path);
g_free(sdi->priv);
g_free(sdi->vendor);
g_free(sdi->version);
g_free(sdi);
}

View File

@@ -287,7 +287,7 @@ static GSList *scan(GSList *options)
if (!devc)
return NULL;
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, 0, SR_ST_INITIALIZING,
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, SR_ST_INITIALIZING,
prof->vendor, prof->model, prof->model_version);
if (!sdi) {
@@ -1046,7 +1046,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
{
unsigned int i;
int ret;
struct DSL_context *devc = sdi->priv;
struct DSL_context *devc;
assert(sdi);
assert(sdi->priv);
devc = sdi->priv;
ret = dsl_config_get(id, data, sdi, ch, cg);
if (ret != SR_OK) {
@@ -1202,6 +1207,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
unsigned int i;
GSList *l;
assert(sdi);
assert(sdi->priv);
(void)cg;
if (sdi->status != SR_ST_ACTIVE) {

View File

@@ -357,7 +357,7 @@ static GSList *scan(GSList *options)
if (!devc)
return NULL;
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, -1, SR_ST_INITIALIZING,
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, SR_ST_INITIALIZING,
prof->vendor, prof->model, prof->model_version);
if (!sdi) {
g_free(devc);
@@ -606,6 +606,9 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
struct DSL_context *devc = sdi->priv;
int ret;
assert(sdi);
assert(sdi->priv);
ret = dsl_config_get(id, data, sdi, ch, cg);
if (ret != SR_OK) {
switch (id) {
@@ -722,6 +725,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
struct sr_usb_dev_inst *usb;
unsigned int i;
assert(sdi);
assert(sdi->priv);
(void)cg;
if (sdi->status != SR_ST_ACTIVE) {

View File

@@ -154,7 +154,7 @@ static GSList *hw_scan(GSList *options)
devc->max_height = 0;
adjust_samplerate(devc);
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, 0, SR_ST_INITIALIZING,
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, SR_ST_INITIALIZING,
devc->profile->vendor,
devc->profile->model,
devc->profile->model_version);
@@ -257,7 +257,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
{
(void) cg;
struct demo_context *const devc = sdi->priv;
struct demo_context *devc;
assert(sdi);
assert(sdi->priv);
devc = sdi->priv;
switch (id) {
case SR_CONF_SAMPLERATE:
@@ -375,14 +380,18 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
struct sr_channel *ch,
struct sr_channel_group *cg)
{
(void) cg;
uint16_t i;
int ret, num_probes;
const char *stropt;
uint64_t tmp_u64;
struct demo_context *devc;
(void) cg;
struct demo_context *const devc = sdi->priv;
assert(sdi);
assert(sdi->priv);
devc = sdi->priv;
if (sdi->status != SR_ST_ACTIVE)
return SR_ERR_DEV_CLOSED;

View File

@@ -80,7 +80,7 @@ static int init(struct sr_input *in, const char *filename)
}
/* Create a virtual device. */
in->sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, NULL, NULL, NULL);
in->sdi = sr_dev_inst_new(LOGIC, SR_ST_ACTIVE, NULL, NULL, NULL);
in->internal = ctx;
for (i = 0; i < num_probes; i++) {

View File

@@ -369,7 +369,7 @@ static int init(struct sr_input *in, const char *filename)
ctx->maxprobes = num_probes;
/* Create a virtual device. */
in->sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, NULL, NULL, NULL);
in->sdi = sr_dev_inst_new(LOGIC, SR_ST_ACTIVE, NULL, NULL, NULL);
in->internal = ctx;
for (i = 0; i < num_probes; i++) {

View File

@@ -99,7 +99,7 @@ static int init(struct sr_input *in, const char *filename)
return SR_ERR_MALLOC;
/* Create a virtual device. */
in->sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, NULL, NULL, NULL);
in->sdi = sr_dev_inst_new(LOGIC, SR_ST_ACTIVE, NULL, NULL, NULL);
in->sdi->priv = ctx;
ctx->samplerate = GUINT32_FROM_LE(*(uint32_t *)(buf + 24));

View File

@@ -344,8 +344,7 @@ SR_API int ds_active_device(ds_device_handle handle)
{
bFind = 1;
if (dev->dev_type == DEV_TYPE_USB && DS_RES_PATH[0] == '\0')
{
if (dev->dev_type == DEV_TYPE_USB && DS_RES_PATH[0] == '\0'){
sr_err("%s", "Please call ds_set_firmware_resource_dir() to set the firmware resource path.");
}
@@ -463,10 +462,29 @@ SR_API int ds_have_actived_device()
}
/**
* Create a device from session file, and will auto load the data.
* Create a device from session file, and append to the list.
*/
SR_API int ds_device_from_file(const char *file_path)
{
{
struct sr_dev_inst *dev;
int ret;
if (file_path == NULL || *file_path == '\0'){
sr_err("%s", "Error!File name is empty.");
return SR_ERR_ARG;
}
dev = NULL;
ret = sr_new_virtual_device(file_path, &dev);
if (ret != SR_OK){
return ret;
}
pthread_mutex_lock(&lib_ctx.mutext);
lib_ctx.device_list = g_slist_append(lib_ctx.device_list, dev);
pthread_mutex_unlock(&lib_ctx.mutext);
return SR_OK;
}
@@ -556,7 +574,8 @@ SR_API int ds_get_actived_device_info(struct ds_device_full_info *fill_info)
{
struct sr_dev_inst *dev;
struct ds_device_full_info *p;
int ret;
int ret;
if (fill_info == NULL)
return SR_ERR_ARG;
@@ -586,6 +605,10 @@ SR_API int ds_get_actived_device_info(struct ds_device_full_info *fill_info)
{
strncpy(p->driver_name, dev->driver->name, sizeof(p->driver_name) - 1);
}
if (dev->dev_type == DEV_TYPE_FILELOG && dev->path != NULL){
strncpy(p->path, dev->path, sizeof(p->path) - 1);
}
ret = SR_OK;
}
@@ -713,7 +736,7 @@ END:
if (bError)
send_event(DS_EV_COLLECT_TASK_END_BY_ERROR);
else if (lib_ctx.is_stop_by_detached)
send_event(DS_EV_COLLECT_TASK_END_BY_DETACHED);
post_event_async(DS_EV_COLLECT_TASK_END_BY_DETACHED);
else
send_event(DS_EV_COLLECT_TASK_END); // Normal end.
@@ -1094,6 +1117,9 @@ static int update_device_handle(struct libusb_device *old_dev, struct libusb_dev
return SR_ERR;
}
/**
* hotplug event
*/
static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event)
{
int bDone = 0;
@@ -1155,7 +1181,7 @@ static void hotplug_event_listen_callback(struct libusb_context *ctx, struct lib
&& lib_ctx.actived_device_instance->handle == (ds_device_handle)dev
&& ds_is_collecting())
{
sr_info("%s", "The actived device is detached, will stop collect thread.");
sr_info("%s", "The collecting device is detached, will stop the collect thread.");
lib_ctx.is_stop_by_detached = 1;
ds_release_actived_device();
}
@@ -1435,4 +1461,4 @@ static void send_event(int event)
}
}
/**-------------------private function end---------------*/
/**-------------------private function end---------------*/

View File

@@ -123,29 +123,39 @@ struct sr_dev_driver {
struct sr_dev_inst {
/** Device driver. */
struct sr_dev_driver *driver;
/**Identity. */
ds_device_handle handle;
/** device name. */
char name[50];
char *path;
/** Device type:(demo,filelog,hardware). The type see enum sr_device_type. */
int dev_type;
/** Index of device in driver. */
int index;
/** Device instance status. SR_ST_NOT_FOUND, etc. */
int status;
/** Device mode. LA/DAQ/OSC, etc. */
int mode;
/** Device vendor. */
char *vendor;
/** Device version. */
char *version;
/** List of channels. */
GSList *channels;
/** List of sr_channel_group structs */
GSList *channel_groups;
/** Device instance connection data (used?) */
void *conn;
/** Device instance private data (used?) */
void *priv;
};
@@ -221,8 +231,8 @@ struct ds_trigger {
/*--- device.c --------------------------------------------------------------*/
SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type,
gboolean enabled, const char *name);
SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type, gboolean enabled, const char *name);
SR_PRIV void sr_dev_probes_free(struct sr_dev_inst *sdi);
SR_PRIV int sr_enable_device_channel(struct sr_dev_inst *sdi, const struct sr_channel *probe, gboolean enable);
@@ -237,7 +247,7 @@ SR_PRIV int sr_dev_trigger_set(const struct sr_dev_inst *sdi, uint16_t probenum,
const char *trigger);
/* Generic device instances */
SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status,
SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int status,
const char *vendor, const char *model, const char *version);
SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi);
@@ -366,8 +376,12 @@ SR_PRIV int sr_session_run(void);
SR_PRIV int sr_session_stop(void);
SR_PRIV struct sr_session *sr_session_new(void);
SR_PRIV int sr_session_destroy(void);
/* Session setup */
SR_PRIV int sr_session_load(const char *filename);
/**
* Create a virtual deivce from file.
*/
SR_PRIV int sr_new_virtual_device(const char *filename, struct sr_dev_inst **out_di);
/*--- lib_main.c -------------------------------------------------*/
/**

View File

@@ -1008,12 +1008,6 @@ enum sr_config_option_id{
/** Sessions */
SR_CONF_DEVICE_SESSIONS = 30099,
/** Session filename. */
SR_CONF_SESSIONFILE = 30100,
/** The device supports specifying a capturefile to inject. */
SR_CONF_CAPTUREFILE = 30101,
/** Session file version */
SR_CONF_FILE_VERSION = 30102,
@@ -1375,7 +1369,7 @@ SR_API int ds_get_actived_device_index();
SR_API int ds_have_actived_device();
/**
* Create a device from session file, and will auto load the data.
* Create a device from session file, and append to the list.
*/
SR_API int ds_device_from_file(const char *file_path);
@@ -1418,7 +1412,7 @@ SR_API int ds_stop_collect();
SR_API int ds_is_collecting();
/**
* Close the actived device.
* Close the actived device, and stop collect.
*/
SR_API int ds_release_actived_device();

File diff suppressed because it is too large Load Diff

View File

@@ -1,448 +0,0 @@
/*
* This file is part of the libsigrok project.
*
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "libsigrok-internal.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <minizip/unzip.h>
#include "config.h" /* Needed for PACKAGE_VERSION and others. */
#include "log.h"
#undef LOG_PREFIX
#define LOG_PREFIX "session-file: "
/**
* @file
*
* Loading and saving libsigrok session files.
*/
/**
* @addtogroup grp_session
*
* @{
*/
extern struct sr_session *session;
extern SR_PRIV struct sr_dev_driver session_driver;
/**
* Load the session from the specified filename.
*
* @param filename The name of the session file to load. Must not be NULL.
*
* @return SR_OK upon success, SR_ERR_ARG upon invalid arguments,
* SR_ERR_MALLOC upon memory allocation errors, or SR_ERR upon
* other errors.
*/
SR_PRIV int sr_session_load(const char *filename)
{
GKeyFile *kf;
GPtrArray *capturefiles;
unzFile archive = NULL;
char szFilePath[15];
unz_file_info64 fileInfo;
struct sr_dev_inst *sdi;
struct sr_channel *probe;
int ret, devcnt, i, j;
uint16_t probenum;
uint64_t tmp_u64, total_probes, enabled_probes;
uint16_t p;
int64_t tmp_64;
char **sections, **keys, *metafile, *val;
char probename[SR_MAX_PROBENAME_LEN + 1];
int mode = LOGIC;
int channel_type = SR_CHANNEL_LOGIC;
double tmp_double;
int version = 1;
if (!filename) {
sr_err("%s: filename was NULL", __func__);
return SR_ERR_ARG;
}
archive = unzOpen64(filename);
if (NULL == archive) {
sr_err("load zip file error:%s", filename);
return SR_ERR;
}
if (unzLocateFile(archive, "header", 0) != UNZ_OK){
unzClose(archive);
sr_err("unzLocateFile error:'header', %s", filename);
return SR_ERR;
}
if (unzGetCurrentFileInfo64(archive, &fileInfo, szFilePath,
sizeof(szFilePath), NULL, 0, NULL, 0) != UNZ_OK){
unzClose(archive);
sr_err("unzGetCurrentFileInfo64 error,'header', %s", filename);
return SR_ERR;
}
if(unzOpenCurrentFile(archive) != UNZ_OK){
sr_err("cant't open zip inner file:'header',%s", filename);
unzClose(archive);
return SR_ERR;
}
if (!(metafile = g_try_malloc(fileInfo.uncompressed_size))) {
sr_err("%s: metafile malloc failed", __func__);
return SR_ERR_MALLOC;
}
unzReadCurrentFile(archive, metafile, fileInfo.uncompressed_size);
unzCloseCurrentFile(archive);
if (unzClose(archive) != UNZ_OK){
sr_err("close zip archive error:%s", filename);
return SR_ERR;
}
archive = NULL;
kf = g_key_file_new();
if (!g_key_file_load_from_data(kf, metafile, fileInfo.uncompressed_size, 0, NULL)) {
sr_err("Failed to parse metadata.");
return SR_ERR;
}
sr_session_new();
devcnt = 0;
capturefiles = g_ptr_array_new_with_free_func(g_free);
sections = g_key_file_get_groups(kf, NULL);
for (i = 0; sections[i]; i++) {
if (!strcmp(sections[i], "version")) {
keys = g_key_file_get_keys(kf, sections[i], NULL, NULL);
for (j = 0; keys[j]; j++) {
val = g_key_file_get_string(kf, sections[i], keys[j], NULL);
if (!strcmp(keys[j], "version")) {
version = strtoull(val, NULL, 10);
}
}
}
if (!strncmp(sections[i], "header", 6)) {
/* device section */
sdi = NULL;
enabled_probes = total_probes = 0;
keys = g_key_file_get_keys(kf, sections[i], NULL, NULL);
for (j = 0; keys[j]; j++) {
val = g_key_file_get_string(kf, sections[i], keys[j], NULL);
if (!strcmp(keys[j], "device mode")) {
mode = strtoull(val, NULL, 10);
} else if (!strcmp(keys[j], "capturefile")) {
sdi = sr_dev_inst_new(mode, devcnt, SR_ST_ACTIVE, NULL, NULL, NULL);
sdi->driver = &session_driver;
sdi->dev_type = DEV_TYPE_FILELOG;
if (devcnt == 0)
/* first device, init the driver */
sdi->driver->init(NULL);
//sr_dev_open(sdi);
//sr_session_dev_add(sdi);
g_assert(0);
sdi->driver->config_set(SR_CONF_SESSIONFILE,
g_variant_new_bytestring(filename), sdi, NULL, NULL);
sdi->driver->config_set(SR_CONF_CAPTUREFILE,
g_variant_new_bytestring(val), sdi, NULL, NULL);
g_ptr_array_add(capturefiles, val);
sdi->driver->config_set(SR_CONF_FILE_VERSION,
g_variant_new_int16(version), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "samplerate")) {
sr_parse_sizestring(val, &tmp_u64);
sdi->driver->config_set(SR_CONF_SAMPLERATE,
g_variant_new_uint64(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "total samples")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_LIMIT_SAMPLES,
g_variant_new_uint64(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "hDiv")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_TIMEBASE,
g_variant_new_uint64(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "hDiv min")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_MIN_TIMEBASE,
g_variant_new_uint64(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "hDiv max")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_MAX_TIMEBASE,
g_variant_new_uint64(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "bits")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_UNIT_BITS,
g_variant_new_byte(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "ref min")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_REF_MIN,
g_variant_new_uint32(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "ref max")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_REF_MAX,
g_variant_new_uint32(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "trigger time")) {
tmp_64 = strtoll(val, NULL, 10);
sdi->driver->config_set(SR_CONF_TRIGGER_TIME,
g_variant_new_int64(tmp_64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "trigger pos")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_TRIGGER_POS,
g_variant_new_uint64(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "total blocks")) {
tmp_u64 = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_NUM_BLOCKS,
g_variant_new_uint64(tmp_u64), sdi, NULL, NULL);
} else if (!strcmp(keys[j], "total probes")) {
total_probes = strtoull(val, NULL, 10);
sdi->driver->config_set(SR_CONF_CAPTURE_NUM_PROBES,
g_variant_new_uint64(total_probes), sdi, NULL, NULL);
if (version == 1) {
channel_type = (mode == DSO) ? SR_CHANNEL_DSO :
(mode == ANALOG) ? SR_CHANNEL_ANALOG : SR_CHANNEL_LOGIC;
for (p = 0; p < total_probes; p++) {
snprintf(probename, SR_MAX_PROBENAME_LEN, "%u", p);
if (!(probe = sr_channel_new(p, channel_type, FALSE,
probename)))
return SR_ERR;
sdi->channels = g_slist_append(sdi->channels, probe);
}
}
} else if (!strncmp(keys[j], "probe", 5)) {
if (!sdi)
continue;
enabled_probes++;
tmp_u64 = strtoul(keys[j]+5, NULL, 10);
/* sr_session_save() */
if (version == 1) {
sr_dev_probe_name_set(sdi, tmp_u64, val);
sr_dev_probe_enable(sdi, tmp_u64, TRUE);
} else if (version == 2) {
channel_type = (mode == DSO) ? SR_CHANNEL_DSO :
(mode == ANALOG) ? SR_CHANNEL_ANALOG : SR_CHANNEL_LOGIC;
if (!(probe = sr_channel_new(tmp_u64, channel_type, TRUE,
val)))
return SR_ERR;
sdi->channels = g_slist_append(sdi->channels, probe);
}
} else if (!strncmp(keys[j], "trigger", 7)) {
probenum = strtoul(keys[j]+7, NULL, 10);
sr_dev_trigger_set(sdi, probenum, val);
} else if (!strncmp(keys[j], "enable", 6)) {
if (mode != LOGIC)
continue;
probenum = strtoul(keys[j]+6, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_EN,
g_variant_new_boolean(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "coupling", 8)) {
probenum = strtoul(keys[j]+8, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_COUPLING,
g_variant_new_byte(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "vDiv", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_VDIV,
g_variant_new_uint64(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "vFactor", 7)) {
probenum = strtoul(keys[j]+7, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_FACTOR,
g_variant_new_uint64(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "vOffset", 7)) {
probenum = strtoul(keys[j]+7, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_HW_OFFSET,
g_variant_new_uint16(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "vTrig", 5)) {
probenum = strtoul(keys[j]+5, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_TRIGGER_VALUE,
g_variant_new_byte(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "period", 6)) {
probenum = strtoul(keys[j]+6, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_PERIOD,
g_variant_new_uint32(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "pcnt", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_PCNT,
g_variant_new_uint32(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "max", 3)) {
probenum = strtoul(keys[j]+3, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_MAX,
g_variant_new_byte(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "min", 3)) {
probenum = strtoul(keys[j]+3, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_MIN,
g_variant_new_byte(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "plen", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_PLEN,
g_variant_new_uint32(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "llen", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_LLEN,
g_variant_new_uint32(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "level", 5)) {
probenum = strtoul(keys[j]+5, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_LEVEL,
g_variant_new_boolean(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "plevel", 6)) {
probenum = strtoul(keys[j]+6, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_PLEVEL,
g_variant_new_boolean(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "low", 3)) {
probenum = strtoul(keys[j]+3, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_LOW,
g_variant_new_byte(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "high", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_HIGH,
g_variant_new_byte(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "rlen", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_RLEN,
g_variant_new_uint32(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "flen", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_FLEN,
g_variant_new_uint32(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "rms", 3)) {
probenum = strtoul(keys[j]+3, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_RMS,
g_variant_new_uint64(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "mean", 4)) {
probenum = strtoul(keys[j]+4, NULL, 10);
tmp_u64 = strtoull(val, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_STATUS_MEAN,
g_variant_new_uint32(tmp_u64), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "mapUnit", 7)) {
probenum = strtoul(keys[j]+7, NULL, 10);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_MAP_UNIT,
g_variant_new_string(val), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "mapMax", 6)) {
probenum = strtoul(keys[j]+6, NULL, 10);
tmp_double = strtod(val, NULL);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_MAP_MAX,
g_variant_new_double(tmp_double), sdi, probe, NULL);
}
} else if (!strncmp(keys[j], "mapMin", 6)) {
probenum = strtoul(keys[j]+6, NULL, 10);
tmp_double = strtod(val, NULL);
if (probenum < g_slist_length(sdi->channels)) {
probe = g_slist_nth(sdi->channels, probenum)->data;
sdi->driver->config_set(SR_CONF_PROBE_MAP_MIN,
g_variant_new_double(tmp_double), sdi, probe, NULL);
}
}
}
g_strfreev(keys);
}
devcnt++;
}
g_strfreev(sections);
g_key_file_free(kf);
return SR_OK;
}
/** @} */