//
#include "qtdnserialportimpl.h"
+#include "ui_portinfodialog.h"
#include "DNServerSerialPort.h"
#include "DNThread.h"
+#include "mainwindow.h"
+#include "TKLog.h"
#include "DNUtils.h"
+
#include <QThread>
+#include <QtCore/QVariant>
class SleeperThread : public QThread
{
QtDNSerialPortImpl::QtDNSerialPortImpl(DNServerSerialPort *server) :
- DNSerialPortImpl(server), mListnerThread(NULL), mHandlerThread(NULL), mPort(NULL), mStopping(false)
+ DNSerialPortImpl(server), mListnerThread(NULL), mHandlerThread(NULL), mStopping(false),
+ mPortName(""),
+ mBaudRate(SerialPort::Rate9600),
+ mDataBits(SerialPort::Data8),
+ mParity(SerialPort::NoParity),
+ mStopBits(SerialPort::OneStop),
+ mFlowControl(SerialPort::NoFlowControl)
{
-
}
QtDNSerialPortImpl::~QtDNSerialPortImpl()
delete mHandlerThread;
mHandlerThread = NULL;
}
- if (mPort)
- {
- delete mPort;
- mPort = NULL;
- }
}
bool QtDNSerialPortImpl::setup()
{
//TODO
- return false;
+ if (!MainWindow::instance)
+ return false;
+
+ QtDNSerialPortSettingDialog dialog(MainWindow::instance);
+ dialog.exec();
+
+ mPortName = dialog.getSelectedPortName();
+ mBaudRate = (SerialPort::Rate) dialog.getSelectedRate();
+
+ return true;
+
}
bool QtDNSerialPortImpl::isRunning()
{
- //TODO
- return false;
+ DNLocker lock(&mStartStopLock);
+ return !mStopping;
}
void QtDNSerialPortImpl::start()
{
stop();
- if (!mListnerThread)
+ mStartStopLock.lock();
+ if (mStopping)
+ {
+ mStopping = false;
mListnerThread = DNThread::createThread(QtDNSerialPortImpl::requestListenerThreadBody, this);
-
- if (!mHandlerThread)
mHandlerThread = DNThread::createThread(QtDNSerialPortImpl::requestHandelrThreadBody, this);
- mListnerThread->start();
- mHandlerThread->start();
+ mListnerThread->start();
+ mHandlerThread->start();
+ }
+ mStartStopLock.unlock();
}
void QtDNSerialPortImpl::stop()
{
-
+ mStartStopLock.lock();
+ if (!mStopping)
+ {
+ mStopping = true;
+ if (mListnerThread)
+ {
+ mListnerThread->waitForExit(1000);
+ delete mListnerThread;
+ mListnerThread = NULL;
+ }
+ if (mHandlerThread)
+ {
+ mHandlerThread->waitForExit(1000);
+ delete mHandlerThread;
+ mHandlerThread = NULL;
+ }
+ mRequestQueue.clear();
+ }
+ mStartStopLock.unlock();
}
//static
return;
QtDNSerialPortImpl *impl = (QtDNSerialPortImpl*)_impl;
+
+ if (impl->mPortName.length()==0 || impl->mBaudRate == 0)
+ {
+ impl->mStartStopLock.lock();
+ impl->mStopping = true;
+ impl->mStartStopLock.unlock();
+ return;
+ }
+
+ SerialPort *port = new SerialPort(impl->mPortName);
+ if (port == NULL)
+ {
+ impl->mStartStopLock.lock();
+ impl->mStopping = true;
+ impl->mStartStopLock.unlock();
+ return;
+ }
+
+ bool r = port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
+ if (r)
+ {
+ if (!port->setRate(impl->mBaudRate))
+ {
+ r = false;
+ }
+ }
+ if (r)
+ {
+ if (!port->setDataBits(impl->mDataBits))
+ {
+ r = false;
+ }
+ }
+ if (r)
+ {
+ if (!port->setParity(impl->mParity))
+ {
+ r = false;
+ }
+ }
+ if (r)
+ {
+ if (!port->setStopBits(impl->mStopBits))
+ {
+ r = false;
+ }
+ }
+ if (r)
+ {
+ if (!port->setFlowControl(impl->mFlowControl))
+ {
+ r = false;
+ }
+ }
+
+ if (!r)
+ {
+ if (port)
+ delete port;
+
+ impl->mStartStopLock.lock();
+ impl->mStopping = true;
+ impl->mStartStopLock.unlock();
+ return;
+ }
+
+
char buffer[1024];
+ int p = 0;
while(!impl->mStopping)
{
- if ((impl->mPort->bytesAvailable() > 0) || impl->mPort->waitForReadyRead(100))
+ if (port->bytesAvailable() > 0 || port->waitForReadyRead(100))
{
- int len = impl->mPort->readLine(buffer, sizeof(buffer));
+ int len = port->read( (buffer + p), sizeof(buffer) - p);
if (len != -1)
{
- impl->mLock.lock();
- impl->mRequestQueue.push_back(QString::fromLocal8Bit(buffer));
- if (impl->mQueueSemaphore.available()==0)
+ int i = p;
+ while (i < p + len)
{
- impl->mQueueSemaphore.release(1);
+ if (buffer[i] == '\r' || buffer[i] == '\n' || i == sizeof(buffer)-1)
+ {
+ if (i>0)
+ {
+ buffer[i] = 0;
+ impl->mLock.lock();
+ impl->mRequestQueue.push_back(QString::fromLocal8Bit(buffer));
+ impl->mLock.unlock();
+ impl->mQueueSemaphore.release(1);
+ }
+ int j = i + 1;
+ while(j < p + len)
+ {
+ if (buffer[j]!='\r' && buffer[j]!='\n')
+ {
+ break;
+ }
+ j++;
+ }
+ int d = 0;
+ while (j < p + len)
+ {
+ buffer[d] = buffer[j];
+ d++;
+ j++;
+ }
+ p = 0;
+ i = 0;
+ len = d;
+ continue;
+ }
+ i++;
}
- impl->mLock.unlock();
+ p = p + len;
}
}
- if (!impl->mPort->isOpen())
+ if (!port->isOpen())
{
SleeperThread::msleep(300);
}
}
+ port->close();
+ delete port;
}
//static
impl->mLock.unlock();
//TODO
+ TKLog::printf("serial input:%s", line.toLocal8Bit().constData());
}
else
}
}
+}
+
+
+Q_DECLARE_METATYPE(SerialPortInfo)
+
+QtDNSerialPortSettingDialog::QtDNSerialPortSettingDialog(QWidget *parent)
+ : QDialog(parent)
+ , ui(new Ui::QtDNSerialPortSettingDialog)
+{
+ ui->setupUi(this);
+ procUpdateAvailablePorts();
+ procItemPortChanged(0);
+
+ connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(procUpdateAvailablePorts()));
+ connect(ui->portsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(procItemPortChanged(int)));
+ connect(ui->busyButton, SIGNAL(clicked()), this, SLOT(procBusyButtonClick()));
+ connect(ui->validButton, SIGNAL(clicked()), this, SLOT(procValidButtonClick()));
+ connect(ui->ratesButton, SIGNAL(clicked()), this, SLOT(procRatesButtonClick()));
+}
+
+QtDNSerialPortSettingDialog::~QtDNSerialPortSettingDialog()
+{
+ delete ui;
+}
+
+QString QtDNSerialPortSettingDialog::getSelectedPortName()
+{
+ return ui->portsComboBox->currentText();
+}
+
+int QtDNSerialPortSettingDialog::getSelectedRate()
+{
+ return ui->ratesComboBox->currentText().toInt();
+}
+
+void QtDNSerialPortSettingDialog::procUpdateAvailablePorts()
+{
+ ui->portsComboBox->clear();
+ foreach (SerialPortInfo info, SerialPortInfo::availablePorts()) {
+ QVariant v;
+ v.setValue(info);
+ ui->portsComboBox->addItem(info.portName(), v);
+ }
+}
+
+void QtDNSerialPortSettingDialog::procItemPortChanged(int idx)
+{
+ QVariant v = ui->portsComboBox->itemData(idx);
+ if (v.isValid()) {
+ SerialPortInfo info = v.value<SerialPortInfo>();
+ ui->locationValueLabel->setText(info.systemLocation());
+ ui->descriptionValueLabel->setText(info.description());
+ ui->manufacturerValueLabel->setText(info.manufacturer());
+ ui->busyLabel->setText("***");
+ ui->validLabel->setText("***");
+ ui->ratesComboBox->clear();
+ }
}
+void QtDNSerialPortSettingDialog::procBusyButtonClick()
+{
+ int idx = ui->portsComboBox->currentIndex();
+ if (idx >= 0) {
+ QVariant v = ui->portsComboBox->itemData(idx);
+ if (v.isValid()) {
+ SerialPortInfo info = v.value<SerialPortInfo>();
+ ui->busyLabel->setText(info.isBusy() ? tr("Busy") : tr("Free"));
+ }
+ }
+}
+
+void QtDNSerialPortSettingDialog::procValidButtonClick()
+{
+ int idx = ui->portsComboBox->currentIndex();
+ if (idx >= 0) {
+ QVariant v = ui->portsComboBox->itemData(idx);
+ if (v.isValid()) {
+ SerialPortInfo info = v.value<SerialPortInfo>();
+ ui->validLabel->setText(info.isValid() ? tr("Valid") : tr("Invalid"));
+ }
+ }
+}
+
+void QtDNSerialPortSettingDialog::procRatesButtonClick()
+{
+ ui->ratesComboBox->clear();
+ int idx = ui->portsComboBox->currentIndex();
+ if (idx >= 0) {
+ QVariant v = ui->portsComboBox->itemData(idx);
+ if (v.isValid()) {
+ SerialPortInfo info = v.value<SerialPortInfo>();
+
+ foreach (qint32 rate, info.standardRates())
+ ui->ratesComboBox->addItem(QString::number(rate));
+ }
+ }
+}