1#![allow(dead_code)]
2use bytes::{BufMut, BytesMut};
8use downcast_rs::{impl_downcast, DowncastSync};
9use rand::Rng;
10use serialport::prelude::*;
11use std::convert::TryFrom;
12
13pub static BROADCAST_ADDR: u64 = 0xffff;
14
15static DELIM: u8 = 0x7e;
16
17#[derive(Debug)]
18pub enum Error {
19 FrameError(String),
20 PayloadError(String),
21 IOError(std::io::Error),
22 SerialPortError(serialport::Error),
23 DerefError,
24}
25
26impl std::error::Error for Error {}
27
28impl std::fmt::Display for Error {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match *self {
31 Error::FrameError(ref err) => write!(f, "{}", err),
32 Error::PayloadError(ref err) => write!(f, "{}", err),
33 Error::IOError(ref err) => write!(f, "{}", err),
34 Error::SerialPortError(ref err) => write!(f, "{}", err),
35 Error::DerefError => write!(f, "Unable to deref trait"),
36 }
37 }
38}
39
40impl From<std::io::Error> for Error {
41 fn from(err: std::io::Error) -> Self {
42 Error::IOError(err)
43 }
44}
45
46impl From<serialport::Error> for Error {
47 fn from(err: serialport::Error) -> Self {
48 Error::SerialPortError(err)
49 }
50}
51
52pub type Result<T> = std::result::Result<T, Error>;
53
54#[derive(Debug, PartialEq)]
55pub enum FrameId {
56 TransmitRequest,
57 TransmitStatus,
58 AtCommand,
59 AtCommandResponse,
60 RemoteAtCommand,
61 RemoteAtCommandResponse,
62 Null,
63}
64
65impl FrameId {
66 fn id(&self) -> u8 {
67 match *self {
68 FrameId::TransmitRequest => 0x90,
69 FrameId::TransmitStatus => 0x8b,
70 FrameId::AtCommand => 0x08,
71 FrameId::AtCommandResponse => 0x88,
72 FrameId::RemoteAtCommand => 0x17,
73 FrameId::RemoteAtCommandResponse => 0x97,
74 FrameId::Null => 0xff,
75 }
76 }
77}
78
79pub trait RecieveApiFrame: std::fmt::Debug + DowncastSync {
80 fn recieve(ser: Box<dyn SerialPort>) -> Result<Self>
81 where
82 Self: std::marker::Sized;
83
84 fn id(&self) -> FrameId;
85 fn summary(&self) {
86 println!("{:#x?}", self);
87 }
88 fn payload(&self) -> Result<BytesMut>;
89}
90
91impl_downcast!(sync RecieveApiFrame);
92
93pub trait TransmitApiFrame {
94 fn gen(&self) -> Result<BytesMut>;
95 fn delim(&self) -> u8 {
96 0x7e
97 }
98 fn id(&self) -> FrameId;
99 fn calc_checksum(&self, frame: &[u8]) -> Result<u8> {
100 if frame.len() < 5 {
101 return Err(Error::FrameError(
102 "Frame length does not meet minimum requirements".to_string(),
103 ));
104 }
105
106 let mut checksum: u64 = 0;
107 for (pos, byte) in frame.iter().enumerate() {
108 if pos > 2 {
109 checksum += *byte as u64;
110 }
111 }
112
113 Ok(0xff - (checksum as u8))
114 }
115
116 fn gen_frame_id(&self) -> u8 {
117 let mut rng = rand::thread_rng();
118 let r: u8 = rng.gen();
119 r
120 }
121}
122
123pub struct AtCommand<'a> {
129 pub command: &'a str,
130 pub parameter: &'a Option<&'a [u8]>,
131 pub rcr_len: usize, }
133
134#[derive(Debug)]
135pub enum AtCommands<'a> {
136 Discover(Option<&'a [u8]>),
137 AtCmd((&'a str, Option<&'a [u8]>)),
138 CmdMode(bool),
139}
140
141impl AtCommands<'_> {
142 pub fn create(&self) -> AtCommand {
143 match *self {
144 AtCommands::CmdMode(ref state) => match state {
145 true => AtCommand {
146 command: "+++",
147 parameter: &None,
148 rcr_len: 1,
149 },
150 false => AtCommand {
151 command: "CN",
152 parameter: &None,
153 rcr_len: 1,
154 },
155 },
156 AtCommands::Discover(ref param) => AtCommand {
157 command: "ND",
158 parameter: param,
159 rcr_len: 10 + 1,
160 },
161 AtCommands::AtCmd((ref cmd, ref param)) => AtCommand {
162 command: cmd,
163 parameter: param,
164 rcr_len: 1,
165 },
166 }
167 }
168}
169#[derive(Debug)]
172pub struct NullRecieve;
173impl RecieveApiFrame for NullRecieve {
174 fn id(&self) -> FrameId {
175 FrameId::Null
176 }
177 fn recieve(mut _ser: Box<dyn SerialPort>) -> Result<Self> {
178 Ok(Self)
179 }
180
181 fn summary(&self) {
182 println!("{:#?}", self);
183 }
184
185 fn payload(&self) -> Result<BytesMut> {
186 Err(Error::FrameError(
187 "Uncallabe method for Null Recieve Frame".to_string(),
188 ))
189 }
190}
191
192#[derive(Debug)]
195pub struct TransmitStatus {
196 frame_id: u8,
197 transmit_retry_count: u8,
198 deliver_status: u8,
199 discovery_status: u8,
200 payload: Option<BytesMut>,
201}
202
203impl RecieveApiFrame for TransmitStatus {
204 fn id(&self) -> FrameId {
205 FrameId::TransmitStatus
206 }
207
208 fn recieve(mut ser: Box<dyn SerialPort>) -> Result<Self> {
209 let mut response: [u8; 11] = [0; 11];
211 ser.read_exact(&mut response)?;
212 Ok(Self {
213 frame_id: response[4],
214 transmit_retry_count: response[7],
215 deliver_status: response[8],
216 discovery_status: response[9],
217 payload: Some(BytesMut::from(&response[..])),
218 })
219 }
220
221 fn payload(&self) -> Result<BytesMut> {
222 match &self.payload {
223 Some(p) => Ok(p.clone()),
224 None => Err(Error::FrameError("Empty payload".to_string())),
225 }
226 }
227}
228
229pub enum MessagingMode {
232 PointToPoint,
233 Repeater,
234 DigiMesh,
235}
236
237pub struct TransmitRequestOptions {
238 pub disable_ack: bool,
239 pub disable_route_discovery: bool,
240 pub enable_unicast_nack: bool,
241 pub enable_unicast_trace_route: bool,
242 pub mode: MessagingMode,
243}
244
245impl TransmitRequestOptions {
246 pub fn compile(&self) -> u8 {
247 let mut val: u8 = 0;
248
249 if self.disable_ack == true {
250 val |= 1 << 0;
251 }
252 if self.disable_route_discovery == true {
253 val |= 1 << 1;
254 }
255 if self.enable_unicast_nack == true {
256 val |= 1 << 2;
257 }
258
259 if self.enable_unicast_trace_route == true {
260 val |= 1 << 3;
261 }
262
263 match self.mode {
264 MessagingMode::PointToPoint => (0x1 << 6) | val,
265 MessagingMode::Repeater => (0x2 << 6) | val,
266 MessagingMode::DigiMesh => (0x3 << 6) | val,
267 }
268 }
269}
270
271pub struct TransmitRequestFrame<'a> {
272 pub dest_addr: u64,
273 pub broadcast_radius: u8,
274 pub options: Option<&'a TransmitRequestOptions>,
275 pub payload: &'a [u8],
276}
277
278impl TransmitApiFrame for TransmitRequestFrame<'_> {
279 fn id(&self) -> FrameId {
280 FrameId::TransmitRequest
281 }
282
283 fn gen(&self) -> Result<BytesMut> {
284 let mut packet = BytesMut::new();
285 let mut rng = rand::thread_rng();
286 if self.payload.len() > 65535 - 112 {
287 return Err(Error::PayloadError("Payload exceeds max size".to_string()));
288 }
289
290 let frame_id: u8 = rng.gen();
291
292 packet.put_u8(self.delim());
293 packet.put_u16((self.payload.len() as u16) + (0x0e as u16));
294 packet.put_u8(0x10);
295 packet.put_u8(frame_id);
296 packet.put_u64(self.dest_addr);
297 packet.put_u16(0xfffe);
298 packet.put_u8(self.broadcast_radius);
299
300 match self.options {
301 Some(opts) => packet.put_u8(opts.compile()),
302 None => packet.put_u8(0),
303 }
304 packet.put(self.payload);
305
306 let chksum = self.calc_checksum(&packet[..])?;
307 packet.put_u8(chksum);
308
309 Ok(packet)
310 }
311}
312
313pub struct RemoteCommandOptions {
315 pub apply_changes: bool,
316}
317
318pub struct RemoteAtCommandFrame<'a> {
319 pub dest_addr: u64,
320 pub options: &'a RemoteCommandOptions,
321 pub atcmd: &'a str,
322 pub cmd_param: Option<&'a [u8]>,
323}
324
325impl TransmitApiFrame for RemoteAtCommandFrame<'_> {
326 fn id(&self) -> FrameId {
327 FrameId::RemoteAtCommand
328 }
329
330 fn gen(&self) -> Result<BytesMut> {
331 let mut packet = BytesMut::with_capacity(64);
332 let frame_id: u8 = self.gen_frame_id();
333 packet.put_u8(DELIM);
334 packet.put_u16(0); packet.put_u8(self.id().id());
336 packet.put_u8(frame_id);
337 packet.put_u64(self.dest_addr);
338 packet.put_u16(0xfffe);
339
340 if self.options.apply_changes == true {
341 packet.put_u8(0x02);
342 } else {
343 packet.put_u8(0);
344 }
345
346 packet.put(self.atcmd.as_bytes());
347
348 if let Some(param) = self.cmd_param {
349 packet.put(¶m[..]);
350 }
351
352 let packet_len = (packet.len() - 3) as u16;
354 packet[1] = (packet_len >> 8) as u8;
355 packet[2] = (packet_len & 0xff) as u8;
356 let chksum = self.calc_checksum(&packet[..])?;
358 packet.put_u8(chksum);
359
360 Ok(packet)
361 }
362}
363
364pub struct RemoteAtCommandResponse {
366 frame_id: u8,
367 pub dest_addr: u64,
368 pub at_command: Vec<u8>,
369 command_status: u8,
370 pub command_data: Option<BytesMut>,
371 payload: Option<BytesMut>,
372}
373
374impl std::fmt::Debug for RemoteAtCommandResponse {
375 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
376 let atcmd = std::str::from_utf8(&self.at_command[..]).ok();
377
378 let cmd_data = match self.command_data {
379 Some(ref data) => format!("{:x?}", &data[..]),
380 None => format!("None"),
381 };
382
383 f.debug_struct("AtCommandResponse")
384 .field("FrameId", &format!("0x{:02x?}", self.frame_id))
385 .field("Dest Addr", &format!("0x{:016x?}", self.dest_addr))
386 .field("AtCommand", &format!("{}", atcmd.unwrap()))
387 .field("Command Status", &format!("{}", self.command_status))
388 .field("Command Data", &cmd_data)
389 .finish()
390 }
391}
392
393impl RecieveApiFrame for RemoteAtCommandResponse {
394 fn id(&self) -> FrameId {
395 FrameId::RemoteAtCommandResponse
396 }
397
398 fn recieve(mut ser: Box<dyn SerialPort>) -> Result<Self> {
399 let mut buffer = BytesMut::with_capacity(1024);
400 let mut mini_buf: [u8; 1] = [0];
401 loop {
402 if let Err(err) = ser.read_exact(&mut mini_buf) {
403 if err.kind() == std::io::ErrorKind::TimedOut {
404 break;
405 } else {
406 return Err(Error::IOError(err));
407 }
408 }
409 buffer.put_u8(mini_buf[0]);
410 }
411
412 let mut cmd_data = None;
413 if buffer.len() > 18 {
414 cmd_data = Some(BytesMut::from(&buffer[18..buffer.len() - 1]));
415 }
416 let mut at_cmd: Vec<u8> = Vec::new();
417 at_cmd.push(buffer[15]);
418 at_cmd.push(buffer[16]);
419 let dest_buf = &buffer[5..13];
420 let dest_addr = u64::from_be_bytes(<[u8; 8]>::try_from(dest_buf).unwrap()); Ok(Self {
422 frame_id: buffer[4],
423 dest_addr: dest_addr,
424 at_command: at_cmd,
425 command_status: buffer[17],
426 command_data: cmd_data,
427 payload: Some(buffer),
428 })
429 }
430
431 fn payload(&self) -> Result<BytesMut> {
432 match &self.payload {
433 Some(p) => Ok(p.clone()),
434 None => Err(Error::FrameError("Empty payload".to_string())),
435 }
436 }
437}
438pub struct AtCommandFrame<'a>(pub &'a str, pub Option<&'a [u8]>);
441impl TransmitApiFrame for AtCommandFrame<'_> {
442 fn id(&self) -> FrameId {
443 FrameId::AtCommand
444 }
445
446 fn gen(&self) -> Result<BytesMut> {
447 let mut packet = BytesMut::with_capacity(9);
448 let frame_id: u8 = self.gen_frame_id();
449 packet.put_u8(DELIM);
450 packet.put_u16(0); packet.put_u8(self.id().id());
452 packet.put_u8(frame_id);
453 packet.put(self.0.as_bytes());
454 if let Some(param) = self.1 {
455 packet.put(¶m[..])
456 }
457
458 let packet_len = (packet.len() - 3) as u16;
459 packet[1] = (packet_len >> 8) as u8;
460 packet[2] = (packet_len & 0xff) as u8;
461 let chksum = self.calc_checksum(&packet[..])?;
462 packet.put_u8(chksum);
463 Ok(packet)
464 }
465}
466
467pub struct AtCommandResponse {
469 pub frame_id: u8,
470 pub at_command: Vec<u8>,
471 pub command_status: u8,
472 pub command_data: Option<BytesMut>,
473 pub payload: Option<BytesMut>,
474}
475
476impl std::fmt::Debug for AtCommandResponse {
477 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
478 let atcmd = std::str::from_utf8(&self.at_command[..]).ok();
479
480 let cmd_data = match self.command_data {
481 Some(ref data) => format!("{:x?}", &data[..]),
482 None => format!("None"),
483 };
484
485 f.debug_struct("AtCommandResponse")
486 .field("FrameId", &format!("0x{:02x?}", self.frame_id))
487 .field("AtCommand", &format!("{}", atcmd.unwrap()))
488 .field("Command Status", &format!("{}", self.command_status))
489 .field("Command Data", &cmd_data)
490 .finish()
491 }
492}
493
494impl RecieveApiFrame for AtCommandResponse {
495 fn id(&self) -> FrameId {
496 FrameId::AtCommandResponse
497 }
498
499 fn recieve(mut ser: Box<dyn SerialPort>) -> Result<Self> {
500 let mut buffer = BytesMut::with_capacity(256);
501 let mut mini_buf: [u8; 1] = [0];
502 loop {
503 if let Err(err) = ser.read_exact(&mut mini_buf) {
504 if err.kind() == std::io::ErrorKind::TimedOut {
505 break;
506 } else {
507 return Err(Error::IOError(err));
508 }
509 }
510 buffer.put_u8(mini_buf[0]);
511 }
512 let mut cmd_data = None;
513 if buffer.len() > 9 {
514 cmd_data = Some(BytesMut::from(&buffer[8..buffer.len() - 1]));
515 }
516
517 if buffer.len() == 0 {
518 return Err(Error::FrameError("No frame detected".to_string()));
519 }
520 let mut at_cmd: Vec<u8> = Vec::new();
521 at_cmd.push(buffer[5]);
522 at_cmd.push(buffer[6]);
523 Ok(Self {
524 frame_id: buffer[4],
525 at_command: at_cmd,
526 command_status: buffer[7],
527 command_data: cmd_data,
528 payload: Some(buffer),
529 })
530 }
531
532 fn payload(&self) -> Result<BytesMut> {
533 match &self.payload {
534 Some(p) => Ok(p.clone()),
535 None => Err(Error::FrameError("Emtpy payload".to_string())),
536 }
537 }
538}