Skip to content

Commit 3b31db7

Browse files
authored
Update main.rs
1 parent 4c61d00 commit 3b31db7

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

rust_nmea_tokenizer/src/main.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
#[derive(Debug)]
23
pub struct NmeaSentence {
34
pub sentence_type: char,
@@ -28,12 +29,24 @@ pub struct SeatalkMessage {
2829
pub checksum: String,
2930
}
3031

32+
#[derive(Debug)]
33+
pub struct DscMessage {
34+
pub format_specifier: String,
35+
pub address: String,
36+
pub category: String,
37+
pub self_id: String,
38+
pub subsequent_communications: String,
39+
pub data_fields: Vec<String>,
40+
pub checksum: Option<String>,
41+
}
42+
3143
#[derive(Debug)]
3244
pub enum MessageType {
3345
Nmea(NmeaSentence),
3446
Ais(NmeaSentence),
3547
Inmarsat(InmarsatMessage),
3648
Seatalk(SeatalkMessage),
49+
Dsc(DscMessage),
3750
}
3851

3952
pub fn parse_inmarsat_header(header: &str) -> Result<InmarsatHeader, &'static str> {
@@ -119,6 +132,64 @@ pub fn parse_nmea_sentence(sentence: &str) -> Result<NmeaSentence, &'static str>
119132
})
120133
}
121134

135+
pub fn parse_dsc_message(message: &str) -> Result<DscMessage, &'static str> {
136+
// DSC messages start with $ and have DSC as talker ID
137+
if !message.starts_with('$') {
138+
return Err("DSC message must start with '$'");
139+
}
140+
141+
let content = &message[1..]; // Remove the leading '$'
142+
143+
// Split into data part and checksum part
144+
let (data_part, checksum_part) = match content.split_once('*') {
145+
Some((data, checksum)) => (data, Some(checksum)),
146+
None => (content, None),
147+
};
148+
149+
// Split data part into fields
150+
let fields: Vec<&str> = data_part.split(',').collect();
151+
if fields.len() < 6 {
152+
return Err("DSC message must have at least 6 fields");
153+
}
154+
155+
// Verify talker ID is DSC
156+
if fields[0] != "DSC" {
157+
return Err("DSC message must have 'DSC' as talker ID");
158+
}
159+
160+
// Extract required DSC fields
161+
let format_specifier = fields[1].to_string();
162+
let address = fields[2].to_string();
163+
let category = fields[3].to_string();
164+
let self_id = fields[4].to_string();
165+
let subsequent_communications = fields[5].to_string();
166+
167+
// Process remaining data fields
168+
let data_fields = fields[6..]
169+
.iter()
170+
.map(|field| field.to_string())
171+
.collect();
172+
173+
// Process checksum if present
174+
let checksum = checksum_part.and_then(|cs| {
175+
if cs.len() >= 2 {
176+
Some(cs[0..2].to_string())
177+
} else {
178+
None
179+
}
180+
});
181+
182+
Ok(DscMessage {
183+
format_specifier,
184+
address,
185+
category,
186+
self_id,
187+
subsequent_communications,
188+
data_fields,
189+
checksum,
190+
})
191+
}
192+
122193
pub fn parse_inmarsat_message(message: &str) -> Result<InmarsatMessage, &'static str> {
123194
// Split the message into header and payload
124195
let (header_part, payload_part) = match message.split_once('/') {
@@ -173,6 +244,10 @@ pub fn detect_and_parse_message(message: &str) -> Result<MessageType, &'static s
173244
// SeaTalk message
174245
let seatalk_message = parse_seatalk_message(message)?;
175246
Ok(MessageType::Seatalk(seatalk_message))
247+
} else if message.starts_with("$DSC") {
248+
// DSC message
249+
let dsc_message = parse_dsc_message(message)?;
250+
Ok(MessageType::Dsc(dsc_message))
176251
} else {
177252
// NMEA message
178253
let nmea_sentence = parse_nmea_sentence(message)?;
@@ -202,6 +277,8 @@ fn main() {
202277
"/g:1-9-1234,s:egcterm1,n:213,c:1333636200*hh/$CSSM3,123456,005213,798,0,3,14,00,2012,04,05,14,30,3400,N,076,W,300*hh",
203278
// SeaTalk example
204279
"$STALK,84,56,e,0,0,0,0,0,8*0F",
280+
// DSC example
281+
"$DSC,12,3380405810,00,1234567890,72,1234567890,00,00,00,00,00,00,00*3B",
205282
];
206283

207284
for example in examples {
@@ -212,6 +289,7 @@ fn main() {
212289
MessageType::Ais(ais) => println!("AIS Sentence: {:?}", ais),
213290
MessageType::Inmarsat(inmarsat) => println!("Inmarsat Message: {:?}", inmarsat),
214291
MessageType::Seatalk(seatalk) => println!("SeaTalk Message: {:?}", seatalk),
292+
MessageType::Dsc(dsc) => println!("DSC Message: {:?}", dsc),
215293
},
216294
Err(e) => eprintln!("Error parsing message: {}", e),
217295
}

0 commit comments

Comments
 (0)