mirror of
https://github.com/meshcore-dev/meshcore_py.git
synced 2026-04-20 22:13:49 +00:00
Revert "Refactor command system to be queue based"
This reverts commit 28957a4b60.
This commit is contained in:
parent
9aeffb41a1
commit
ccb1d6eb9e
12 changed files with 516 additions and 376 deletions
|
|
@ -1,9 +1,10 @@
|
|||
import logging
|
||||
import json
|
||||
import time
|
||||
from typing import Any, Dict
|
||||
from .events import Event, EventType, EventDispatcher
|
||||
from .packets import PacketType
|
||||
from .binary_parsing import BinaryReqType, lpp_parse, lpp_parse_mma, parse_acl
|
||||
from .packets import BinaryReqType, PacketType
|
||||
from .parsing import lpp_parse, lpp_parse_mma, parse_acl, parse_status
|
||||
from cayennelpp import LppFrame, LppData
|
||||
from meshcore.lpp_json_encoder import lpp_json_encoder
|
||||
|
||||
|
|
@ -17,7 +18,35 @@ class MessageReader:
|
|||
# before events are dispatched
|
||||
self.contacts = {} # Temporary storage during contact list building
|
||||
self.contact_nb = 0 # Used for contact processing
|
||||
|
||||
# Track pending binary requests by tag for proper response parsing
|
||||
self.pending_binary_requests: Dict[str, Dict[str, Any]] = {} # tag -> {request_type, expires_at}
|
||||
|
||||
def register_binary_request(self, prefix: str, tag: str, request_type: BinaryReqType, timeout_seconds: float):
|
||||
"""Register a pending binary request for proper response parsing"""
|
||||
# Clean up expired requests before adding new one
|
||||
self.cleanup_expired_requests()
|
||||
|
||||
expires_at = time.time() + timeout_seconds
|
||||
self.pending_binary_requests[tag] = {
|
||||
"request_type": request_type,
|
||||
"pubkey_prefix": prefix,
|
||||
"expires_at": expires_at
|
||||
}
|
||||
logger.debug(f"Registered binary request: tag={tag}, type={request_type}, expires in {timeout_seconds}s")
|
||||
|
||||
def cleanup_expired_requests(self):
|
||||
"""Remove expired binary requests"""
|
||||
current_time = time.time()
|
||||
expired_tags = [
|
||||
tag for tag, info in self.pending_binary_requests.items()
|
||||
if current_time > info["expires_at"]
|
||||
]
|
||||
|
||||
for tag in expired_tags:
|
||||
logger.debug(f"Cleaning up expired binary request: tag={tag}")
|
||||
del self.pending_binary_requests[tag]
|
||||
|
||||
async def handle_rx(self, data: bytearray):
|
||||
packet_type_value = data[0]
|
||||
logger.debug(f"Received data: {data.hex()}")
|
||||
|
|
@ -331,36 +360,13 @@ class MessageReader:
|
|||
)
|
||||
|
||||
elif packet_type_value == PacketType.STATUS_RESPONSE.value:
|
||||
res = {}
|
||||
res["pubkey_pre"] = data[2:8].hex()
|
||||
res["bat"] = int.from_bytes(data[8:10], byteorder="little")
|
||||
res["tx_queue_len"] = int.from_bytes(data[10:12], byteorder="little")
|
||||
res["noise_floor"] = int.from_bytes(
|
||||
data[12:14], byteorder="little", signed=True
|
||||
)
|
||||
res["last_rssi"] = int.from_bytes(
|
||||
data[14:16], byteorder="little", signed=True
|
||||
)
|
||||
res["nb_recv"] = int.from_bytes(
|
||||
data[16:20], byteorder="little", signed=False
|
||||
)
|
||||
res["nb_sent"] = int.from_bytes(
|
||||
data[20:24], byteorder="little", signed=False
|
||||
)
|
||||
res["airtime"] = int.from_bytes(data[24:28], byteorder="little")
|
||||
res["uptime"] = int.from_bytes(data[28:32], byteorder="little")
|
||||
res["sent_flood"] = int.from_bytes(data[32:36], byteorder="little")
|
||||
res["sent_direct"] = int.from_bytes(data[36:40], byteorder="little")
|
||||
res["recv_flood"] = int.from_bytes(data[40:44], byteorder="little")
|
||||
res["recv_direct"] = int.from_bytes(data[44:48], byteorder="little")
|
||||
res["full_evts"] = int.from_bytes(data[48:50], byteorder="little")
|
||||
res["last_snr"] = (
|
||||
int.from_bytes(data[50:52], byteorder="little", signed=True) / 4
|
||||
)
|
||||
res["direct_dups"] = int.from_bytes(data[52:54], byteorder="little")
|
||||
res["flood_dups"] = int.from_bytes(data[54:56], byteorder="little")
|
||||
res["rx_airtime"] = int.from_bytes(data[56:60], byteorder="little")
|
||||
res = parse_status(data, offset=8)
|
||||
data_hex = data[8:].hex()
|
||||
logger.debug(f"Status response: {data_hex}")
|
||||
|
||||
attributes = {
|
||||
"pubkey_prefix": res["pubkey_pre"],
|
||||
}
|
||||
data_hex = data[8:].hex()
|
||||
logger.debug(f"Status response: {data_hex}")
|
||||
|
||||
|
|
@ -491,112 +497,60 @@ class MessageReader:
|
|||
|
||||
elif packet_type_value == PacketType.BINARY_RESPONSE.value:
|
||||
logger.debug(f"Received binary data: {data.hex()}")
|
||||
res = {}
|
||||
|
||||
res["tag"] = data[2:6].hex()
|
||||
res["data"] = data[6:].hex()
|
||||
|
||||
attributes = {"tag": res["tag"]}
|
||||
|
||||
# Always dispatch the generic BINARY_RESPONSE event first
|
||||
await self.dispatcher.dispatch(
|
||||
Event(EventType.BINARY_RESPONSE, res, attributes)
|
||||
)
|
||||
|
||||
# Parse the request type from the response data and dispatch specific events
|
||||
tag = data[2:6].hex()
|
||||
response_data = data[6:]
|
||||
if response_data: # Check if there's response data
|
||||
request_type = response_data[0]
|
||||
|
||||
# Always dispatch generic BINARY_RESPONSE
|
||||
binary_res = {"tag": tag, "data": response_data.hex()}
|
||||
await self.dispatcher.dispatch(
|
||||
Event(EventType.BINARY_RESPONSE, binary_res, {"tag": tag})
|
||||
)
|
||||
|
||||
# Check for tracked request type and dispatch specific response
|
||||
if tag in self.pending_binary_requests:
|
||||
request_type = self.pending_binary_requests[tag]["request_type"]
|
||||
pubkey_prefix = self.pending_binary_requests[tag]["pubkey_prefix"]
|
||||
del self.pending_binary_requests[tag]
|
||||
logger.debug(f"Processing binary response for tag {tag}, type {request_type}, pubkey_prefix {pubkey_prefix}")
|
||||
|
||||
if request_type == BinaryReqType.STATUS.value:
|
||||
# Parse as status response - use same parsing as STATUS_RESPONSE
|
||||
if len(response_data) >= 53: # Minimum size for status data
|
||||
status_res = {}
|
||||
status_res["pubkey_pre"] = data[2:8].hex() # Use pubkey from tag area
|
||||
status_data = response_data[1:] # Skip the request type byte
|
||||
|
||||
status_res["bat"] = int.from_bytes(status_data[0:2], byteorder="little")
|
||||
status_res["tx_queue_len"] = int.from_bytes(status_data[2:4], byteorder="little")
|
||||
status_res["noise_floor"] = int.from_bytes(status_data[4:6], byteorder="little", signed=True)
|
||||
status_res["last_rssi"] = int.from_bytes(status_data[6:8], byteorder="little", signed=True)
|
||||
status_res["nb_recv"] = int.from_bytes(status_data[8:12], byteorder="little", signed=False)
|
||||
status_res["nb_sent"] = int.from_bytes(status_data[12:16], byteorder="little", signed=False)
|
||||
status_res["airtime"] = int.from_bytes(status_data[16:20], byteorder="little")
|
||||
status_res["uptime"] = int.from_bytes(status_data[20:24], byteorder="little")
|
||||
status_res["sent_flood"] = int.from_bytes(status_data[24:28], byteorder="little")
|
||||
status_res["sent_direct"] = int.from_bytes(status_data[28:32], byteorder="little")
|
||||
status_res["recv_flood"] = int.from_bytes(status_data[32:36], byteorder="little")
|
||||
status_res["recv_direct"] = int.from_bytes(status_data[36:40], byteorder="little")
|
||||
status_res["full_evts"] = int.from_bytes(status_data[40:42], byteorder="little")
|
||||
status_res["last_snr"] = int.from_bytes(status_data[42:44], byteorder="little", signed=True) / 4
|
||||
status_res["direct_dups"] = int.from_bytes(status_data[44:46], byteorder="little")
|
||||
status_res["flood_dups"] = int.from_bytes(status_data[46:48], byteorder="little")
|
||||
status_res["rx_airtime"] = int.from_bytes(status_data[48:52], byteorder="little")
|
||||
|
||||
status_attributes = {"pubkey_prefix": status_res["pubkey_pre"]}
|
||||
await self.dispatcher.dispatch(
|
||||
Event(EventType.STATUS_RESPONSE, status_res, status_attributes)
|
||||
)
|
||||
if request_type == BinaryReqType.STATUS and len(response_data) >= 52:
|
||||
res = {}
|
||||
res = parse_status(response_data, pubkey_prefix=pubkey_prefix)
|
||||
await self.dispatcher.dispatch(
|
||||
Event(EventType.STATUS_RESPONSE, res, {"pubkey_prefix": res["pubkey_pre"], "tag": tag})
|
||||
)
|
||||
|
||||
elif request_type == BinaryReqType.TELEMETRY.value:
|
||||
# Parse as telemetry response
|
||||
elif request_type == BinaryReqType.TELEMETRY:
|
||||
try:
|
||||
telemetry_data = response_data[1:] # Skip the request type byte
|
||||
lpp = lpp_parse(telemetry_data)
|
||||
|
||||
telem_res = {
|
||||
"pubkey_pre": data[2:8].hex(),
|
||||
"lpp": lpp
|
||||
}
|
||||
|
||||
telem_attributes = {
|
||||
"raw": telemetry_data.hex(),
|
||||
"pubkey_prefix": telem_res["pubkey_pre"]
|
||||
}
|
||||
|
||||
lpp = lpp_parse(response_data)
|
||||
telem_res = {"tag": tag, "lpp": lpp, "pubkey_prefix": pubkey_prefix}
|
||||
await self.dispatcher.dispatch(
|
||||
Event(EventType.TELEMETRY_RESPONSE, telem_res, telem_attributes)
|
||||
Event(EventType.TELEMETRY_RESPONSE, telem_res, telem_res)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error parsing binary telemetry response: {e}")
|
||||
|
||||
elif request_type == BinaryReqType.MMA.value:
|
||||
# Parse as MMA response
|
||||
elif request_type == BinaryReqType.MMA:
|
||||
try:
|
||||
mma_data = response_data[5:] # Skip request type + 4 bytes header
|
||||
mma_result = lpp_parse_mma(mma_data)
|
||||
|
||||
mma_res = {
|
||||
"pubkey_pre": data[2:8].hex(),
|
||||
"mma_data": mma_result
|
||||
}
|
||||
|
||||
mma_attributes = {"pubkey_prefix": mma_res["pubkey_pre"]}
|
||||
|
||||
mma_result = lpp_parse_mma(response_data[4:]) # Skip 4-byte header
|
||||
mma_res = {"tag": tag, "mma_data": mma_result, "pubkey_prefix": pubkey_prefix}
|
||||
await self.dispatcher.dispatch(
|
||||
Event(EventType.MMA_RESPONSE, mma_res, mma_attributes)
|
||||
Event(EventType.MMA_RESPONSE, mma_res, mma_res)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error parsing binary MMA response: {e}")
|
||||
|
||||
elif request_type == BinaryReqType.ACL.value:
|
||||
# Parse as ACL response
|
||||
elif request_type == BinaryReqType.ACL:
|
||||
try:
|
||||
acl_data = response_data[1:] # Skip the request type byte
|
||||
acl_result = parse_acl(acl_data)
|
||||
|
||||
acl_res = {
|
||||
"pubkey_pre": data[2:8].hex(),
|
||||
"acl_data": acl_result
|
||||
}
|
||||
|
||||
acl_attributes = {"pubkey_prefix": acl_res["pubkey_pre"]}
|
||||
|
||||
acl_result = parse_acl(response_data)
|
||||
acl_res = {"tag": tag, "acl_data": acl_result, "pubkey_prefix": pubkey_prefix}
|
||||
await self.dispatcher.dispatch(
|
||||
Event(EventType.ACL_RESPONSE, acl_res, acl_attributes)
|
||||
Event(EventType.ACL_RESPONSE, acl_res, {"tag": tag, "pubkey_prefix": pubkey_prefix})
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error parsing binary ACL response: {e}")
|
||||
else:
|
||||
logger.debug(f"No tracked request found for binary response tag {tag}")
|
||||
|
||||
elif packet_type_value == PacketType.PATH_DISCOVERY_RESPONSE.value:
|
||||
logger.debug(f"Received path discovery response: {data.hex()}")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue