summaryrefslogtreecommitdiffstats
path: root/src/net/mcast/McastSender.cpp
blob: 24a629c036d2af8496e12de029a9fec63e674e32 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
# Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg
#
# This program is free software distributed under the GPL version 2.
# See http://openslx.org/COPYING
#
# If you have any feedback please consult http://openslx.org/feedback and
# send your suggestions, praise, or complaints to feedback@openslx.org
#
# General information about OpenSLX can be found at http://openslx.org/
# -----------------------------------------------------------------------------
# src/net/mcast/McastReceiver.h
#    - implement the receiver-side multicast file transfer protocol -- implementation
# -----------------------------------------------------------------------------
*/

#include "McastSender.h"
#include "McastConstants.h"

#include <QDataStream>

#include <pgm/pgm.h>
// OpenPGM #defines bool. This is bad in C++.
#undef bool

McastSender::McastSender(QIODevice* iodev, McastConfiguration const* config, QObject* parent) :
    QObject(parent),
    _config(config ? new McastConfiguration(*config) : new McastConfiguration()),
    _socket(0),
    _iodev(iodev),
    _curoffs(0),
    _hash(QCryptographicHash::Md5),
    _finished(false)
{
}

McastSender::~McastSender()
{
	delete _config;
}

void McastSender::start()
{
    _socket = new McastPGMSocket(this);
    connect(_socket, SIGNAL(readyToSend()), this, SLOT(readyToSend()));
    _socket->open(_config, McastPGMSocket::PSOCK_WRITE);
}

void McastSender::readyToSend()
{
	if(_finished)
		return;

    if(_iodev->atEnd())
    {
        QByteArray fpdu;
        QDataStream strm(&fpdu, QIODevice::WriteOnly);
        strm.setByteOrder(QDataStream::BigEndian);

        strm << (quint64)MCASTFT_MAGIC << (quint64)UINT64_C(0xffffffffffffffff) << _hash.result();
        strm << qChecksum(fpdu.constData(), fpdu.size());

        _socket->sendPacket(fpdu);
        // _socket->finish();

        _finished = true;

        emit finished();
        return;
    }

    QByteArray barr(DEFAULT_MULTICAST_APDU, '\0');
    qint64 len_read;
    len_read = _iodev->read(barr.data(), barr.capacity());
    barr.resize((int)len_read);

    _hash.addData(barr);

    QByteArray pdu;
    QDataStream strm(&pdu, QIODevice::WriteOnly);
    strm.setByteOrder(QDataStream::BigEndian);

    strm << (quint64)MCASTFT_MAGIC << _curoffs;
    strm << barr;
    quint16 checksum = qChecksum(pdu.constData(), pdu.size());
    strm << checksum;

    _curoffs += len_read;

    _socket->sendPacket(pdu);
}

void McastSender::close()
{
	_socket->finish();
}