kenwood_thd75/protocol/
aprs.rs1use crate::error::ProtocolError;
7use crate::types::radio_params::{BeaconMode, TncBaud};
8
9use super::Response;
10
11fn parse_u8_field(s: &str, cmd: &str, field: &str) -> Result<u8, ProtocolError> {
13 s.parse::<u8>().map_err(|_| ProtocolError::FieldParse {
14 command: cmd.to_owned(),
15 field: field.to_owned(),
16 detail: format!("invalid u8: {s:?}"),
17 })
18}
19
20fn parse_ae(payload: &str) -> Response {
25 if let Some((serial, model_code)) = payload.split_once(',') {
26 Response::SerialInfo {
27 serial: serial.to_owned(),
28 model_code: model_code.to_owned(),
29 }
30 } else {
31 Response::SerialInfo {
33 serial: payload.to_owned(),
34 model_code: String::new(),
35 }
36 }
37}
38
39pub(crate) fn parse_aprs(mnemonic: &str, payload: &str) -> Option<Result<Response, ProtocolError>> {
43 match mnemonic {
44 "AS" => Some(parse_u8_field(payload, "AS", "rate").and_then(|raw| {
45 TncBaud::try_from(raw)
46 .map(|rate| Response::TncBaud { rate })
47 .map_err(|e| ProtocolError::FieldParse {
48 command: "AS".into(),
49 field: "rate".into(),
50 detail: e.to_string(),
51 })
52 })),
53 "AE" => Some(Ok(parse_ae(payload))),
54 "PT" => Some(parse_u8_field(payload, "PT", "mode").and_then(|raw| {
55 BeaconMode::try_from(raw)
56 .map(|mode| Response::BeaconType { mode })
57 .map_err(|e| ProtocolError::FieldParse {
58 command: "PT".into(),
59 field: "mode".into(),
60 detail: e.to_string(),
61 })
62 })),
63 "MS" => Some(
64 parse_u8_field(payload, "MS", "source")
65 .map(|source| Response::PositionSource { source }),
66 ),
67 _ => None,
68 }
69}