Skip to content

Commit 1cd711e

Browse files
authored
Add identifiable packets through a counter (#272)
1 parent b0068a0 commit 1cd711e

File tree

2 files changed

+168
-54
lines changed

2 files changed

+168
-54
lines changed

pysquared/hardware/radio/packetizer/packet_manager.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import time
33

44
from ....logger import Logger
5+
from ....nvm.counter import Counter
56
from ....protos.radio import RadioProto
67

78
try:
@@ -17,17 +18,18 @@ def __init__(
1718
logger: Logger,
1819
radio: RadioProto,
1920
license: str,
21+
message_counter: Counter,
2022
send_delay: float = 0.2,
2123
) -> None:
2224
"""Initialize the packet manager with maximum packet size"""
2325
self._logger: Logger = logger
2426
self._radio: RadioProto = radio
2527
self._send_delay: float = send_delay
2628
self._license: str = license
27-
self._header_size: int = (
28-
5 # 2 bytes for sequence number, 2 for total packets, 1 for rssi
29-
)
29+
# 1 byte for packet identifier, 2 bytes for sequence number, 2 for total packets, 1 for rssi
30+
self._header_size: int = 6
3031
self._payload_size: int = radio.get_max_packet_size() - self._header_size
32+
self._message_counter: Counter = message_counter
3133

3234
def send(self, data: bytes) -> bool:
3335
"""Send data"""
@@ -55,8 +57,10 @@ def _pack_data(self, data: bytes) -> list[bytes]:
5557
"""
5658
Takes input data and returns a list of packets ready for transmission
5759
Each packet includes:
60+
- 1 byte: packet identifier
5861
- 2 bytes: sequence number (0-based)
5962
- 2 bytes: total number of packets
63+
- 1 byte: rssi
6064
- remaining bytes: payload
6165
"""
6266
# Calculate number of packets needed
@@ -67,11 +71,14 @@ def _pack_data(self, data: bytes) -> list[bytes]:
6771
data_length=len(data),
6872
)
6973

74+
packet_identifier: int = self._get_packet_identifier()
75+
7076
packets: list[bytes] = []
7177
for sequence_number in range(total_packets):
7278
# Create header
7379
header: bytes = (
74-
sequence_number.to_bytes(2, "big")
80+
packet_identifier.to_bytes(1, "big")
81+
+ sequence_number.to_bytes(2, "big")
7582
+ total_packets.to_bytes(2, "big")
7683
+ abs(self._radio.get_rssi()).to_bytes(1, "big")
7784
)
@@ -117,6 +124,8 @@ def listen(self, timeout: Optional[int] = None) -> bytes | None:
117124
if packet is None:
118125
continue
119126

127+
packet_identifier, _, total_packets, _ = self._get_header(packet)
128+
120129
# Log received packets
121130
self._logger.debug(
122131
"Received packet",
@@ -125,11 +134,19 @@ def listen(self, timeout: Optional[int] = None) -> bytes | None:
125134
payload=self._get_payload(packet),
126135
)
127136

128-
# Process received packet
137+
if received_packets:
138+
(
139+
first_packet_identifier,
140+
_,
141+
_,
142+
_,
143+
) = self._get_header(received_packets[0])
144+
if packet_identifier != first_packet_identifier:
145+
continue
146+
129147
received_packets.append(packet)
130148

131149
# Check if we have all packets
132-
_, total_packets, _ = self._get_header(packet)
133150
if total_packets == len(received_packets):
134151
self._logger.debug(
135152
"Received all expected packets", received=total_packets
@@ -150,19 +167,25 @@ def _unpack_data(self, packets: list[bytes]) -> bytes:
150167
Returns None if packets are missing or corrupted
151168
"""
152169
sorted_packets: list = sorted(
153-
packets, key=lambda p: int.from_bytes(p[:2], "big")
170+
packets, key=lambda p: int.from_bytes(p[1:3], "big")
154171
)
155172

156173
return b"".join(self._get_payload(packet) for packet in sorted_packets)
157174

158-
def _get_header(self, packet: bytes) -> tuple[int, int, int]:
175+
def _get_header(self, packet: bytes) -> tuple[int, int, int, int]:
159176
"""Returns the sequence number and total packets stored in the header."""
160177
return (
161-
int.from_bytes(packet[0:2], "big"), # sequence number
162-
int.from_bytes(packet[2:4], "big"), # total packets
163-
-int.from_bytes(packet[4:5], "big"), # RSSI
178+
int.from_bytes(packet[0:1], "big"), # packet identifier
179+
int.from_bytes(packet[1:3], "big"), # sequence number
180+
int.from_bytes(packet[3:5], "big"), # total packets
181+
-int.from_bytes(packet[5:6], "big"), # RSSI
164182
)
165183

166184
def _get_payload(self, packet: bytes) -> bytes:
167185
"""Returns the payload of the packet."""
168186
return packet[self._header_size :]
187+
188+
def _get_packet_identifier(self) -> int:
189+
"""Increments message_counter and returns the current identifier for a packet"""
190+
self._message_counter.increment()
191+
return self._message_counter.get()

0 commit comments

Comments
 (0)