Get with File on P-ION: connect and transfer the way Ontrol's Niagara driver does
A real P-ION (fw 1.32) restarted on every Sox file get. Ontrol's Niagara 4 driver gets app.sab from the same device, so its settings are copied: - DASP hello asks for 256-byte packets (idealMax/absMax), so file chunks are 238 bytes - the message-length header (0x81) goes to Orion only, decided once the platform id is read - the app is saved on the device before app.sab is read, the save resent every 5 s rather than 1 s (a P-ION save takes 2-3+ s) - the file open is resent every 15 s; DASP gains a per-packet resend interval for this Tested on a P-ION at 192.168.1.252: save 3.2 s, app.sab + kits.scode + app.sax in 15.8 s, no resends, device stayed up. The unsaved-changes question became a notice, since the app is now always saved first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -456,7 +456,7 @@ def _to_ack_more(seq_more, max_bytes):
|
||||
|
||||
class _Packet:
|
||||
__slots__ = ("seq_num", "payload", "acked", "enqueued_time",
|
||||
"sent_time", "send_attempts", "next")
|
||||
"sent_time", "send_attempts", "send_retry", "next")
|
||||
|
||||
def __init__(self):
|
||||
self.seq_num = 0
|
||||
@@ -465,6 +465,7 @@ class _Packet:
|
||||
self.enqueued_time = 0.0
|
||||
self.sent_time = 0.0
|
||||
self.send_attempts = 1
|
||||
self.send_retry = None # seconds; None = the window's own interval
|
||||
self.next = None
|
||||
|
||||
|
||||
@@ -506,8 +507,9 @@ class SendWindow:
|
||||
self._tail = None
|
||||
self._cond.notify_all()
|
||||
|
||||
def send(self, payload):
|
||||
def send(self, payload, send_retry=None):
|
||||
p = _Packet()
|
||||
p.send_retry = send_retry
|
||||
p.enqueued_time = _ticks()
|
||||
with self._cond:
|
||||
p.seq_num = self._seq_num & 0xFFFF
|
||||
@@ -618,9 +620,15 @@ class SendWindow:
|
||||
p = self._head
|
||||
while p is not None:
|
||||
if not p.acked:
|
||||
backoff_shift = min(p.send_attempts - 1, 32)
|
||||
interval = min(self.send_retry * (1 << backoff_shift),
|
||||
self.max_retry_backoff)
|
||||
if p.send_retry is not None:
|
||||
# A request the device is slow to take -- a P-ION saving its
|
||||
# app, opening a file -- is resent at its own steady interval:
|
||||
# the 1 s default resends it while the device is still busy.
|
||||
interval = p.send_retry
|
||||
else:
|
||||
backoff_shift = min(p.send_attempts - 1, 32)
|
||||
interval = min(self.send_retry * (1 << backoff_shift),
|
||||
self.max_retry_backoff)
|
||||
if now - p.sent_time >= interval:
|
||||
self._resend(p)
|
||||
oldest = max(oldest, now - p.enqueued_time)
|
||||
@@ -776,10 +784,11 @@ class DaspSession:
|
||||
|
||||
# ── Send / Receive ──────────────────────────────────────────
|
||||
|
||||
def send(self, payload):
|
||||
def send(self, payload, send_retry=None):
|
||||
"""Queues a datagram. send_retry (seconds) overrides the resend interval."""
|
||||
if self.is_closed:
|
||||
raise DaspException(f"Session closed: {self.close_cause}")
|
||||
self.send_window.send(payload)
|
||||
self.send_window.send(payload, send_retry)
|
||||
|
||||
def receive(self, timeout=1.0):
|
||||
if self.is_closed:
|
||||
|
||||
Reference in New Issue
Block a user