diff options
| author | Manjeet Dahiya <manjeetdahiya@gmail.com> | 2009-10-27 12:04:03 +0000 |
|---|---|---|
| committer | Manjeet Dahiya <manjeetdahiya@gmail.com> | 2009-10-27 12:04:03 +0000 |
| commit | 10c093a617929db5c6b201dbf03d6070b12b36b4 (patch) | |
| tree | d9b1c4507fdb1969c3225f27b4632258c4916dc0 /source/QXmppIbbTransferJob.cpp | |
| parent | 239b2b15c3cfd9e4d7cc085ed31645d6ae6942ee (diff) | |
| download | qxmpp-10c093a617929db5c6b201dbf03d6070b12b36b4.tar.gz | |
Issue 15: Implement XEP-0047
Diffstat (limited to 'source/QXmppIbbTransferJob.cpp')
| -rw-r--r-- | source/QXmppIbbTransferJob.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/source/QXmppIbbTransferJob.cpp b/source/QXmppIbbTransferJob.cpp new file mode 100644 index 00000000..4835596a --- /dev/null +++ b/source/QXmppIbbTransferJob.cpp @@ -0,0 +1,230 @@ +#include "QXmppIbbTransferJob.h"
+
+#include <QIODevice>
+#include <QUuid>
+#include "QXmppIbbIqs.h"
+#include "QXmppDataIq.h"
+#include "QXmppClient.h"
+#include "QXmppUtils.h"
+
+QXmppIbbTransferJob::QXmppIbbTransferJob( QXmppClient *parent )
+ : QObject (parent ), m_client(parent), m_io(0), m_blockSize(4096),
+ m_streamBlockSize(0), m_sequence(0), m_state(Idle)
+{
+ m_localJid = parent->getConfiguration().getJid();
+ m_id = generateStanzaHash();
+ m_sid = generateStanzaHash();
+}
+
+QXmppIbbTransferJob::~QXmppIbbTransferJob()
+{
+}
+
+QString QXmppIbbTransferJob::getSid() const
+{
+ return m_sid;
+}
+
+void QXmppIbbTransferJob::setSid( const QString &sid )
+{
+ m_sid = sid;
+}
+
+void QXmppIbbTransferJob::setRemoteJid( const QString &jid )
+{
+ m_remoteJid = jid;
+}
+
+QString QXmppIbbTransferJob::getRemoteJid( ) const
+{
+ return m_remoteJid;
+}
+
+QString QXmppIbbTransferJob::getId() const
+{
+ return m_id;
+}
+
+void QXmppIbbTransferJob::setId( const QString &id )
+{
+ m_id = id;
+}
+
+
+void QXmppIbbTransferJob::requestTransfer( )
+{
+ m_state = Requesting;
+ QXmppIbbOpenIq request;
+ request.setBlockSize(m_blockSize);
+ request.setTo( m_remoteJid );
+ request.setFrom( m_localJid );
+ request.setSid( m_sid );
+ request.generateAndSetNextId();
+ m_id = request.getId();
+
+ m_client->sendPacket( request );
+
+}
+
+void QXmppIbbTransferJob::acceptTransfer( )
+{
+ if( m_state != Pending )
+ {
+ return;
+ }
+
+ m_state = TransferringIn;
+ QXmppIbbAckIq ack;
+ ack.setTo( m_remoteJid );
+ ack.setFrom( m_localJid );
+ ack.setId( m_id );
+ m_client->sendPacket( ack );
+ emit transferStarted(m_sid);
+}
+
+void QXmppIbbTransferJob::cancelTransfer( )
+{
+ QXmppIbbErrorIq cancel;
+ cancel.setId(m_id);
+ cancel.setErrorType( QXmppIbbErrorIq::Cancel );
+ m_client->sendPacket( cancel );
+}
+
+void QXmppIbbTransferJob::setIoDevice( QIODevice *io )
+{
+ m_io = io;
+}
+
+void QXmppIbbTransferJob::setBlockSize( long size)
+{
+ m_blockSize = size;
+}
+
+void QXmppIbbTransferJob::gotAck()
+{
+ if( m_state == Requesting )
+ {
+ // start transfer
+ m_state = TransferringOut;
+ sendNextBlock();
+ }
+ else if ( m_state == TransferringOut )
+ {
+ // send next packet
+ sendNextBlock();
+ }
+ else if ( m_state == Idle )
+ {
+ emit readyForTeardown(m_sid);
+ }
+ else
+ {
+
+ }
+}
+
+void QXmppIbbTransferJob::gotOpen( const QXmppIbbOpenIq &open )
+{
+ m_sid = open.getSid();
+ m_id = open.getId();
+ m_remoteJid = open.getFrom();
+ if( open.getBlockSize() > m_blockSize )
+ {
+ // cancel
+ m_state = Idle;
+ QXmppIbbErrorIq modifyError;
+ modifyError.setId(m_id);
+ modifyError.setErrorType( QXmppIbbErrorIq::Modify );
+ m_client->sendPacket( modifyError );
+ emit readyForTeardown(m_sid);
+ }
+ else
+ {
+ m_streamBlockSize = open.getBlockSize();
+ m_state = Pending;
+ emit transferRequested( m_sid , m_remoteJid );
+ }
+}
+
+void QXmppIbbTransferJob::gotClose( const QXmppIbbCloseIq &close )
+{
+ m_state = Idle;
+ QXmppIbbAckIq ack;
+ ack.setTo( m_remoteJid );
+ ack.setFrom( m_localJid );
+ ack.setId( m_id );
+ m_client->sendPacket( ack );
+ emit transferFinished(m_sid, "Closed");
+ emit readyForTeardown(m_sid);
+}
+
+void QXmppIbbTransferJob::gotError( const QXmppIbbErrorIq &err )
+{
+ m_state = Idle;
+ emit transferCanceled(m_sid,err.getError().getConditionStr());
+ emit readyForTeardown(m_sid);
+}
+void QXmppIbbTransferJob::gotData( const QXmppDataIq &data )
+{
+ if( m_io &&
+ (data.getSequence() == 0 || data.getSequence() > m_sequence) )
+ {
+ m_io->write( data.getPayload() );
+ m_sequence = data.getSequence();
+ QXmppIbbAckIq ack;
+ ack.setId(m_id);
+ ack.setTo(m_remoteJid);
+ ack.setFrom(m_localJid);
+ m_client->sendPacket( ack );
+ }
+ else
+ {
+ QXmppIbbErrorIq error;
+ error.setId(m_id);
+ error.setTo(m_remoteJid);
+ error.setFrom(m_localJid);
+ error.setErrorType(QXmppIbbErrorIq::Cancel);
+ m_client->sendPacket( error );
+ }
+}
+
+void QXmppIbbTransferJob::sendNextBlock()
+{
+
+ if( m_io == 0 || !m_io->isReadable() )
+ {
+ QXmppIbbErrorIq error;
+ error.setId(m_id);
+ error.setTo(m_remoteJid);
+ error.setFrom(m_localJid);
+ error.setErrorType(QXmppIbbErrorIq::Cancel);
+ m_client->sendPacket( error );
+ }
+ else if( m_io->atEnd() || !m_io->isOpen() )
+ {
+ QXmppIbbCloseIq close;
+ close.setId(m_id);
+ close.setTo(m_remoteJid);
+ close.setFrom(m_localJid);
+ close.setSid(m_sid);
+ m_client->sendPacket( close );
+ m_state = Idle;
+ emit transferFinished(m_sid, "Send finished");
+ }
+ else
+ {
+ //FIXME: work better with sockets and other stream devices.
+ QByteArray buffer = m_io->read( m_blockSize );
+
+ m_sequence++;
+ QXmppDataIq sendData;
+ sendData.setId(m_id);
+ sendData.setTo(m_remoteJid);
+ sendData.setFrom(m_localJid);
+ sendData.setSid(m_sid);
+ sendData.setSequence(m_sequence);
+ sendData.setPayload( buffer );
+
+ m_client->sendPacket( sendData );
+ }
+}
|
