OSDN Git Service

alpha 1 development in progress.
authortkawata <tkawata@users.sourceforge.jp>
Fri, 20 Apr 2012 14:03:19 +0000 (23:03 +0900)
committertkawata <tkawata@users.sourceforge.jp>
Fri, 20 Apr 2012 14:03:19 +0000 (23:03 +0900)
Serial port communication feature under development.

Source/DNEngine.cpp
Source/DNThread.h
Source/DNUtils.cpp
Source/DNUtils.h
Source/QtDennco/mainwindow.cpp
Source/QtDennco/mainwindow.h
Source/QtDennco/portinfodialog.ui
Source/Source.pro
Source/platform/qt/qtdnserialportimpl.cpp
Source/platform/qt/qtdnserialportimpl.h

index 9f6babb..b979008 100644 (file)
@@ -107,18 +107,22 @@ DNEngine::~DNEngine()
 {
     mValid = false;
     
+    if (mHTTPServer)
+    {
+        stopHTTPServer();
+    }
+
+    if (mSerialServer)
+    {
+        stopSerialServer();
+    }
+
     if (mContainer)
     {
         delete mContainer;
         mContainer = NULL;
     }
-        
-    if (mHTTPServer)
-    {
-        delete mHTTPServer;
-        mHTTPServer = NULL;
-    }
-    
+            
     if (mTimeKeeper)
     {
         delete mTimeKeeper;
@@ -208,7 +212,14 @@ bool DNEngine::parseSettingFile(const char *contentRoot)
                 }
                 else if (e->name == "EnableSerialServer")
                 {
-
+                    if ( upperString(e->text) == "YES")
+                    {
+                        startSerialServer();
+                    }
+                    else
+                    {
+                        stopSerialServer();
+                    }
                 }
                 e = e->next;
             }
@@ -245,7 +256,7 @@ bool DNEngine::startHTTPServer(int portNumber)
 
 void DNEngine::stopHTTPServer()
 {
-    if (mHTTPServer && mHTTPServer->isRunning())
+    if (mHTTPServer)
     {
         mHTTPServer->stop();
         delete mHTTPServer;
@@ -255,12 +266,7 @@ void DNEngine::stopHTTPServer()
 
 bool DNEngine::startSerialServer()
 {
-    if (mSerialServer && mSerialServer->isRunning())
-    {
-        mSerialServer->stop();
-        delete mSerialServer;
-        mSerialServer = NULL;
-    }
+    stopSerialServer();
     mSerialServer = new DNServerSerialPort(this);
     if (mSerialServer)
     {
@@ -279,7 +285,7 @@ bool DNEngine::startSerialServer()
 
 void DNEngine::stopSerialServer()
 {
-    if (mSerialServer && mSerialServer->isRunning())
+    if (mSerialServer)
     {
         mSerialServer->stop();
         delete mSerialServer;
@@ -317,6 +323,9 @@ bool DNEngine::stopEngine()
         mContainer->releaseDataStore();
     }
 
+    if (mSerialServer)
+        mSerialServer->stop();
+
     return r;
 }
 
index 58b166f..643e8ae 100644 (file)
@@ -29,7 +29,7 @@ public:
     DNThread(DNThreadImpl *impl);
     ~DNThread();
 
-    bool   waitForExit(int timeout);
+    bool   waitForExit(int timeout_ms);
     bool   start();
 
     static DNThread*    createThread(DNThreadFunc threadFunc, void *data);
index 5145303..f760ae0 100644 (file)
@@ -26,6 +26,8 @@
     #include <stdlib.h>
 #endif
 
+#include <algorithm>
+
 void trimString(std::string& str)
 {
     std::string::size_type pos1 = str.find_first_not_of(' ');
@@ -39,6 +41,15 @@ void trimString(std::string& str)
     str = str.substr(pos1 == std::string::npos ? 0 : pos1, 
                      pos2 == std::string::npos ? str.length() - 1 : pos2 - pos1 + 1);
 }
+
+std::string upperString( const std::string &src )
+{
+    std::string data = src;
+    std::transform(data.begin(), data.end(), data.begin(), ::toupper);
+
+    return data;
+}
+
 std::string parseCellCodeForScriptEngine(std::string jname, std::string cellCode)
 {
 #ifdef DEBUG
index 1a40b36..9394c3e 100644 (file)
@@ -24,6 +24,7 @@
 #include "TKLock.h"
 
 void trimString(std::string& str);
+std::string upperString( const std::string &src );
 
 std::string getFQNString(const char *location, const char *name);
 std::string getJSEscapeString(const char *cstring);
index f112f97..28e5420 100644 (file)
 #include "TKConsole.h"
 #include "dnwebinterface.h"
 
+//static
+QWidget *MainWindow::instance = NULL;
+
 MainWindow::MainWindow(QWidget *parent) :
     QMainWindow(parent),
     ui(new Ui::MainWindow),
     mEngine(NULL), mWebInterface(NULL),
     mHasPendingConsoleMessage(false)
 {
+    instance = this;
     ui->setupUi(this);
 
     QSettings settings("dennco project", "dennco engine");
@@ -56,6 +60,7 @@ MainWindow::MainWindow(QWidget *parent) :
 
 MainWindow::~MainWindow()
 {
+    instance = 0;
     delete ui;
 }
 
index 132acdb..a2e2757 100644 (file)
@@ -40,6 +40,8 @@ public:
     explicit MainWindow(QWidget *parent = 0);
     ~MainWindow();
 
+    static QWidget *instance;
+
 protected:
     virtual void closeEvent(QCloseEvent *event);
     virtual void paintEvent(QPaintEvent *event );
index abe58ec..11a47cd 100644 (file)
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>Dialog</class>
- <widget class="QDialog" name="Dialog">
+ <class>QtDNSerialPortSettingDialog</class>
+ <widget class="QDialog" name="QtDNSerialPortSettingDialog">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>293</width>
+    <width>295</width>
     <height>255</height>
    </rect>
   </property>
index ed287e7..5b4327b 100644 (file)
@@ -10,7 +10,7 @@ TARGET = QtDennco
 TEMPLATE = app
 
 
-INCLUDEPATH += QtScript platform/qt ../Thirdparty/serialport/include
+INCLUDEPATH += QtScript QtDennco platform/qt ../Thirdparty/serialport/include
 
 SOURCES += QtDennco/mainwindow.cpp \
     QtDennco/main.cpp \
@@ -124,3 +124,11 @@ FORMS    += QtDennco/mainwindow.ui
 FORMS    += QtDennco/portinfodialog.ui
 
 Debug:DEFINES+=DEBUG
+
+Debug{
+    LIBS += -L"../Thirdparty/serialport/src/debug" -lSerialPort
+}
+
+Release{
+    LIBS += -L"../Thirdparty/serialport/src/release" -lSerialPort
+}
index e9357ed..9f4a0a0 100644 (file)
 //
 #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
 {
@@ -39,9 +44,14 @@ DNSerialPortImpl * DNSerialPortImpl::create(DNServerSerialPort *server)
 
 
 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()
@@ -57,41 +67,67 @@ 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
@@ -101,28 +137,128 @@ void QtDNSerialPortImpl::requestListenerThreadBody(void *_impl)
         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
@@ -142,6 +278,7 @@ void QtDNSerialPortImpl::requestHandelrThreadBody(void *_impl)
             impl->mLock.unlock();
 
             //TODO
+            TKLog::printf("serial input:%s", line.toLocal8Bit().constData());
 
         }
         else
@@ -150,7 +287,102 @@ void QtDNSerialPortImpl::requestHandelrThreadBody(void *_impl)
         }
 
     }
+}
+
+
+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));
+        }
+    }
+}
index 4063f0e..cff1f99 100644 (file)
 #include "DNSerialPortImpl.h"
 
 #include "TKLock.h"
+#include "ui_portinfodialog.h"
 
 #include <serialport.h>
+#include <serialportinfo.h>
 #include <QString>
 #include <QQueue>
 #include <QSemaphore>
+#include <QDialog>
 
 class DNServerSerialPort;
 class DNThread;
 
+namespace Ui {
+    class QtDNSerialPortSettingDialog;
+}
+
+class QtDNSerialPortSettingDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit QtDNSerialPortSettingDialog(QWidget *parent = 0);
+    ~QtDNSerialPortSettingDialog();
+
+    QString getSelectedPortName();
+    int     getSelectedRate();
+
+private slots:
+    void procUpdateAvailablePorts();
+    void procItemPortChanged(int idx);
+    void procBusyButtonClick();
+    void procValidButtonClick();
+    void procRatesButtonClick();
+
+private:
+    Ui::QtDNSerialPortSettingDialog *ui;
+};
+
 class QtDNSerialPortImpl : public DNSerialPortImpl
 {
 public:
@@ -49,12 +78,20 @@ public:
 private:
     DNThread *mListnerThread;
     DNThread *mHandlerThread;
-    SerialPort *mPort;
     bool    mStopping;
 
     QQueue<QString> mRequestQueue;
     TKLock          mLock;
+    TKLock          mStartStopLock;
     QSemaphore      mQueueSemaphore;
+
+    QString mPortName;
+    SerialPort::Rate mBaudRate;
+    SerialPort::DataBits mDataBits;
+    SerialPort::Parity mParity;
+    SerialPort::StopBits mStopBits;
+    SerialPort::FlowControl mFlowControl;
+
 };
 
 #endif // QTDNSERIALPORTIMPL_H