123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /****************************************************************************
- **
- ** 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 "sdbcommandexecutor.h"
- #include "sdbconnector.h"
- #include "sdbpacketutils.h"
- #include <utils/qtcassert.h>
- #include <QDebug>
- namespace Tizen {
- SdbCommandExecutor::SdbCommandExecutor(SdbConnector * connector, QObject *parent) :
- QIODevice(parent),
- m_connector(connector),
- m_socket(NULL),
- m_state(Disconnected)
- {
- }
- SdbCommandExecutor::~SdbCommandExecutor()
- {
- if(m_socket) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- }
- }
- bool SdbCommandExecutor::atEnd() const
- {
- return QIODevice::atEnd() && m_buffer.isEmpty();
- }
- qint64 SdbCommandExecutor::bytesAvailable() const
- {
- return QIODevice::bytesAvailable() + m_buffer.size();
- }
- bool SdbCommandExecutor::canReadLine() const
- {
- return QIODevice::canReadLine() || m_buffer.contains('\n');
- }
- void SdbCommandExecutor::close()
- {
- if(m_state == Disconnected)
- return;
- if(m_state == Disconnecting)
- return;
- if(m_state == Connecting) {
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- return;
- }
- m_state = Disconnecting;
- m_socket->disconnectFromHost();
- QIODevice::close();
- }
- bool SdbCommandExecutor::isSequential() const
- {
- return true;
- }
- void SdbCommandExecutor::start(const QString &deviceId, const QString& command)
- {
- QTC_ASSERT(m_state == Disconnected, return);
- #ifdef QT_DEBUG
- qDebug() << this << ": Execute command" << command << "on device" << deviceId;
- #endif
- m_state = Connecting;
- m_command = command;
- m_deviceId = deviceId;
- m_socket = m_connector->createChannel(this);
- if(!m_socket) {
- setErrorString(tr("Can't create SDB socket"));
- emit failed();
- return;
- }
- connect(m_socket, SIGNAL(connected()), SLOT(socketConnected()));
- connect(m_socket, SIGNAL(disconnected()), SLOT(socketDisconnected()));
- connect(m_socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
- connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(socketError(QAbstractSocket::SocketError)));
- connect(m_socket, SIGNAL(readChannelFinished()), SIGNAL(readChannelFinished()));
- connect(m_socket, SIGNAL(aboutToClose()), SIGNAL(aboutToClose()));
- }
- qint64 SdbCommandExecutor::readData(char *data, qint64 maxlen)
- {
- const qint64 bytesRead = qMin(qint64(m_buffer.size()), maxlen);
- memcpy(data, m_buffer.constData(), bytesRead);
- m_buffer.remove(0, bytesRead);
- return bytesRead;
- }
- qint64 SdbCommandExecutor::writeData(const char *data, qint64 len)
- {
- if(m_state == Running) {
- return m_socket->write(data, len);
- }
- return 0;
- }
- void SdbCommandExecutor::socketReadyRead()
- {
- if(m_state == Running) {
- QByteArray chunk = m_socket->readAll();
- //#ifdef QT_DEBUG
- // qDebug() << this << "Read:" << chunk;
- //#endif
- m_buffer.append(chunk);
- emit readyRead();
- } else if(m_state == WaitForInitResponse) {
- m_cmdBuffer.append(m_socket->readAll());
- Tizen::SdbResponse resp;
- if(Tizen::SdbPacketUtils::parseResponse(m_cmdBuffer, false, resp)) {
- m_cmdBuffer.remove(0, resp.length_read);
- if(!resp.okay) {
- #ifdef QT_DEBUG
- qDebug() << this << ": Device selection failure: " << resp.message;
- #endif
- m_state = Disconnecting;
- m_socket->disconnectFromHost();
- setErrorString(resp.message);
- emit failed();
- return;
- }
- #ifdef QT_DEBUG
- qDebug() << this << ": Device selected for command. Request shell command";
- #endif
- m_socket->write(Tizen::SdbPacketUtils::makeRequest(QByteArray("shell:") + m_command.toUtf8()));
- m_state = WaitForExecResponse;
- }
- } else if(m_state == WaitForExecResponse) {
- m_cmdBuffer.append(m_socket->readAll());
- Tizen::SdbResponse resp;
- if(Tizen::SdbPacketUtils::parseResponse(m_cmdBuffer, false, resp)) {
- #ifdef QT_DEBUG
- #endif
- m_cmdBuffer.remove(0, resp.length_read);
- if(!resp.okay) {
- #ifdef QT_DEBUG
- qDebug() << this << ": Command exec failure: " << resp.message;
- #endif
- m_state = Disconnecting;
- disconnect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
- m_socket->disconnectFromHost();
- setErrorString(resp.message);
- emit failed();
- return;
- }
- open(QIODevice::ReadWrite);
- #ifdef QT_DEBUG
- qDebug() << this << ": Command started";
- #endif
- m_state = Running;
- emit started();
- qSwap(m_buffer, m_cmdBuffer);
- if(!m_buffer.isEmpty()) {
- //#ifdef QT_DEBUG
- // qDebug() << "Buffer is" << m_buffer;
- //#endif
- emit readyRead();
- }
- }
- }
- }
- void SdbCommandExecutor::socketConnected()
- {
- m_state = WaitForInitResponse;
- m_socket->write(Tizen::SdbPacketUtils::makeInitializeDeviceMessage(m_deviceId));
- #ifdef QT_DEBUG
- qDebug() << this << ": Socket connected. Wait for device selection";
- #endif
- }
- void SdbCommandExecutor::socketDisconnected()
- {
- #ifdef QT_DEBUG
- qDebug() << this << ": Socket disconnected in state" << m_state;
- #endif
- if(m_state == Disconnecting) {
- m_state = Disconnected;
- emit finished();
- }
- }
- void SdbCommandExecutor::socketError(QAbstractSocket::SocketError error)
- {
- #ifdef QT_DEBUG
- qDebug() << this << ": Socket error" << m_socket->errorString() << "in state" << m_state << ", " << m_buffer.size() << "bytes left in buffer";
- #endif
- if(m_state == Running) {
- if(error == QAbstractSocket::RemoteHostClosedError) {
- m_state = Disconnected;
- emit finished();
- return;
- }
- }
- setErrorString(m_socket->errorString());
- m_socket->disconnect(this);
- m_socket->deleteLater();
- m_socket = NULL;
- if(isOpen())
- QIODevice::close();
- m_state = Disconnected;
- emit failed();
- }
- } // namespace Tizen
|