123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- /****************************************************************************
- **
- ** Copyright (C) 2013 Jarek Pelczar <jpelczar@gmail.com>
- **
- ** This file is part of Qt Creator.
- **
- ** Commercial License Usage
- ** Licensees holding valid commercial Qt licenses may use this file in
- ** accordance with the commercial license agreement provided with the
- ** Software or, alternatively, in accordance with the terms contained in
- ** a written agreement between you and Digia. For licensing terms and
- ** conditions see http://qt.digia.com/licensing. For further information
- ** use the contact form at http://qt.digia.com/contact-us.
- **
- ** GNU Lesser General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU Lesser
- ** General Public License version 2.1 as published by the Free Software
- ** Foundation and appearing in the file LICENSE.LGPL included in the
- ** packaging of this file. Please review the following information to
- ** ensure the GNU Lesser General Public License version 2.1 requirements
- ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- **
- ** In addition, as a special exception, Digia gives you certain additional
- ** rights. These rights are described in the Digia Qt LGPL Exception
- ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- **
- ****************************************************************************/
- #include "sdbconnector.h"
- #include "sdbconstants.h"
- #include "sdbpacketutils.h"
- #include <QHostAddress>
- #include <QDebug>
- #include <QFileInfo>
- #include <coreplugin/id.h>
- namespace Tizen {
- SdbConnector::SdbConnector(QObject *parent) :
- QObject(parent),
- m_socket(NULL),
- m_sdbProcess(NULL),
- m_state(SdbDisconnected),
- m_sdbPort(DefaultServerPort),
- m_startWait(NULL),
- m_retry(0)
- {
- m_startWait = new QTimer(this);
- connect(m_startWait, SIGNAL(timeout()), SLOT(_q_startWaitTimeout()));
- m_startWait->setInterval(1000);
- m_startWait->setSingleShot(true);
- m_commandResponseTimer = new QTimer(this);
- connect(m_commandResponseTimer, SIGNAL(timeout()), SLOT(_q_commandTimeout()));
- m_commandResponseTimer->setSingleShot(true);
- m_commandResponseTimer->setInterval(500);
- }
- SdbConnector::~SdbConnector()
- {
- }
- int SdbConnector::serverPort() const
- {
- return m_sdbPort;
- }
- void SdbConnector::setServerPort(int port)
- {
- m_sdbPort = port;
- }
- QString SdbConnector::sdbPath() const
- {
- return m_sdbPath;
- }
- void SdbConnector::setSdbPath(const QString& path)
- {
- m_sdbPath = path;
- }
- SdbState SdbConnector::state() const
- {
- return m_state;
- }
- void SdbConnector::startConnector()
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::startConnector] State =" << m_state;
- #endif
- if(m_state == SdbDisconnected || m_state == SdbError) {
- startConnecting();
- } else if(m_state == SdbDisconnecting) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- m_retry = 0;
- startConnecting();
- }
- }
- void SdbConnector::stopConnector()
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::stopConnector] State =" << m_state;
- #endif
- m_commandResponseTimer->stop();
- if(m_state == SdbConnecting) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- m_retry = 0;
- m_state = SdbDisconnected;
- emit stateChanged(SdbDisconnected);
- } else if(m_state == SdbConnected) {
- m_socket->disconnectFromHost();
- } else if(m_state == SdbDisconnecting) {
- } else if(m_state == SdbRestarting) {
- m_startWait->stop();
- m_retry = 0;
- }
- }
- void SdbConnector::startConnecting()
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::startConnecting] Port =" << m_sdbPort;
- #endif
- if(m_state != SdbConnecting) {
- m_state = SdbConnecting;
- emit stateChanged(m_state);
- }
- m_socket = new QTcpSocket(this);
- connect(m_socket, SIGNAL(connected()), SLOT(_q_tcpConnected()));
- connect(m_socket, SIGNAL(readyRead()), SLOT(_q_readyRead()));
- connect(m_socket, SIGNAL(disconnected()), SLOT(_q_tcpDisconnected()));
- connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(_q_socketError(QAbstractSocket::SocketError)));
- m_socket->connectToHost(QHostAddress::LocalHost, m_sdbPort);
- m_commandResponseTimer->start(1000);
- }
- void SdbConnector::_q_tcpConnected()
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::_q_tcpConnected] Local port =" << m_socket->localPort();
- #endif
- m_commandResponseTimer->stop();
- m_state = SdbConnected;
- m_protoState = WaitingForDeviceListResp;
- m_socket->write(Tizen::SdbPacketUtils::makeRequest(QByteArray("host:track-devices")));
- m_commandResponseTimer->start();
- emit stateChanged(SdbConnected);
- }
- void SdbConnector::_q_readyRead()
- {
- while(!m_socket->atEnd()) {
- if(m_protoState == WaitingForDeviceListResp) {
- SdbResponse resp;
- if(SdbPacketUtils::parseResponse(m_socket, false, resp)) {
- m_commandResponseTimer->stop();
- m_protoState = WaitingForDeviceListHeader;
- if(!resp.okay) {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector] Failed to query device list";
- #endif
- }
- }
- }
- if(m_protoState == WaitingForDeviceListHeader) {
- if(m_socket->bytesAvailable() >= 4) {
- char hdr[5];
- if(m_socket->read(hdr, 4) != 4)
- return;
- hdr[4] = 0;
- sscanf(hdr, "%X", &m_packetLength);
- if(m_packetLength > 0)
- m_protoState = WaitingForDeviceListData;
- else
- continue;
- } else {
- return;
- }
- }
- if(m_protoState == WaitingForDeviceListData) {
- if(m_socket->bytesAvailable() >= m_packetLength) {
- SdbDeviceList deviceList;
- m_protoState = WaitingForDeviceListHeader;
- QByteArray string = m_socket->read(m_packetLength);
- QList<QByteArray> lines = string.split('\n');
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector]: received list update" << string;
- #endif
- if(!lines.empty())
- deviceList.reserve(lines.size());
- foreach(const QByteArray& line, lines) {
- QList<QByteArray> params = line.split('\t');
- if(params.length() == 3) {
- SdbDevice device;
- device.serialNumber = params.at(0).trimmed();
- device.name = QString::fromUtf8(params.at(2));
- QByteArray deviceState = params.at(1);
- if(deviceState == "offline") {
- device.state = SdbDevice::Offline;
- } else if(deviceState == "device") {
- device.state = SdbDevice::Device;
- } else {
- device.state = SdbDevice::Unknown;
- }
- deviceList.append(device);
- }
- }
- emit deviceListUpdated(deviceList);
- } else
- return;
- }
- }
- }
- void SdbConnector::_q_tcpDisconnected()
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::_q_tcpDisconnected]";
- #endif
- m_commandResponseTimer->stop();
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- m_retry = 0;
- m_state = SdbDisconnected;
- emit stateChanged(SdbDisconnected);
- }
- void SdbConnector::_q_socketError(QAbstractSocket::SocketError error)
- {
- Q_UNUSED(error);
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::_q_socketError] Error =" << error << "and error string =" << m_socket->errorString();
- #endif
- m_commandResponseTimer->stop();
- if(m_state == SdbConnecting) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- QFileInfo fi(m_sdbPath);
- if(!fi.exists() || m_retry > 0) {
- #ifdef QT_DEBUG
- qWarning() << "SDB path not found";
- #endif
- m_state = SdbError;
- m_retry = 0;
- emit stateChanged(SdbError);
- return;
- }
- m_state = SdbRestarting;
- m_sdbProcess = new QProcess(this);
- connect(m_sdbProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(_q_finished(int,QProcess::ExitStatus)));
- m_sdbProcess->start(m_sdbPath, QStringList() << QLatin1String("start-server"));
- emit stateChanged(SdbRestarting);
- } else if(m_state == SdbConnected) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- m_state = SdbDisconnected;
- m_retry = 0;
- emit stateChanged(SdbDisconnected);
- }
- }
- void SdbConnector::_q_finished(int exitCode, QProcess::ExitStatus exitStatus)
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::_q_finished] Exit code =" << exitCode << "Status =" << exitStatus <<
- "Error =" << m_sdbProcess->errorString();
- #endif
- m_sdbProcess->deleteLater();
- m_sdbProcess = NULL;
- if(exitStatus == QProcess::NormalExit && exitCode == 0) {
- m_startWait->start();
- } else {
- m_state = SdbError;
- m_retry = 0;
- emit stateChanged(SdbError);
- }
- }
- void SdbConnector::_q_startWaitTimeout()
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector::_q_startWaitTimeout]";
- #endif
- ++m_retry;
- startConnecting();
- }
- QTcpSocket * SdbConnector::createChannel(QObject *parent)
- {
- if(m_state != SdbConnected)
- return NULL;
- QTcpSocket * socket = new QTcpSocket(parent);
- socket->connectToHost(QHostAddress::LocalHost, m_sdbPort);
- return socket;
- }
- void SdbConnector::_q_commandTimeout()
- {
- #ifdef QT_DEBUG
- qDebug() << "[SdbConnector] Command timeout in state" << m_state;
- #endif
- if(m_state == SdbConnecting) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- QFileInfo fi(m_sdbPath);
- if(!fi.exists() || m_retry > 0) {
- #ifdef QT_DEBUG
- qWarning() << "SDB path not found";
- #endif
- m_state = SdbError;
- m_retry = 0;
- emit stateChanged(SdbError);
- return;
- }
- #ifdef QT_DEBUG
- qDebug() << "Try starting SDB";
- #endif
- m_state = SdbRestarting;
- m_sdbProcess = new QProcess(this);
- connect(m_sdbProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(_q_finished(int,QProcess::ExitStatus)));
- m_sdbProcess->start(m_sdbPath, QStringList() << QLatin1String("start-server"));
- emit stateChanged(SdbRestarting);
- } else if(m_state == SdbConnected) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- m_state = SdbError;
- m_retry = 0;
- emit stateChanged(SdbError);
- }
- }
- }
|