diff --git a/DSView/pv/appcontrol.cpp b/DSView/pv/appcontrol.cpp index c17ac902..444d68ba 100644 --- a/DSView/pv/appcontrol.cpp +++ b/DSView/pv/appcontrol.cpp @@ -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) diff --git a/DSView/pv/dock/protocoldock.h b/DSView/pv/dock/protocoldock.h index 57069289..ff085854 100644 --- a/DSView/pv/dock/protocoldock.h +++ b/DSView/pv/dock/protocoldock.h @@ -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; diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index ae165342..c1019715 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -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(s))) { + if ((dsoSig = dynamic_cast(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(s))) { + if ((logicSig = dynamic_cast(s))) + { logicSig->set_trig(obj["strigger"].toDouble()); } view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { + if ((dsoSig = dynamic_cast(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(s))) { + if ((analogSig = dynamic_cast(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 diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 032930bb..abb24783 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -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 diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 27e83b24..12d5a0e6 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -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 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 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 diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index a0e3b573..da923a9a 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -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(); diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index 56aedc6e..4ae0c459 100644 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -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; } diff --git a/DSView/pv/storesession.h b/DSView/pv/storesession.h index 58892322..529d5469 100644 --- a/DSView/pv/storesession.h +++ b/DSView/pv/storesession.h @@ -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); diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index e4478ad7..6e07edec 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -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); diff --git a/libsigrok4DSL/dsdevice.c b/libsigrok4DSL/dsdevice.c index 79c455c5..8f168418 100644 --- a/libsigrok4DSL/dsdevice.c +++ b/libsigrok4DSL/dsdevice.c @@ -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); } diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 769860c2..0ec5d959 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -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) { diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index f5607021..245c7a6c 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -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) { diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index c3f04623..cb1c45c4 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -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; diff --git a/libsigrok4DSL/input/in_binary.c b/libsigrok4DSL/input/in_binary.c index 64de7d4c..fc1a8636 100644 --- a/libsigrok4DSL/input/in_binary.c +++ b/libsigrok4DSL/input/in_binary.c @@ -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++) { diff --git a/libsigrok4DSL/input/in_vcd.c b/libsigrok4DSL/input/in_vcd.c index 544f65d3..08e9f736 100644 --- a/libsigrok4DSL/input/in_vcd.c +++ b/libsigrok4DSL/input/in_vcd.c @@ -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++) { diff --git a/libsigrok4DSL/input/in_wav.c b/libsigrok4DSL/input/in_wav.c index c909ce12..3174f3e5 100644 --- a/libsigrok4DSL/input/in_wav.c +++ b/libsigrok4DSL/input/in_wav.c @@ -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)); diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index 45c2457e..0d870703 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -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---------------*/ \ No newline at end of file +/**-------------------private function end---------------*/ diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index 15ba99a5..7727e500 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -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 -------------------------------------------------*/ /** diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 01b37d50..2e3e9fde 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -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(); diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index 5c5cf746..504ddac4 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include "libsigrok-internal.h" #include #include @@ -30,7 +30,7 @@ /* Message logging helpers with subsystem-specific prefix string. */ -#undef LOG_PREFIX +#undef LOG_PREFIX #define LOG_PREFIX "virtual-session: " /* size of payloads sent across the session bus */ @@ -39,6 +39,11 @@ #define UNITLEN 64 /** @endcond */ +extern struct sr_session *session; +extern SR_PRIV struct sr_dev_driver session_driver; + +static int sr_load_virtual_device_session(struct sr_dev_inst *sdi); + static uint64_t samplerates[1]; static uint64_t samplecounts[1]; @@ -49,7 +54,7 @@ static const char *maxHeights[] = { "4X", "5X", }; - + static const uint64_t vdivs[] = { SR_mV(10), SR_mV(20), @@ -61,25 +66,54 @@ static const uint64_t vdivs[] = { SR_V(2), }; -struct session_vdev { +static void get_file_short_name(const char *file, char *buf, int buflen) +{ + if (file == NULL || *file == '\0' || buf == NULL || buflen < 1) + return; + + int len = strlen(file); + int pos = len; + char *wr = buf; + char c; + + while (pos >= 0) + { + pos--; + c = *(file + pos); + if (c == '/' || c == '\\') + { + pos++; + break; + } + } + + while (pos < len && (wr - buf) <= buflen) + { + *wr = *(file + pos); + wr++; + pos++; + } + *wr = '\0'; +} + +struct session_vdev +{ int language; int version; - char *sessionfile; - char *capturefile; - unzFile archive; //zip document - int capfile; //current inner file open status + unzFile archive; // zip document + int capfile; // current inner file open status void *buf; void *logic_buf; - int64_t bytes_read; + int64_t bytes_read; int cur_channel; int cur_block; - int num_blocks; - uint64_t samplerate; + int num_blocks; + uint64_t samplerate; uint64_t total_samples; int64_t trig_time; uint64_t trig_pos; - int num_probes; + int num_probes; int enabled_probes; uint64_t timebase; uint64_t max_timebase; @@ -91,8 +125,6 @@ struct session_vdev { struct sr_status mstatus; }; -static GSList *dev_insts = NULL; - static const int hwoptions[] = { SR_CONF_MAX_HEIGHT, }; @@ -128,19 +160,23 @@ static int trans_data(struct sr_dev_inst *sdi) assert(vdev->logic_buf != NULL); assert(CHUNKSIZE % UNITLEN == 0); - //int bytes = ceil(vdev->num_probes / 8.0); + // int bytes = ceil(vdev->num_probes / 8.0); int bytes = 2; uint8_t *src_ptr = (uint8_t *)vdev->buf; uint64_t *dest_ptr = (uint64_t *)vdev->logic_buf; - for (int k = 0; k < CHUNKSIZE / (UNITLEN * bytes); k++) { + + for (int k = 0; k < CHUNKSIZE / (UNITLEN * bytes); k++) + { src_ptr = (uint8_t *)vdev->buf + (k * bytes * UNITLEN); - for (l = sdi->channels; l; l = l->next) { + for (l = sdi->channels; l; l = l->next) + { probe = l->data; if (!probe->enabled) continue; uint64_t mask = 1ULL << probe->index; uint64_t result = 0; - for (int j = 0; j < UNITLEN; j++) { + for (int j = 0; j < UNITLEN; j++) + { if (*(uint64_t *)(src_ptr + j * bytes) & mask) result += 1ULL << j; } @@ -153,16 +189,18 @@ static int trans_data(struct sr_dev_inst *sdi) static int close_archive(struct session_vdev *vdev) { - assert(vdev->archive); + assert(vdev->archive); - //close current inner file - if (vdev->capfile){ + // close current inner file + if (vdev->capfile) + { unzCloseCurrentFile(vdev->archive); vdev->capfile = 0; } int ret = unzClose(vdev->archive); - if (ret != UNZ_OK){ + if (ret != UNZ_OK) + { sr_err("close zip archive error!"); } @@ -179,52 +217,53 @@ static void send_error_packet(const struct sr_dev_inst *cb_sdi, struct session_v close_archive(vdev); } -static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) +static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; struct session_vdev *vdev = NULL; - struct sr_datafeed_packet packet; - struct sr_datafeed_logic logic; + struct sr_datafeed_packet packet; + struct sr_datafeed_logic logic; struct sr_datafeed_dso dso; struct sr_datafeed_analog analog; - GSList *l; + GSList *l; int ret; char file_name[32]; struct sr_channel *probe = NULL; GSList *pl; - int channel; + int channel; - (void)fd; + assert(sdi); + assert(sdi->priv); + + (void)fd; //(void)revents; - sr_detail("Feed chunk."); + sr_detail("Feed chunk."); ret = 0; packet.status = SR_PKT_OK; - for (l = dev_insts; l; l = l->next) { - sdi = l->data; - vdev = sdi->priv; - - if (!vdev) - /* already done with this instance */ - continue; + vdev = sdi->priv; + if (vdev != NULL) + { assert(vdev->unit_bits > 0); assert(vdev->cur_channel >= 0); assert(vdev->archive); - if (vdev->cur_channel < vdev->num_probes) + if (vdev->cur_channel < vdev->num_probes) { - if (vdev->version == 1) { + if (vdev->version == 1) + { ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE); - if (-1 == ret){ - sr_err("read zip inner file error:%s", vdev->capturefile); - send_error_packet(cb_sdi, vdev, &packet); + if (-1 == ret) + { + sr_err("%s: Read inner file error!", __func__); + send_error_packet(sdi, vdev, &packet); return FALSE; } } - else if (vdev->version == 2) { + else if (vdev->version == 2) + { channel = vdev->cur_channel; pl = sdi->channels; @@ -233,41 +272,47 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) probe = (struct sr_channel *)pl->data; - if (vdev->capfile == 0) { - char *type_name = (probe->type == SR_CHANNEL_LOGIC) ? "L" : - (probe->type == SR_CHANNEL_DSO) ? "O" : - (probe->type == SR_CHANNEL_ANALOG) ? "A" : "U"; + if (vdev->capfile == 0) + { + char *type_name = (probe->type == SR_CHANNEL_LOGIC) ? "L" : (probe->type == SR_CHANNEL_DSO) ? "O" + : (probe->type == SR_CHANNEL_ANALOG) ? "A" + : "U"; snprintf(file_name, 31, "%s-%d/%d", type_name, sdi->mode == LOGIC ? probe->index : 0, vdev->cur_block); - if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK) - { - sr_err("cant't locate zip inner file:%s", file_name); - send_error_packet(cb_sdi, vdev, &packet); - return FALSE; - } - if(unzOpenCurrentFile(vdev->archive) != UNZ_OK){ - sr_err("cant't open zip inner file:%s", file_name); - send_error_packet(cb_sdi, vdev, &packet); - return FALSE; - } - vdev->capfile = 1; + if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK) + { + sr_err("cant't locate zip inner file:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + if (unzOpenCurrentFile(vdev->archive) != UNZ_OK) + { + sr_err("cant't open zip inner file:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + vdev->capfile = 1; } - if (vdev->capfile){ + if (vdev->capfile) + { ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE); - if (-1 == ret){ + if (-1 == ret) + { sr_err("read zip inner file error:%s", file_name); - send_error_packet(cb_sdi, vdev, &packet); - return FALSE; + send_error_packet(sdi, vdev, &packet); + return FALSE; } } } - - if (ret > 0) { - if (sdi->mode == DSO) { + + if (ret > 0) + { + if (sdi->mode == DSO) + { packet.type = SR_DF_DSO; packet.payload = &dso; dso.num_samples = ret / vdev->num_probes; @@ -276,8 +321,9 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) dso.mq = SR_MQ_VOLTAGE; dso.unit = SR_UNIT_VOLT; dso.mqflags = SR_MQFLAG_AC; - } - else if (sdi->mode == ANALOG){ + } + else if (sdi->mode == ANALOG) + { packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.probes = sdi->channels; @@ -287,8 +333,9 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; analog.data = vdev->buf; - } - else { + } + else + { packet.type = SR_DF_LOGIC; packet.payload = &logic; logic.length = ret; @@ -299,53 +346,61 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) logic.index = 0; logic.order = vdev->cur_channel; - if (vdev->version == 1) { + if (vdev->version == 1) + { logic.length = ret / 16 * vdev->enabled_probes; logic.data = vdev->logic_buf; trans_data(sdi); - } - else if (vdev->version == 2) { + } + else if (vdev->version == 2) + { logic.length = ret; logic.data = vdev->buf; } } vdev->bytes_read += ret; - ds_data_forward(cb_sdi, &packet); + ds_data_forward(sdi, &packet); } - else{ + else + { /* done with this capture file */ unzCloseCurrentFile(vdev->archive); vdev->capfile = 0; - - if (vdev->version == 1){ + + if (vdev->version == 1) + { vdev->cur_channel++; } - else if (vdev->version == 2) { + else if (vdev->version == 2) + { vdev->cur_block++; // if read to the last block, move to next channel - if (vdev->cur_block == vdev->num_blocks) { + if (vdev->cur_block == vdev->num_blocks) + { vdev->cur_block = 0; vdev->cur_channel++; } } } } - } + } - if (!vdev || vdev->cur_channel >= vdev->num_probes || revents == -1) { - packet.type = SR_DF_END; - ds_data_forward(cb_sdi, &packet); - sr_session_source_remove(-1); + if (!vdev || vdev->cur_channel >= vdev->num_probes || revents == -1) + { + packet.type = SR_DF_END; + ds_data_forward(sdi, &packet); + sr_session_source_remove(-1); - if (NULL != vdev){ - // abort - close_archive(vdev); + if (NULL != vdev) + { + // abort + close_archive(vdev); vdev->bytes_read = 0; - } - } + } + } - return TRUE; + return TRUE; } /* driver callbacks */ @@ -353,9 +408,9 @@ static int dev_clear(void); static int init(struct sr_context *sr_ctx) { - (void)sr_ctx; + (void)sr_ctx; - return SR_OK; + return SR_OK; } static const GSList *dev_mode_list(const struct sr_dev_inst *sdi) @@ -363,7 +418,8 @@ static const GSList *dev_mode_list(const struct sr_dev_inst *sdi) GSList *l = NULL; unsigned int i; - for (i = 0; i < ARRAY_SIZE(sr_mode_list); i++) { + for (i = 0; i < ARRAY_SIZE(sr_mode_list); i++) + { if (sdi->mode == sr_mode_list[i].mode) l = g_slist_append(l, &sr_mode_list[i]); } @@ -373,33 +429,40 @@ static const GSList *dev_mode_list(const struct sr_dev_inst *sdi) static int dev_clear(void) { - GSList *l; - - for (l = dev_insts; l; l = l->next) - sr_dev_inst_free(l->data); - g_slist_free(dev_insts); - dev_insts = NULL; - - return SR_OK; + return SR_OK; } static int dev_open(struct sr_dev_inst *sdi) { - if (!(sdi->priv = g_try_malloc0(sizeof(struct session_vdev)))) { - sr_err("%s: sdi->priv malloc failed", __func__); - return SR_ERR_MALLOC; - } + int ret; + + if (sdi->priv == NULL) + { + sdi->priv = g_try_malloc0(sizeof(struct session_vdev)); + if (sdi->priv == NULL) + { + sr_err("%s: sdi->priv malloc failed", __func__); + return SR_ERR_MALLOC; + } + } struct session_vdev *vdev; vdev = sdi->priv; - if (!(vdev->buf = g_try_malloc(CHUNKSIZE + sizeof(uint64_t)))) { - sr_err("%s: vdev->buf malloc failed", __func__); - return SR_ERR_MALLOC; + + if (vdev->buf == NULL) + { + vdev->buf = g_try_malloc(CHUNKSIZE + sizeof(uint64_t)); + if (vdev->buf == NULL) + { + sr_err("%s: vdev->buf malloc failed", __func__); + return SR_ERR_MALLOC; + } } + vdev->trig_pos = 0; vdev->trig_time = 0; vdev->cur_block = 0; - vdev->cur_channel = 0; + vdev->cur_channel = 0; vdev->num_blocks = 0; vdev->unit_bits = 1; vdev->ref_min = 0; @@ -411,22 +474,26 @@ static int dev_open(struct sr_dev_inst *sdi) vdev->archive = NULL; vdev->capfile = 0; - dev_insts = g_slist_append(dev_insts, sdi); + ret = sr_load_virtual_device_session(sdi); + if (ret != SR_OK) + { + sr_err("%s", "Error!Load session file failed."); + return ret; + } - return SR_OK; + return SR_OK; } static int dev_close(struct sr_dev_inst *sdi) { struct session_vdev *vdev; - if (sdi && sdi->priv){ + if (sdi && sdi->priv) + { vdev = sdi->priv; - g_safe_free(vdev->sessionfile); - g_safe_free(vdev->capturefile); g_safe_free(vdev->buf); g_safe_free(vdev->logic_buf); - g_safe_free(sdi->priv); + g_safe_free(sdi->priv); } return SR_OK; @@ -435,7 +502,7 @@ static int dev_close(struct sr_dev_inst *sdi) static int dev_destroy(struct sr_dev_inst *sdi) { assert(sdi); - dev_close(sdi); + dev_close(sdi); sr_dev_inst_free(sdi); } @@ -445,120 +512,154 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, { (void)cg; - struct session_vdev *vdev; + assert(sdi); + assert(sdi->priv); - switch (id) { + struct session_vdev *vdev; + + switch (id) + { case SR_CONF_LANGUAGE: if (!sdi) return SR_ERR; vdev = sdi->priv; *data = g_variant_new_int16(vdev->language); break; - case SR_CONF_SAMPLERATE: - if (sdi) { - vdev = sdi->priv; - *data = g_variant_new_uint64(vdev->samplerate); - } else - return SR_ERR; - break; + case SR_CONF_SAMPLERATE: + if (sdi) + { + vdev = sdi->priv; + *data = g_variant_new_uint64(vdev->samplerate); + } + else + return SR_ERR; + break; case SR_CONF_LIMIT_SAMPLES: - if (sdi) { + if (sdi) + { vdev = sdi->priv; *data = g_variant_new_uint64(vdev->total_samples); - } else + } + else return SR_ERR; break; case SR_CONF_TRIGGER_TIME: - if (sdi) { + if (sdi) + { vdev = sdi->priv; *data = g_variant_new_int64(vdev->trig_time); - } else + } + else return SR_ERR; break; case SR_CONF_TIMEBASE: - if (sdi) { + if (sdi) + { vdev = sdi->priv; *data = g_variant_new_uint64(vdev->timebase); - } else + } + else return SR_ERR; break; case SR_CONF_MAX_TIMEBASE: - if (sdi) { + if (sdi) + { vdev = sdi->priv; *data = g_variant_new_uint64(vdev->max_timebase); - } else + } + else return SR_ERR; break; case SR_CONF_MIN_TIMEBASE: - if (sdi) { + if (sdi) + { vdev = sdi->priv; *data = g_variant_new_uint64(vdev->min_timebase); - } else + } + else return SR_ERR; break; case SR_CONF_UNIT_BITS: - if (sdi) { + if (sdi) + { vdev = sdi->priv; *data = g_variant_new_byte(vdev->unit_bits); - } else + } + else return SR_ERR; break; case SR_CONF_REF_MIN: - if (sdi) { + if (sdi) + { vdev = sdi->priv; if (vdev->ref_min == 0) return SR_ERR; else *data = g_variant_new_uint32(vdev->ref_min); - } else + } + else return SR_ERR; break; case SR_CONF_REF_MAX: - if (sdi) { + if (sdi) + { vdev = sdi->priv; if (vdev->ref_max == 0) return SR_ERR; else *data = g_variant_new_uint32(vdev->ref_max); - } else + } + else return SR_ERR; break; case SR_CONF_PROBE_EN: - if (sdi && ch) { + if (sdi && ch) + { *data = g_variant_new_boolean(ch->enabled); - } else + } + else return SR_ERR; break; case SR_CONF_PROBE_COUPLING: - if (sdi && ch) { + if (sdi && ch) + { *data = g_variant_new_byte(ch->coupling); - } else + } + else return SR_ERR; break; case SR_CONF_PROBE_VDIV: - if (sdi && ch) { + if (sdi && ch) + { *data = g_variant_new_uint64(ch->vdiv); - } else + } + else return SR_ERR; break; case SR_CONF_PROBE_FACTOR: - if (sdi && ch) { + if (sdi && ch) + { *data = g_variant_new_uint64(ch->vfactor); - } else + } + else return SR_ERR; break; case SR_CONF_PROBE_OFFSET: - if (sdi && ch) { + if (sdi && ch) + { *data = g_variant_new_uint16(ch->offset); - } else + } + else return SR_ERR; break; case SR_CONF_PROBE_HW_OFFSET: - if (sdi && ch) { + if (sdi && ch) + { *data = g_variant_new_uint16(ch->hw_offset); - } else + } + else return SR_ERR; - break; + break; case SR_CONF_PROBE_MAP_UNIT: if (!sdi || !ch) return SR_ERR; @@ -575,9 +676,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_double(ch->map_max); break; case SR_CONF_TRIGGER_VALUE: - if (sdi && ch) { + if (sdi && ch) + { *data = g_variant_new_byte(ch->trig_value); - } else + } + else return SR_ERR; break; case SR_CONF_MAX_DSO_SAMPLERATE: @@ -623,10 +726,10 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_int16(vdev->version); break; default: - return SR_ERR_ARG; - } + return SR_ERR_ARG; + } - return SR_OK; + return SR_OK; } static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, @@ -635,21 +738,25 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, { (void)cg; - struct session_vdev *vdev; + struct session_vdev *vdev; const char *stropt; unsigned int i; - vdev = sdi->priv; + assert(sdi); + assert(sdi->priv); - switch (id) { + vdev = sdi->priv; + + switch (id) + { case SR_CONF_LANGUAGE: vdev->language = g_variant_get_int16(data); break; - case SR_CONF_SAMPLERATE: - vdev->samplerate = g_variant_get_uint64(data); + case SR_CONF_SAMPLERATE: + vdev->samplerate = g_variant_get_uint64(data); samplerates[0] = vdev->samplerate; - sr_dbg("Setting samplerate to %llu.", vdev->samplerate); - break; + sr_dbg("Setting samplerate to %llu.", vdev->samplerate); + break; case SR_CONF_TIMEBASE: vdev->timebase = g_variant_get_uint64(data); sr_dbg("Setting timebase to %llu.", vdev->timebase); @@ -674,14 +781,6 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, vdev->ref_max = g_variant_get_uint32(data); sr_dbg("Setting ref max to %d.", vdev->ref_max); break; - case SR_CONF_SESSIONFILE: - vdev->sessionfile = g_strdup(g_variant_get_bytestring(data)); - sr_dbg("Setting sessionfile to '%s'.", vdev->sessionfile); - break; - case SR_CONF_CAPTUREFILE: - vdev->capturefile = g_strdup(g_variant_get_bytestring(data)); - sr_dbg("Setting capturefile to '%s'.", vdev->capturefile); - break; case SR_CONF_FILE_VERSION: vdev->version = g_variant_get_int16(data); sr_dbg("Setting file version to '%d'.", vdev->version); @@ -704,17 +803,22 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("Setting block number to %llu.", vdev->num_blocks); break; case SR_CONF_CAPTURE_NUM_PROBES: - vdev->num_probes = g_variant_get_uint64(data); - if (vdev->version == 1) { - if (sdi->mode == LOGIC) { - if (!(vdev->logic_buf = g_try_malloc(CHUNKSIZE/16*vdev->num_probes))) { + vdev->num_probes = g_variant_get_uint64(data); + if (vdev->version == 1) + { + if (sdi->mode == LOGIC) + { + if (!(vdev->logic_buf = g_try_malloc(CHUNKSIZE / 16 * vdev->num_probes))) + { sr_err("%s: vdev->logic_buf malloc failed", __func__); } } - } else { + } + else + { vdev->logic_buf = NULL; } - break; + break; case SR_CONF_PROBE_EN: ch->enabled = g_variant_get_boolean(data); break; @@ -733,7 +837,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, case SR_CONF_PROBE_HW_OFFSET: ch->hw_offset = g_variant_get_uint16(data); ch->offset = ch->hw_offset; - break; + break; case SR_CONF_PROBE_MAP_UNIT: ch->map_unit = g_variant_get_string(data, NULL); break; @@ -832,24 +936,26 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, break; case SR_CONF_MAX_HEIGHT: stropt = g_variant_get_string(data, NULL); - for (i = 0; i < ARRAY_SIZE(maxHeights); i++) { - if (!strcmp(stropt, maxHeights[i])) { + for (i = 0; i < ARRAY_SIZE(maxHeights); i++) + { + if (!strcmp(stropt, maxHeights[i])) + { vdev->max_height = i; break; } } sr_dbg("%s: setting Signal Max Height to %d", - __func__, vdev->max_height); + __func__, vdev->max_height); break; case SR_CONF_INSTANT: case SR_CONF_RLE: break; default: - sr_err("Unknown capability: %d.", id); - return SR_ERR; - } + sr_err("Unknown capability: %d.", id); + return SR_ERR; + } - return SR_OK; + return SR_OK; } static int config_list(int key, GVariant **data, @@ -861,32 +967,29 @@ static int config_list(int key, GVariant **data, GVariant *gvar; GVariantBuilder gvb; - (void)sdi; + (void)sdi; - switch (key) { + switch (key) + { case SR_CONF_DEVICE_OPTIONS: -// *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, -// hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t)); *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), - hwoptions, ARRAY_SIZE(hwoptions)*sizeof(int32_t), TRUE, NULL, NULL); + hwoptions, ARRAY_SIZE(hwoptions) * sizeof(int32_t), TRUE, NULL, NULL); break; case SR_CONF_DEVICE_SESSIONS: *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), - sessions, ARRAY_SIZE(sessions)*sizeof(int32_t), TRUE, NULL, NULL); + sessions, ARRAY_SIZE(sessions) * sizeof(int32_t), TRUE, NULL, NULL); break; case SR_CONF_SAMPLERATE: g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); -// gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates, -// ARRAY_SIZE(samplerates), sizeof(uint64_t)); gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), - samplerates, ARRAY_SIZE(samplerates)*sizeof(uint64_t), TRUE, NULL, NULL); + samplerates, ARRAY_SIZE(samplerates) * sizeof(uint64_t), TRUE, NULL, NULL); g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar); *data = g_variant_builder_end(&gvb); break; case SR_CONF_LIMIT_SAMPLES: g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), - samplecounts, ARRAY_SIZE(samplecounts)*sizeof(uint64_t), TRUE, NULL, NULL); + samplecounts, ARRAY_SIZE(samplecounts) * sizeof(uint64_t), TRUE, NULL, NULL); g_variant_builder_add(&gvb, "{sv}", "samplecounts", gvar); *data = g_variant_builder_end(&gvb); break; @@ -896,12 +999,12 @@ static int config_list(int key, GVariant **data, case SR_CONF_PROBE_CONFIGS: *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), - probeOptions, ARRAY_SIZE(probeOptions)*sizeof(int32_t), TRUE, NULL, NULL); + probeOptions, ARRAY_SIZE(probeOptions) * sizeof(int32_t), TRUE, NULL, NULL); break; case SR_CONF_PROBE_VDIV: g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), - vdivs, ARRAY_SIZE(vdivs)*sizeof(uint64_t), TRUE, NULL, NULL); + vdivs, ARRAY_SIZE(vdivs) * sizeof(uint64_t), TRUE, NULL, NULL); g_variant_builder_add(&gvb, "{sv}", "vdivs", gvar); *data = g_variant_builder_end(&gvb); break; @@ -909,10 +1012,10 @@ static int config_list(int key, GVariant **data, *data = g_variant_new_strv(probeMapUnits, ARRAY_SIZE(probeMapUnits)); break; default: - return SR_ERR_ARG; - } + return SR_ERR_ARG; + } - return SR_OK; + return SR_OK; } static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg) @@ -921,84 +1024,100 @@ static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *statu struct session_vdev *vdev; - if (sdi) { + if (sdi) + { vdev = sdi->priv; *status = vdev->mstatus; return SR_OK; - } else { + } + else + { return SR_ERR; } } -static int dev_acquisition_start(struct sr_dev_inst *sdi, - void *cb_data) +static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) { (void)cb_data; - - struct session_vdev *vdev; + + struct session_vdev *vdev; struct sr_datafeed_packet packet; int ret; GSList *l; - struct sr_channel *probe; + struct sr_channel *probe; - vdev = sdi->priv; + assert(sdi); + assert(sdi->priv); + assert(sdi->path); + + if (sdi->dev_type != DEV_TYPE_FILELOG) + { + assert(0); + } + + vdev = sdi->priv; vdev->enabled_probes = 0; packet.status = SR_PKT_OK; - //reset status + // reset status vdev->cur_block = 0; vdev->cur_channel = 0; - if (vdev->archive != NULL){ + if (vdev->archive != NULL) + { sr_err("history archive is not closed."); - } - sr_dbg("Opening archive %s file %s", vdev->sessionfile, - vdev->capturefile); + sr_dbg("Opening archive file %s", sdi->path); - vdev->archive = unzOpen64(vdev->sessionfile); + vdev->archive = unzOpen64(sdi->path); - if (NULL == vdev->archive) { - sr_err("Failed to open session file '%s': " - "zip error %d\n", vdev->sessionfile, ret); - return SR_ERR; - } + if (NULL == vdev->archive) + { + sr_err("Failed to open session file '%s': " + "zip error %d\n", + sdi->path, ret); + return SR_ERR; + } - if (vdev->version == 1) { - if (unzLocateFile(vdev->archive, vdev->capturefile, 0) != UNZ_OK) + if (vdev->version == 1) + { + if (unzLocateFile(vdev->archive, "data", 0) != UNZ_OK) { - sr_err("cant't locate zip inner file:%s", vdev->capturefile); - close_archive(vdev); - return SR_ERR; + sr_err("cant't locate zip inner file:%s", "data"); + close_archive(vdev); + return SR_ERR; } if (unzOpenCurrentFile(vdev->archive) != UNZ_OK) { - sr_err("cant't open zip inner file:%s", vdev->capturefile); - close_archive(vdev); - return SR_ERR; + sr_err("cant't open zip inner file:%s", "data"); + close_archive(vdev); + return SR_ERR; } vdev->capfile = 1; vdev->cur_channel = vdev->num_probes - 1; - } - else { + } + else + { if (sdi->mode == LOGIC) vdev->cur_channel = 0; else vdev->cur_channel = vdev->num_probes - 1; } - for (l = sdi->channels; l; l = l->next) { + for (l = sdi->channels; l; l = l->next) + { probe = l->data; if (probe->enabled) vdev->enabled_probes++; } - /* Send header packet to the session bus. */ + /* Send header packet to the session bus. */ std_session_send_df_header(sdi, LOG_PREFIX); /* Send trigger packet to the session bus */ - if (vdev->trig_pos != 0) { + if (vdev->trig_pos != 0) + { struct ds_trigger_pos session_trigger; if (sdi->mode == DSO) session_trigger.real_pos = vdev->trig_pos * vdev->enabled_probes / vdev->num_probes; @@ -1009,10 +1128,629 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, ds_data_forward(sdi, &packet); } - /* freewheeling source */ + /* freewheeling source */ sr_session_source_add(-1, 0, 0, receive_data, sdi); - return SR_OK; + return SR_OK; +} + +SR_PRIV int sr_new_virtual_device(const char *filename, struct sr_dev_inst **out_di) +{ + struct sr_dev_inst *sdi; + char short_name[50]; + GKeyFile *kf; + char **sections, **keys, *metafile, *val; + int mode = LOGIC; + unzFile archive; + unz_file_info64 fileInfo; + char szFilePath[15]; + int i, j; + + archive = NULL; + sdi = NULL; + + if (!filename) + { + sr_err("%s: filename was NULL", __func__); + return SR_ERR_ARG; + } + + if (out_di == NULL) + { + sr_err("%s: @out_di 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; + } + + // Get mode value. + sections = g_key_file_get_groups(kf, NULL); + for (i = 0; sections[i]; i++) + { + if (strncmp(sections[i], "header", 6) == 0) + { + keys = g_key_file_get_keys(kf, sections[i], NULL, NULL); + for (j = 0; keys[j]; j++) + { + if (strcmp(keys[j], "device mode") == 0) + { + val = g_key_file_get_string(kf, sections[i], keys[j], NULL); + mode = strtoull(val, NULL, 10); + break; + } + } + g_strfreev(keys); + } + } + g_strfreev(sections); + g_key_file_free(kf); + g_free(metafile); + + sdi = sr_dev_inst_new(mode, SR_ST_ACTIVE, NULL, NULL, NULL); + sdi->driver = &session_driver; + sdi->dev_type = DEV_TYPE_FILELOG; + + get_file_short_name(filename, short_name, sizeof(short_name) - 1); + strncpy(sdi->name, short_name, sizeof(short_name) - 1); + sdi->path = g_strdup(filename); + + *out_di = sdi; + + return SR_OK; +} + +static int sr_load_virtual_device_session(struct sr_dev_inst *sdi) +{ + GKeyFile *kf; + unzFile archive = NULL; + char szFilePath[15]; + unz_file_info64 fileInfo; + + 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; + + assert(sdi); + assert(sdi->path); + + if (sdi->dev_type != DEV_TYPE_FILELOG) + { + sr_err("%s: Is not a virtual device instance.", __func__); + return SR_ERR_ARG; + } + + // Clear all channels. + sr_dev_probes_free(sdi); + + archive = unzOpen64(sdi->path); + if (NULL == archive) + { + sr_err("%s: Load zip file error.", __func__); + return SR_ERR; + } + if (unzLocateFile(archive, "header", 0) != UNZ_OK) + { + unzClose(archive); + sr_err("%s: unzLocateFile error.", __func__); + return SR_ERR; + } + if (unzGetCurrentFileInfo64(archive, &fileInfo, szFilePath, + sizeof(szFilePath), NULL, 0, NULL, 0) != UNZ_OK) + { + unzClose(archive); + sr_err("%s: unzGetCurrentFileInfo64 error.", __func__); + return SR_ERR; + } + if (unzOpenCurrentFile(archive) != UNZ_OK) + { + sr_err("%s: Cant't open zip inner file.", __func__); + 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("%s: Close zip archive error.", __func__); + 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; + } + + devcnt = 0; + 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 */ + 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->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))) + { + sr_err("%s: create channel failed", __func__); + sr_dev_inst_free(sdi); + 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))) + { + sr_err("%s: create channel failed", __func__); + sr_dev_inst_free(sdi); + 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); + g_free(metafile); + + return SR_OK; } /** @private */ @@ -1023,7 +1761,7 @@ SR_PRIV struct sr_dev_driver session_driver = { .driver_type = DRIVER_TYPE_FILE, .init = init, .cleanup = dev_clear, - .scan = NULL, + .scan = NULL, .dev_mode_list = dev_mode_list, .config_get = config_get, .config_set = config_set, diff --git a/libsigrok4DSL/session_file.c b/libsigrok4DSL/session_file.c deleted file mode 100644 index 8d1ec67b..00000000 --- a/libsigrok4DSL/session_file.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * This file is part of the libsigrok project. - * - * Copyright (C) 2013 Bert Vermeulen - * - * 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 . - */ - -#include "libsigrok-internal.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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; -} - -/** @} */