diff --git a/bin/dmshell_client.py b/bin/dmshell_client.py index 6f76d79a4..df082eaf7 100644 --- a/bin/dmshell_client.py +++ b/bin/dmshell_client.py @@ -409,7 +409,7 @@ def reader_loop(sock: socket.socket, state: SessionState) -> None: send_ack_frame(sock, state) continue if action == "gap": - state.event_queue.put(f"missing frame before seq={shell.seq}, requesting replay from seq={missing_from}") + # state.event_queue.put(f"missing frame before seq={shell.seq}, requesting replay from seq={missing_from}") send_ack_frame(sock, state, replay_from=missing_from) continue diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index ca3d78503..5ef688629 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -172,6 +172,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified /** Attempt to find a packet in the TxQueue. Returns true if the packet was found. */ virtual bool findInTxQueue(NodeNum from, PacketId id) override; + uint8_t packetsInTxQueue() { return txQueue.getMaxLen() - txQueue.getFree(); } + private: /** if we have something waiting to send, start a short (random) timer so we can come check for collision before actually * doing the transmit */ diff --git a/src/modules/DMShell.cpp b/src/modules/DMShell.cpp index fed1a526e..36a1b0247 100644 --- a/src/modules/DMShell.cpp +++ b/src/modules/DMShell.cpp @@ -98,13 +98,21 @@ ProcessMessage DMShellModule::handleReceived(const meshtastic_MeshPacket &mp) return ProcessMessage::STOP; } + // TODO: double-check the sender is the same as the one we have an active session with before processing ACKs + if (frame.op == meshtastic_DMShell_OpCode_ACK) { + if (session.active && frame.sessionId == session.sessionId && getFrom(&mp) == session.peer) { + handleAckFrame(frame); + } + return ProcessMessage::STOP; + } + if (frame.op >= 64) { - LOG_WARN("DMShell: ignoring frame with op code %d", frame.op); + LOG_WARN("DMShell: ignoring frame with op code %d, seq %d", frame.op, frame.seq); return ProcessMessage::CONTINUE; } if (!isAuthorizedPacket(mp)) { - LOG_WARN("DMShell: unauthorized sender 0x%x", mp.from); + LOG_WARN("DMShell: unauthorized sender 0x%x, %u", mp.from, frame.op); myReply = allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp); return ProcessMessage::STOP; } @@ -113,13 +121,6 @@ ProcessMessage DMShellModule::handleReceived(const meshtastic_MeshPacket &mp) pruneSentFrames(frame.ackSeq); } - if (frame.op == meshtastic_DMShell_OpCode_ACK) { - if (session.active && frame.sessionId == session.sessionId && getFrom(&mp) == session.peer) { - handleAckFrame(frame); - } - return ProcessMessage::STOP; - } - if (frame.op == meshtastic_DMShell_OpCode_OPEN) { LOG_WARN("DMShell: received OPEN from 0x%x sessionId=0x%x", mp.from, frame.sessionId); if (!openSession(mp, frame)) { @@ -189,6 +190,10 @@ int32_t DMShellModule::runOnce() return 100; } + if (RadioLibInterface::instance->packetsInTxQueue() > 1) { + return 50; + } + uint8_t outBuf[MAX_PTY_READ_SIZE]; while (session.masterFd >= 0) { const ssize_t bytesRead = read(session.masterFd, outBuf, sizeof(outBuf)); @@ -196,7 +201,8 @@ int32_t DMShellModule::runOnce() LOG_WARN("DMShell: read %d bytes from PTY", bytesRead); sendControl(meshtastic_DMShell_OpCode_OUTPUT, outBuf, static_cast(bytesRead)); session.lastActivityMs = millis(); - continue; + // continue; + return 50; } if (bytesRead == 0) {