+ if !stream_wants_to_tx && !packet_wants_to_tx {
+ return None;
+ }
+
+ // We have something we might send if the channel is free
+
+ // TODO: Proper full duplex support
+ // A true full duplex TNC should be able to rx and tx concurrently, implying
+ // separate states.
+ if !self.full_duplex {
+ match self.next_csma_check {
+ None => {
+ if self.dcd {
+ self.next_csma_check = Some(self.now + 1920);
+ return None;
+ } else {
+ // channel is idle at the moment we get a frame to send
+ // go right ahead
+ }
+ }
+ Some(at_time) => {
+ if self.now < at_time {
+ return None;
+ }
+ // 25% chance that we'll transmit this slot.
+ // Using self.now as random is probably fine so long as it's not being set in
+ // a lumpy manner. m17app's soundmodem should be fine.
+ // TODO: bring in prng to help in cases where `now` never ends in 0b11
+ let p1_4 = (self.now & 3) == 3;
+ if !self.dcd || !p1_4 {
+ self.next_csma_check = Some(self.now + 1920);
+ return None;
+ } else {
+ self.next_csma_check = None;
+ }
+ }
+ }
+ }
+
+ if stream_wants_to_tx {