1
0
mirror of https://github.com/craigerl/aprsd.git synced 2024-12-22 01:20:59 -05:00

Merge pull request #128 from craigerl/fix_kiss

Fix sending packets over KISS interface
This commit is contained in:
Walter A. Boring IV 2023-07-28 18:08:54 -04:00 committed by GitHub
commit 3994235380
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 55 deletions

View File

@ -81,27 +81,18 @@ class KISS3Client:
LOG.debug("Start blocking KISS consumer") LOG.debug("Start blocking KISS consumer")
self._parse_callback = callback self._parse_callback = callback
self.kiss.read(callback=self.parse_frame, min_frames=None) self.kiss.read(callback=self.parse_frame, min_frames=None)
LOG.debug("END blocking KISS consumer") LOG.debug(f"END blocking KISS consumer {self.kiss}")
def send(self, packet): def send(self, packet):
"""Send an APRS Message object.""" """Send an APRS Message object."""
# payload = (':%-9s:%s' % (
# msg.tocall,
# payload
# )).encode('US-ASCII'),
# payload = str(msg).encode('US-ASCII')
payload = None payload = None
path = ["WIDE1-1", "WIDE2-1"] path = ["WIDE1-1", "WIDE2-1"]
if isinstance(packet, core.AckPacket): if isinstance(packet, core.Packet):
msg_payload = f"ack{packet.msgNo}" packet.prepare()
elif isinstance(packet, core.Packet): payload = packet.payload.encode("US-ASCII")
payload = packet.raw.encode("US-ASCII")
path = ["WIDE2-1"]
else: else:
msg_payload = f"{packet.raw}{{{str(packet.msgNo)}" msg_payload = f"{packet.raw}{{{str(packet.msgNo)}"
if not payload:
payload = ( payload = (
":{:<9}:{}".format( ":{:<9}:{}".format(
packet.to_call, packet.to_call,
@ -109,9 +100,12 @@ class KISS3Client:
) )
).encode("US-ASCII") ).encode("US-ASCII")
LOG.debug(f"Send '{payload}' TO KISS") LOG.debug(
f"KISS Send '{payload}' TO '{packet.to_call}' From "
f"'{packet.from_call}' with PATH '{path}'",
)
frame = Frame.ui( frame = Frame.ui(
destination=packet.to_call, destination="APZ100",
source=packet.from_call, source=packet.from_call,
path=path, path=path,
info=payload, info=payload,

View File

@ -57,6 +57,8 @@ class Packet(metaclass=abc.ABCMeta):
# or holds the raw string from input packet # or holds the raw string from input packet
raw: str = None raw: str = None
raw_dict: dict = field(repr=False, default_factory=lambda: {}) raw_dict: dict = field(repr=False, default_factory=lambda: {})
# Built by calling prepare(). raw needs this built first.
payload: str = None
# Fields related to sending packets out # Fields related to sending packets out
send_count: int = field(repr=False, default=0) send_count: int = field(repr=False, default=0)
@ -92,11 +94,24 @@ class Packet(metaclass=abc.ABCMeta):
def prepare(self): def prepare(self):
"""Do stuff here that is needed prior to sending over the air.""" """Do stuff here that is needed prior to sending over the air."""
# now build the raw message for sending # now build the raw message for sending
self._build_payload()
self._build_raw() self._build_raw()
def _build_payload(self):
"""The payload is the non headers portion of the packet."""
msg = self._filter_for_send().rstrip("\n")
self.payload = (
f":{self.to_call.ljust(9)}"
f":{msg}"
)
def _build_raw(self): def _build_raw(self):
"""Build the self.raw string which is what is sent over the air.""" """Build the self.raw which is what is sent over the air."""
self.raw = self._filter_for_send().rstrip("\n") self.raw = "{}>APZ100:{}".format(
self.from_call,
self.payload,
)
LOG.debug(f"_build_raw: payload '{self.payload}' raw '{self.raw}'")
@staticmethod @staticmethod
def factory(raw_packet): def factory(raw_packet):
@ -233,7 +248,7 @@ class PathPacket(Packet):
path: List[str] = field(default_factory=list) path: List[str] = field(default_factory=list)
via: str = None via: str = None
def _build_raw(self): def _build_payload(self):
raise NotImplementedError raise NotImplementedError
@ -245,13 +260,8 @@ class AckPacket(PathPacket):
if self.response: if self.response:
LOG.warning("Response set!") LOG.warning("Response set!")
def _build_raw(self): def _build_payload(self):
"""Build the self.raw which is what is sent over the air.""" self.payload = f":{self.to_call.ljust(9)}:ack{self.msgNo}"
self.raw = "{}>APZ100::{}:ack{}".format(
self.from_call,
self.to_call.ljust(9),
self.msgNo,
)
@dataclass @dataclass
@ -262,13 +272,8 @@ class RejectPacket(PathPacket):
if self.response: if self.response:
LOG.warning("Response set!") LOG.warning("Response set!")
def _build_raw(self): def _build_payload(self):
"""Build the self.raw which is what is sent over the air.""" self.payload = f":{self.to_call.ljust(9)} :rej{self.msgNo}"
self.raw = "{}>APZ100::{} :rej{}".format(
self.from_call,
self.to_call.ljust(9),
self.msgNo,
)
@dataclass @dataclass
@ -285,10 +290,8 @@ class MessagePacket(PathPacket):
# We all miss George Carlin # We all miss George Carlin
return re.sub("fuck|shit|cunt|piss|cock|bitch", "****", message) return re.sub("fuck|shit|cunt|piss|cock|bitch", "****", message)
def _build_raw(self): def _build_payload(self):
"""Build the self.raw which is what is sent over the air.""" self.payload = ":{}:{}{{{}".format(
self.raw = "{}>APZ100::{}:{}{{{}".format(
self.from_call,
self.to_call.ljust(9), self.to_call.ljust(9),
self._filter_for_send().rstrip("\n"), self._filter_for_send().rstrip("\n"),
str(self.msgNo), str(self.msgNo),
@ -301,7 +304,7 @@ class StatusPacket(PathPacket):
messagecapable: bool = False messagecapable: bool = False
comment: str = None comment: str = None
def _build_raw(self): def _build_payload(self):
raise NotImplementedError raise NotImplementedError
@ -400,16 +403,24 @@ class GPSPacket(PathPacket):
time_zulu = result_utc_datetime.strftime("%d%H%M") time_zulu = result_utc_datetime.strftime("%d%H%M")
return time_zulu return time_zulu
def _build_raw(self): def _build_payload(self):
"""The payload is the non headers portion of the packet."""
time_zulu = self._build_time_zulu() time_zulu = self._build_time_zulu()
lat = self.latitude
long = self.longitude
self.payload = (
f"@{time_zulu}z{lat}{self.symbol_table}"
f"{long}{self.symbol}"
)
if self.comment:
self.payload = f"{self.payload}{self.comment}"
def _build_raw(self):
self.raw = ( self.raw = (
f"{self.from_call}>{self.to_call},WIDE2-1:" f"{self.from_call}>{self.to_call},WIDE2-1:"
f"@{time_zulu}z{self.latitude}{self.symbol_table}" f"{self.payload}"
f"{self.longitude}{self.symbol}"
) )
if self.comment:
self.raw = f"{self.raw}{self.comment}"
@dataclass @dataclass
@ -422,7 +433,7 @@ class MicEPacket(GPSPacket):
# 0 to 360 # 0 to 360
course: int = 0 course: int = 0
def _build_raw(self): def _build_payload(self):
raise NotImplementedError raise NotImplementedError
@ -436,6 +447,19 @@ class ObjectPacket(GPSPacket):
# 0 to 360 # 0 to 360
course: int = 0 course: int = 0
def _build_payload(self):
time_zulu = self._build_time_zulu()
lat = self.convert_latitude(self.latitude)
long = self.convert_longitude(self.longitude)
self.payload = (
f"*{time_zulu}z{lat}{self.symbol_table}"
f"{long}{self.symbol}"
)
if self.comment:
self.payload = f"{self.payload}{self.comment}"
def _build_raw(self): def _build_raw(self):
""" """
REPEAT builds packets like REPEAT builds packets like
@ -446,17 +470,11 @@ class ObjectPacket(GPSPacket):
callsign is the station callsign for the object callsign is the station callsign for the object
The frequency, uplink_tone, offset is part of the comment The frequency, uplink_tone, offset is part of the comment
""" """
time_zulu = self._build_time_zulu()
lat = self.convert_latitude(self.latitude)
long = self.convert_longitude(self.longitude)
self.raw = ( self.raw = (
f"{self.from_call}>APZ100:;{self.to_call:9s}" f"{self.from_call}>APZ100:;{self.to_call:9s}"
f"*{time_zulu}z{lat}{self.symbol_table}" f"{self.payload}"
f"{long}{self.symbol}"
) )
if self.comment:
self.raw = f"{self.raw}{self.comment}"
@dataclass() @dataclass()
@ -474,7 +492,7 @@ class WeatherPacket(GPSPacket):
pressure: float = 0.00 pressure: float = 0.00
comment: str = None comment: str = None
def _build_raw(self): def _build_payload(self):
"""Build an uncompressed weather packet """Build an uncompressed weather packet
Format = Format =
@ -502,7 +520,6 @@ class WeatherPacket(GPSPacket):
time_zulu = self._build_time_zulu() time_zulu = self._build_time_zulu()
contents = [ contents = [
f"{self.from_call}>{self.to_call},WIDE1-1,WIDE2-1:",
f"@{time_zulu}z{self.latitude}{self.symbol_table}", f"@{time_zulu}z{self.latitude}{self.symbol_table}",
f"{self.longitude}{self.symbol}", f"{self.longitude}{self.symbol}",
f"{self.wind_direction:03d}", f"{self.wind_direction:03d}",
@ -523,11 +540,16 @@ class WeatherPacket(GPSPacket):
# Barometric pressure (in tenths of millibars/tenths of hPascal) # Barometric pressure (in tenths of millibars/tenths of hPascal)
f"b{self.pressure:05.0f}", f"b{self.pressure:05.0f}",
] ]
if self.comment: if self.comment:
contents.append(self.comment) contents.append(self.comment)
self.payload = "".join(contents)
self.raw = "".join(contents) def _build_raw(self):
self.raw = (
f"{self.from_call}>{self.to_call},WIDE1-1,WIDE2-1:"
f"{self.payload}"
)
TYPE_LOOKUP = { TYPE_LOOKUP = {

View File

@ -246,7 +246,6 @@ class APRSDStats:
}, },
"plugins": plugin_stats, "plugins": plugin_stats,
} }
LOG.debug(f"STATS = {stats}")
LOG.info("APRSD Stats: DONE") LOG.info("APRSD Stats: DONE")
return stats return stats