* @brief Handles a fully parsed receiver header. */
| 549 | * @brief Handles a fully parsed receiver header. |
| 550 | */ |
| 551 | void IO::Protocols::ZMODEM::parseReceivedHeader(quint8 type, quint32 arg) |
| 552 | { |
| 553 | Q_ASSERT(type <= kZCAN); |
| 554 | Q_ASSERT(isActive()); |
| 555 | |
| 556 | m_timeoutTimer.stop(); |
| 557 | |
| 558 | switch (type) { |
| 559 | case kZRINIT: |
| 560 | if (m_state == State::SentZRQINIT) { |
| 561 | Q_EMIT statusMessage(tr("Receiver ready, sending file info…")); |
| 562 | sendZFILE(); |
| 563 | } else if (m_state == State::SentZEOF) { |
| 564 | Q_EMIT progressChanged(m_fileSize, m_fileSize); |
| 565 | sendZFIN(); |
| 566 | } |
| 567 | break; |
| 568 | |
| 569 | case kZRPOS: |
| 570 | m_fileOffset = qBound<qint64>(0, static_cast<qint64>(arg), m_fileSize); |
| 571 | Q_EMIT statusMessage(tr("Receiver requests data from offset %1").arg(m_fileOffset)); |
| 572 | sendDataSubpackets(); |
| 573 | break; |
| 574 | |
| 575 | case kZACK: |
| 576 | break; |
| 577 | |
| 578 | case kZSKIP: |
| 579 | Q_EMIT statusMessage(tr("Receiver skipped the file")); |
| 580 | sendZFIN(); |
| 581 | break; |
| 582 | |
| 583 | case kZNAK: |
| 584 | ++m_retryCount; |
| 585 | if (m_retryCount >= m_maxRetries) { |
| 586 | sendCancel(); |
| 587 | m_state = State::Idle; |
| 588 | if (m_file.isOpen()) |
| 589 | m_file.close(); |
| 590 | |
| 591 | Q_EMIT statusMessage(tr("Too many errors, transfer aborted")); |
| 592 | Q_EMIT finished(false, tr("Maximum retries exceeded")); |
| 593 | return; |
| 594 | } |
| 595 | |
| 596 | Q_EMIT statusMessage(tr("NAK received, retrying (%1/%2)…") |
| 597 | .arg(QString::number(m_retryCount), QString::number(m_maxRetries))); |
| 598 | |
| 599 | if (m_state == State::SentZRQINIT) |
| 600 | sendZRQINIT(); |
| 601 | |
| 602 | if (m_state == State::SentZFILE) |
| 603 | sendZFILE(); |
| 604 | |
| 605 | if (m_state == State::SentZEOF) |
| 606 | sendDataSubpackets(); |
| 607 | |
| 608 | break; |