mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-10 18:53:03 +02:00
Use numerical acks
This commit is contained in:
+10
-2
@@ -258,6 +258,11 @@ KeyStore.clear_private_key()
|
||||
|
||||
## ACK and Repeat Detection
|
||||
|
||||
The `acked` field is an integer count, not a boolean:
|
||||
- `0` = not acked
|
||||
- `1` = one ACK/echo received
|
||||
- `2+` = multiple flood echoes received
|
||||
|
||||
### Direct Message ACKs
|
||||
|
||||
When sending a direct message, an expected ACK code is tracked:
|
||||
@@ -267,7 +272,7 @@ from app.event_handlers import track_pending_ack
|
||||
track_pending_ack(expected_ack="abc123", message_id=42, timeout_ms=30000)
|
||||
```
|
||||
|
||||
When ACK event arrives, the message is marked as acked.
|
||||
When ACK event arrives, the message's ack count is incremented.
|
||||
|
||||
### Channel Message Repeats
|
||||
|
||||
@@ -276,7 +281,10 @@ Flood messages echo back through repeaters. Detection uses:
|
||||
- Text hash
|
||||
- Timestamp (±5 second window)
|
||||
|
||||
When a repeat is detected, the original outgoing message is marked as "acked".
|
||||
Each repeat increments the ack count. The frontend displays:
|
||||
- `?` = no acks
|
||||
- `✓` = 1 echo
|
||||
- `✓2`, `✓3`, etc. = multiple echoes (real-time updates via WebSocket)
|
||||
|
||||
### Auto-Contact Sync to Radio
|
||||
|
||||
|
||||
@@ -180,8 +180,8 @@ async def on_ack(event: "Event") -> None:
|
||||
message_id, _, _ = _pending_acks.pop(ack_code)
|
||||
logger.info("ACK received for message %d", message_id)
|
||||
|
||||
await MessageRepository.mark_acked(message_id)
|
||||
broadcast_event("message_acked", {"message_id": message_id})
|
||||
ack_count = await MessageRepository.increment_ack_count(message_id)
|
||||
broadcast_event("message_acked", {"message_id": message_id, "ack_count": ack_count})
|
||||
else:
|
||||
logger.debug("ACK code %s does not match any pending messages", ack_code)
|
||||
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ class Message(BaseModel):
|
||||
txt_type: int = 0
|
||||
signature: str | None = None
|
||||
outgoing: bool = False
|
||||
acked: bool = False
|
||||
acked: int = 0
|
||||
|
||||
|
||||
class RawPacket(BaseModel):
|
||||
|
||||
@@ -230,8 +230,8 @@ async def _process_group_text(
|
||||
# Don't pop - let it expire naturally so subsequent repeats via
|
||||
# different radio paths are also caught as duplicates
|
||||
logger.info("Repeat detected for channel message %d", message_id)
|
||||
await MessageRepository.mark_acked(message_id)
|
||||
broadcast_event("message_acked", {"message_id": message_id})
|
||||
ack_count = await MessageRepository.increment_ack_count(message_id)
|
||||
broadcast_event("message_acked", {"message_id": message_id, "ack_count": ack_count})
|
||||
is_repeat = True
|
||||
break
|
||||
|
||||
|
||||
+10
-4
@@ -313,17 +313,23 @@ class MessageRepository:
|
||||
txt_type=row["txt_type"],
|
||||
signature=row["signature"],
|
||||
outgoing=bool(row["outgoing"]),
|
||||
acked=bool(row["acked"]),
|
||||
acked=row["acked"],
|
||||
)
|
||||
for row in rows
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
async def mark_acked(message_id: int) -> None:
|
||||
async def increment_ack_count(message_id: int) -> int:
|
||||
"""Increment ack count and return the new value."""
|
||||
await db.conn.execute(
|
||||
"UPDATE messages SET acked = 1 WHERE id = ?", (message_id,)
|
||||
"UPDATE messages SET acked = acked + 1 WHERE id = ?", (message_id,)
|
||||
)
|
||||
await db.conn.commit()
|
||||
cursor = await db.conn.execute(
|
||||
"SELECT acked FROM messages WHERE id = ?", (message_id,)
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
return row["acked"] if row else 1
|
||||
|
||||
@staticmethod
|
||||
async def find_duplicate(
|
||||
@@ -398,7 +404,7 @@ class MessageRepository:
|
||||
txt_type=row["txt_type"],
|
||||
signature=row["signature"],
|
||||
outgoing=bool(row["outgoing"]),
|
||||
acked=bool(row["acked"]),
|
||||
acked=row["acked"],
|
||||
)
|
||||
for row in rows
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user