#include #include #include "sappeer.h" #include "sapconnection.h" #include "sapsocket.h" #define DELAYED_ACK_TIME 1000 SAPSocket::SAPSocket(SAPConnection *conn, int sessionId, const SAPChannelInfo &chanInfo) : QObject(conn), _sessionId(sessionId), _info(chanInfo), _open(false), _outLastSeqNum(0), _inLastSeqNum(0), _inLastAck(0) { } SAPPeer * SAPSocket::peer() { return connection()->peer(); } SAPConnection * SAPSocket::connection() { return static_cast(parent()); } SAPChannelInfo SAPSocket::channelInfo() const { return _info; } bool SAPSocket::isOpen() const { return _open; } bool SAPSocket::messageAvailable() const { return !_in.empty(); } QByteArray SAPSocket::receive() { if (!_in.empty()) { return _in.dequeue(); } else { return QByteArray(); } } bool SAPSocket::send(const QByteArray &data) { SAProtocol::DataFrame frame; if (!isOpen()) { qWarning() << "Socket is not yet open"; return false; } frame.withSeqNum = isWithSeqNum(); if (isReliable()) { frame.seqNum = ++_outLastSeqNum; } else { frame.seqNum = 0; } frame.unk_1 = 0; frame.data = data; peer()->writeDataToSession(_sessionId, SAProtocol::packDataFrame(frame)); return true; } void SAPSocket::setOpen(bool open) { _open = open; } void SAPSocket::acceptIncomingData(const QByteArray &data) { if (data.isEmpty()) return; SAProtocol::DataFrame frame = SAProtocol::unpackDataFrame(data, isWithSeqNum()); if (isReliable()) { quint16 expectedSeqNum = _inLastSeqNum + 1; if (frame.seqNum != expectedSeqNum) { qWarning() << "Unexpected sequence number" << frame.seqNum << "on session" << _sessionId << "(expected " << expectedSeqNum << ")"; } else { _inLastSeqNum = frame.seqNum; if (!_timer.isActive()) { _timer.start(DELAYED_ACK_TIME, Qt::CoarseTimer, this); } } } _in.enqueue(frame.data); emit messageReceived(); } int SAPSocket::sessionId() const { return _sessionId; } void SAPSocket::timerEvent(QTimerEvent *event) { if (event->timerId() == _timer.timerId()) { if (_inLastSeqNum != _inLastAck) { peer()->writeAckToSession(_sessionId, _inLastSeqNum); _inLastAck = _inLastSeqNum; } _timer.stop(); } else { QObject::timerEvent(event); } } bool SAPSocket::isReliable() const { return _info.qosType() == SAPChannelInfo::QoSReliabilityEnable; } bool SAPSocket::isWithSeqNum() const { return _info.qosType() == SAPChannelInfo::QoSReliabilityDisable || _info.qosType() == SAPChannelInfo::QoSReliabilityEnable; }