@@ -12,11 +12,11 @@ use {
12
12
time:: { Duration , Instant , Timer } ,
13
13
utils:: HexSlice ,
14
14
} ,
15
- core:: marker:: PhantomData ,
15
+ core:: { marker:: PhantomData , mem } ,
16
16
} ;
17
17
18
18
/// Connection state.
19
- pub struct Connection < L : Logger , T : Timer > {
19
+ pub struct Connection < L : Logger , T : Timer , R : Transmitter > {
20
20
access_address : u32 ,
21
21
crc_init : u32 ,
22
22
channel_map : ChannelMap ,
@@ -44,12 +44,20 @@ pub struct Connection<L: Logger, T: Timer> {
44
44
last_header : data:: Header ,
45
45
46
46
/// Whether we have ever received a data packet in this connection.
47
+ ///
48
+ /// If this is `true`, the connection is considered established, which changes the handling of
49
+ /// the supervision timeout.
47
50
received_packet : bool ,
48
51
49
- _p : PhantomData < ( L , T ) > ,
52
+ next_packet : Pdu < ' static > ,
53
+ wants_to_send : bool ,
54
+
55
+ master_md : bool ,
56
+
57
+ _p : PhantomData < ( L , T , R ) > ,
50
58
}
51
59
52
- impl < L : Logger , T : Timer > Connection < L , T > {
60
+ impl < L : Logger , T : Timer , R : Transmitter > Connection < L , T , R > {
53
61
/// Initializes a connection state according to the `LLData` contained in the `CONNECT_REQ`
54
62
/// advertising PDU.
55
63
///
@@ -80,6 +88,9 @@ impl<L: Logger, T: Timer> Connection<L, T> {
80
88
next_expected_seq_num : SeqNum :: ZERO ,
81
89
last_header : Header :: new ( Llid :: DataCont ) ,
82
90
received_packet : false ,
91
+ next_packet : Pdu :: empty ( ) ,
92
+ wants_to_send : false ,
93
+ master_md : false ,
83
94
84
95
_p : PhantomData ,
85
96
} ;
@@ -104,10 +115,9 @@ impl<L: Logger, T: Timer> Connection<L, T> {
104
115
/// Called by the `LinkLayer` when a data channel packet is received.
105
116
///
106
117
/// Returns `Err(())` when the connection is ended (not necessarily due to an error condition).
107
- pub fn process_data_packet < R : Transmitter > (
118
+ pub fn process_data_packet (
108
119
& mut self ,
109
120
rx_end : Instant ,
110
- tx : & mut R ,
111
121
hw : & mut HwInterface < L , T > ,
112
122
header : data:: Header ,
113
123
payload : & [ u8 ] ,
@@ -126,25 +136,12 @@ impl<L: Logger, T: Timer> Connection<L, T> {
126
136
// If CRC is bad, this bit could be flipped, so we always retransmit in that case.
127
137
if self . received_packet {
128
138
self . last_header . set_nesn ( self . next_expected_seq_num ) ;
129
- let d = hw. timer . now ( ) . duration_since ( rx_end) ;
130
- tx. transmit_data (
131
- self . access_address ,
132
- self . crc_init ,
133
- self . last_header ,
134
- self . channel ,
135
- ) ;
136
- let before_log = hw. timer . now ( ) ;
137
- trace ! ( hw. logger, "<<RESEND {} after RX>>" , d) ;
138
- trace ! (
139
- hw. logger,
140
- "<<That LOG took {}>>" ,
141
- hw. timer. now( ) . duration_since( before_log)
142
- ) ;
139
+ //hw.logger.write_str("<<RESEND>>\n").unwrap();
143
140
} else {
144
141
// We've never received (and thus sent) a data packet before, so we can't
145
142
// *re*transmit anything. Send empty PDU instead.
146
143
self . received_packet = true ;
147
- self . send ( Pdu :: empty ( ) , tx , & mut hw . logger ) ;
144
+ self . next_packet = Pdu :: empty ( ) ;
148
145
}
149
146
} else {
150
147
self . received_packet = true ;
@@ -154,40 +151,54 @@ impl<L: Logger, T: Timer> Connection<L, T> {
154
151
155
152
self . transmit_seq_num += SeqNum :: ONE ;
156
153
157
- // Send a new packet
158
- self . send ( Pdu :: empty ( ) , tx , & mut hw . logger ) ;
154
+ // Prepare sending a new packet
155
+ self . next_packet = Pdu :: empty ( ) ;
159
156
}
160
157
161
158
let last_channel = self . channel ;
162
159
163
- // If both devices set MD to `false`, the connection event closes and we hop to the next
164
- // channel.
165
- // If the CRC is bad, we must hop anyways.
166
- if !crc_ok || ( !header. md ( ) && !self . has_more_data ( ) ) {
167
- self . hop_channel ( ) ;
168
- }
160
+ // If the CRC is bad, we hop channels, pretending that MD=false
161
+ self . master_md = crc_ok && header. md ( ) ;
169
162
170
- trace ! (
163
+ /* trace!(
171
164
hw.logger,
172
165
"DATA({}->{})<- {}{:?}, {:?}",
173
166
last_channel.index(),
174
167
self.channel.index(),
175
168
if crc_ok { "" } else { "BADCRC, " },
176
169
header,
177
170
HexSlice(payload)
178
- ) ;
179
-
171
+ );*/
172
+
173
+ // After receiving a packet from the master, we *always* send one back. Set a timer that
174
+ // expires after the IFS is over.
175
+ self . wants_to_send = true ;
176
+ let send_at = rx_end + Duration :: T_IFS ;
177
+ let d = send_at. duration_since ( hw. timer . now ( ) ) ;
178
+ trace ! ( hw. logger, "DATA<-; {}; sending in {}" , self . master_md, d) ;
180
179
Ok ( Cmd {
181
- next_update : NextUpdate :: At ( hw . timer . now ( ) + self . conn_event_timeout ( ) ) ,
182
- radio : RadioCmd :: ListenData {
180
+ next_update : NextUpdate :: At ( send_at ) ,
181
+ radio : RadioCmd :: PrepareTx {
183
182
channel : self . channel ,
184
183
access_address : self . access_address ,
185
184
crc_init : self . crc_init ,
186
185
} ,
187
186
} )
188
187
}
189
188
190
- pub fn timer_update ( & mut self , hw : & mut HwInterface < L , T > ) -> Result < Cmd , ( ) > {
189
+ pub fn timer_update ( & mut self , tx : & mut R , hw : & mut HwInterface < L , T > ) -> Result < Cmd , ( ) > {
190
+ if self . wants_to_send {
191
+ self . wants_to_send = false ;
192
+ // Send a response PDU to the master
193
+ let pdu = mem:: replace ( & mut self . next_packet , Pdu :: empty ( ) ) ;
194
+ self . send ( pdu, tx, & mut hw. logger ) ;
195
+
196
+ // Possibly hop channels here
197
+ if !self . master_md && !self . has_more_data ( ) {
198
+ self . hop_channel ( ) ;
199
+ }
200
+ }
201
+
191
202
if self . received_packet {
192
203
// No packet from master, skip this connection event and listen on the next channel
193
204
@@ -249,7 +260,7 @@ impl<L: Logger, T: Timer> Connection<L, T> {
249
260
}
250
261
251
262
/// Sends a new PDU to the connected device (ie. a non-retransmitted PDU).
252
- fn send < R : Transmitter > ( & mut self , pdu : Pdu < ' _ > , tx : & mut R , logger : & mut L ) {
263
+ fn send ( & mut self , pdu : Pdu < ' _ > , tx : & mut R , logger : & mut L ) {
253
264
let mut payload_writer = ByteWriter :: new ( tx. tx_payload_buf ( ) ) ;
254
265
// Serialize PDU. This should never fail, because the upper layers are supposed to fragment
255
266
// packets so they always fit.
0 commit comments