From 3db2bca184148039250dab296b525e0d811229db Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Apr 2010 19:09:00 +0200 Subject: [PATCH] added himd format feature using libsgutils2 --- libhimd/himd.h | 10 +++- libhimd/himd_scsi.c | 108 +++++++++++++++++++++++++++++++++++ libhimd/libhimd.pro | 10 +++- qhimdtransfer/qhimddetection.h | 1 + qhimdtransfer/qhimdformatdialog.cpp | 54 +++++++++++++++++ qhimdtransfer/qhimdformatdialog.h | 10 +++ qhimdtransfer/qhimdmainwindow.cpp | 27 +++++++-- qhimdtransfer/qhimdmainwindow.h | 1 + qhimdtransfer/qhimdwindetection.cpp | 3 +- 9 files changed, 215 insertions(+), 9 deletions(-) create mode 100644 libhimd/himd_scsi.c diff --git a/libhimd/himd.h b/libhimd/himd.h index c283c1f..5c4789d 100644 --- a/libhimd/himd.h +++ b/libhimd/himd.h @@ -60,7 +60,9 @@ enum himdstatus { HIMD_OK, HIMD_ERROR_BAD_DATA_FORMAT, HIMD_ERROR_UNSUPPORTED_ENCRYPTION, HIMD_ERROR_ENCRYPTION_FAILURE, - HIMD_ERROR_OUT_OF_MEMORY }; + HIMD_ERROR_OUT_OF_MEMORY, + HIMD_ERROR_SCSI_COMMUNICATION_FAILURE, + HIMD_ERROR_SCSI_COMMAND_FAILED }; /* a track on the HiMD */ struct trackinfo { @@ -195,6 +197,12 @@ struct himd_holelist { int himd_find_holes(struct himd * himd, struct himd_holelist * holes, struct himderrinfo * status); +/* himd_scsi.c */ +int himdscsi_open_device(char * device); +int himdscsi_send_format_cmd(int open_device, struct himderrinfo * status); +void himdscsi_wait_for_unit_ready(int open_device); +void himdscsi_close_device(int open_device); + #ifdef __cplusplus } diff --git a/libhimd/himd_scsi.c b/libhimd/himd_scsi.c new file mode 100644 index 0000000..e038d2b --- /dev/null +++ b/libhimd/himd_scsi.c @@ -0,0 +1,108 @@ +#include + +#include "himd.h" +#include "himd_private.h" + +#define _(x) (x) + +#ifdef CONFIG_WITH_LIBSGUTILS +#include +#include + +#define SCSI_TIMEOUT 20 + +int himdscsi_open_device(char * device) +{ + return scsi_pt_open_device(device, 0 ,0); +} + +int himdscsi_send_format_cmd(int open_device, struct himderrinfo * status) +{ + int success = -1; + struct sg_pt_base *ptvp = NULL; + unsigned char sense_buffer[32]; + char sense[1024]; + static const unsigned char cmd_formathimd[12] = {0xC2,0,0,0,3,0,0,0,0,0,0,0}; + + ptvp = construct_scsi_pt_obj(); + if (ptvp == NULL) + { + set_status_const(status, HIMD_ERROR_OUT_OF_MEMORY, _("Error opening scsi_pt object, out of memory")); + goto clean; + } + + set_scsi_pt_cdb(ptvp, cmd_formathimd, sizeof(cmd_formathimd)); + set_scsi_pt_sense(ptvp, sense_buffer, sizeof(sense_buffer)); + + if(do_scsi_pt(ptvp, open_device, SCSI_TIMEOUT, 0) != 0) + { + set_status_const(status, HIMD_ERROR_SCSI_COMMUNICATION_FAILURE, _("Error sending scsi command")); + goto clean; + } + + if(get_scsi_pt_result_category(ptvp) == SCSI_PT_RESULT_GOOD) + { + success = 0; + goto clean; + } + else if(get_scsi_pt_result_category(ptvp) == SCSI_PT_RESULT_SENSE) + { + sg_get_sense_str(NULL, sense_buffer, sizeof(sense_buffer), 0, sizeof(sense), sense); + set_status_const(status, HIMD_ERROR_SCSI_COMMAND_FAILED, sense); + } +clean: + if (ptvp) + destruct_scsi_pt_obj(ptvp); + + return success; +} + +void himdscsi_wait_for_unit_ready(int open_device) +{ + int status; + static const unsigned char cmd_testunitready[6]; + + do + { + struct sg_pt_base *ptvp = construct_scsi_pt_obj(); + if (ptvp == NULL) + break; + set_scsi_pt_cdb(ptvp, cmd_testunitready, sizeof(cmd_testunitready)); + do_scsi_pt(ptvp, open_device, SCSI_TIMEOUT, 0); + status = get_scsi_pt_result_category(ptvp); + destruct_scsi_pt_obj(ptvp); + } + while(status != SCSI_PT_RESULT_GOOD); +} + +void himdscsi_close_device(int open_device) +{ + if (open_device >= 0) + scsi_pt_close_device(open_device); +} +#else + +int himdscsi_open_device(char * device) +{ + return -1; +} + +int himdscsi_send_format_cmd(int open_device, struct himderrinfo * status) +{ + set_status_const(status, HIMD_ERROR_DISABLED_FEATURE, _("Can't send scsi commands: Compiled without sgutils2 library")); + return -1; +} + +void himdscsi_wait_for_unit_ready(int open_device) +{ +} + +void himdscsi_close_device(int open_device) +{ +} + +#endif + + + + diff --git a/libhimd/libhimd.pro b/libhimd/libhimd.pro index 45390d0..acef86e 100644 --- a/libhimd/libhimd.pro +++ b/libhimd/libhimd.pro @@ -16,7 +16,13 @@ else: !build_pass: message(You disabled mcrypt: No PCM and ATRAC transfer will b } else: !build_pass: message(You disabled mad: MP3 transfer will be limited) +!without_libsgutils: { + LIBS += -lsgutils2 + DEFINES += CONFIG_WITH_LIBSGUTILS +} +else:!build_pass:message(You disabled libsgutils2: Formating of himd will not be supported) + PKGCONFIG += glib-2.0 HEADERS += himd.h himd_private.h sony_oma.h -SOURCES += encryption.c himd.c mdstream.c trackindex.c sony_oma.c frag.c -LIBS += -lmad -lmcrypt +SOURCES += encryption.c himd.c mdstream.c trackindex.c sony_oma.c frag.c himd_scsi.c +LIBS += -lmad -lmcrypt -lsgutils2 diff --git a/qhimdtransfer/qhimddetection.h b/qhimdtransfer/qhimddetection.h index 5c30be9..5a417a6 100644 --- a/qhimdtransfer/qhimddetection.h +++ b/qhimdtransfer/qhimddetection.h @@ -24,6 +24,7 @@ struct himd_device { QString path; bool md_inserted; QString recorder_name; + QString scsi_device; virtual ~himd_device(){} /* for polymorphic delete */ }; diff --git a/qhimdtransfer/qhimdformatdialog.cpp b/qhimdtransfer/qhimdformatdialog.cpp index f3e0452..e91a813 100644 --- a/qhimdtransfer/qhimdformatdialog.cpp +++ b/qhimdtransfer/qhimdformatdialog.cpp @@ -1,5 +1,25 @@ #include "qhimdformatdialog.h" #include "ui_qhimdformatdialog.h" +#include +#include "../libhimd/himd.h" + +void QHiMDFormatDialog::open_scsidevice(QString device) +{ + sg_open = -1; + + if(device.isEmpty()) + goto clean; + + sg_open = himdscsi_open_device(device.toLocal8Bit().data()); + if(sg_open >= 0) + { + show(); + return; + } + +clean: + emit format_finished(); +} QHiMDFormatDialog::QHiMDFormatDialog(QWidget *parent) : QDialog(parent), @@ -23,3 +43,37 @@ void QHiMDFormatDialog::changeEvent(QEvent *e) break; } } + +void QHiMDFormatDialog::closeEvent(QEvent *event) +{ + if(sg_open >= 0) + himdscsi_close_device(sg_open); + sg_open = -1; + emit format_finished(); +} + +void QHiMDFormatDialog::on_buttonBox_accepted() +{ + struct himderrinfo status; + QString errmsg; + QMessageBox formatStatus; + + if(himdscsi_send_format_cmd(sg_open, &status) < 0) + formatStatus.setText(tr("Error formatting HiMD:\n") + status.statusmsg); + else + { + himdscsi_wait_for_unit_ready(sg_open); + formatStatus.setText(tr("HiMD successfully formatted")); + } + + himdscsi_close_device(sg_open); + sg_open = -1; + formatStatus.exec(); + emit format_finished(); +} + + +void QHiMDFormatDialog::on_buttonBox_rejected() +{ + closeEvent(NULL); +} diff --git a/qhimdtransfer/qhimdformatdialog.h b/qhimdtransfer/qhimdformatdialog.h index 5b92c8a..39a7ac7 100644 --- a/qhimdtransfer/qhimdformatdialog.h +++ b/qhimdtransfer/qhimdformatdialog.h @@ -13,12 +13,22 @@ class QHiMDFormatDialog : public QDialog { public: explicit QHiMDFormatDialog(QWidget *parent = 0); virtual ~QHiMDFormatDialog(); + void open_scsidevice(QString device); protected: virtual void changeEvent(QEvent *e); + virtual void closeEvent(QEvent *event); private: Ui::QHiMDFormatDialog *m_ui; + int sg_open; + +private slots: + void on_buttonBox_rejected(); + void on_buttonBox_accepted(); + +signals: + void format_finished(); }; #endif // QHIMDFORMATDIALOG_H diff --git a/qhimdtransfer/qhimdmainwindow.cpp b/qhimdtransfer/qhimdmainwindow.cpp index 359c91e..80fbf76 100644 --- a/qhimdtransfer/qhimdmainwindow.cpp +++ b/qhimdtransfer/qhimdmainwindow.cpp @@ -154,7 +154,7 @@ QString QHiMDMainWindow::dumppcm(const QHiMDTrack & track, QString file) while(himd_nonmp3stream_read_block(&str, &data, &len, NULL, &status) >= 0) { - + for(i = 0; i < len/4; i++) { left = data[i*4]*256+data[i*4+1]; @@ -309,7 +309,7 @@ void QHiMDMainWindow::upload_to(const QString & UploadDirectory) allblocks += tracks[i].blockcount(); uploadDialog->init(tracks.length(), allblocks); - + for(int i = 0;i < tracks.length(); i++) { QString filename, errmsg; @@ -360,7 +360,7 @@ void QHiMDMainWindow::upload_to(const QString & UploadDirectory) QHiMDMainWindow::QHiMDMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::QHiMDMainWindowClass) -{ +{ aboutDialog = new QHiMDAboutDialog; formatDialog = new QHiMDFormatDialog; uploadDialog = new QHiMDUploadDialog; @@ -374,6 +374,7 @@ QHiMDMainWindow::QHiMDMainWindow(QWidget *parent) ui->himd_devices->hide(); if(!autodetect_init()) ui->statusBar->showMessage(" autodetection disabled", 10000); + QObject::connect(formatDialog, SIGNAL(format_finished()), this, SLOT(formatDialog_finished())); } QHiMDMainWindow::~QHiMDMainWindow() @@ -423,7 +424,14 @@ void QHiMDMainWindow::on_action_About_triggered() void QHiMDMainWindow::on_action_Format_triggered() { - formatDialog->show(); + himd_device * dev = detect->find_by_path(ui->himd_devices->currentText()); + if(dev == NULL || dev->scsi_device.isEmpty()) + return; + + emit himd_busy(ui->himd_devices->currentText()); + ui->himd_devices->hide(); + ui->action_Connect->setEnabled(false); + formatDialog->open_scsidevice(dev->scsi_device); } void QHiMDMainWindow::on_action_Connect_triggered() @@ -509,11 +517,13 @@ void QHiMDMainWindow::himd_removed(QString HiMDPath) if(HiMDPath.isEmpty()) return; - if (ui->himdpath->text() == HiMDPath) + if (ui->himd_devices->currentText() == HiMDPath) { ui->himdpath->setText(tr("(disconnected)")); ui->statusBar->clearMessage(); trackmodel.close(); + if(formatDialog->isVisible()) + formatDialog->close(); } index = ui->himd_devices->findText(HiMDPath); @@ -533,3 +543,10 @@ void QHiMDMainWindow::on_himd_devices_activated(QString device) { open_himd_at(device); } + +void QHiMDMainWindow::formatDialog_finished() +{ + ui->himd_devices->show(); + ui->action_Connect->setEnabled(true); + emit himd_idle(ui->himd_devices->currentText()); +} diff --git a/qhimdtransfer/qhimdmainwindow.h b/qhimdtransfer/qhimdmainwindow.h index 694622a..a523610 100644 --- a/qhimdtransfer/qhimdmainwindow.h +++ b/qhimdtransfer/qhimdmainwindow.h @@ -66,6 +66,7 @@ private slots: void himd_found(QString path); void himd_removed(QString path); void on_himd_devices_activated(QString device); + void formatDialog_finished(); signals: void himd_busy(QString path); diff --git a/qhimdtransfer/qhimdwindetection.cpp b/qhimdtransfer/qhimdwindetection.cpp index 1dc437a..d65cf43 100644 --- a/qhimdtransfer/qhimdwindetection.cpp +++ b/qhimdtransfer/qhimdwindetection.cpp @@ -58,7 +58,7 @@ QHiMDDetection * createDetection(QObject * parent) return new QHiMDWinDetection(parent); } -QHiMDWinDetection::QHiMDWinDetection(QObject * parent) +QHiMDWinDetection::QHiMDWinDetection(QObject * parent) : QHiMDDetection(parent), QWidget(0) { // ask for Window ID to have Qt create the window. @@ -222,6 +222,7 @@ void QHiMDWinDetection::add_himddevice(QString path, QString name) new_device->is_busy = false; new_device->path = path; new_device->recorder_name = name; + new_device->scsi_device = "PD" + QString::number(sdn.DeviceNumber); file[0] = path.at(0).toAscii(); if(OpenFile(file, &OFfile, OF_EXIST) != HFILE_ERROR) -- 1.6.4.msysgit.0