Skip to content
This repository was archived by the owner on May 18, 2022. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 04cf1d1

Browse files
committedMar 25, 2019
Initial Build
1 parent 4a901dc commit 04cf1d1

File tree

5 files changed

+66
-44
lines changed

5 files changed

+66
-44
lines changed
 

‎src/ble/link/advertising.rs

+3
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,9 @@ impl Header {
703703
Header(u8::from(ty) as u16)
704704
}
705705

706+
/// Parses a header from raw bytes.
707+
///
708+
/// This will panic if `raw` contains less than 2 Bytes.
706709
pub fn parse(raw: &[u8]) -> Self {
707710
Header(LittleEndian::read_u16(&raw))
708711
}

‎src/ble/link/connection.rs

+47-36
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ use {
1212
time::{Duration, Instant, Timer},
1313
utils::HexSlice,
1414
},
15-
core::marker::PhantomData,
15+
core::{marker::PhantomData, mem},
1616
};
1717

1818
/// Connection state.
19-
pub struct Connection<L: Logger, T: Timer> {
19+
pub struct Connection<L: Logger, T: Timer, R: Transmitter> {
2020
access_address: u32,
2121
crc_init: u32,
2222
channel_map: ChannelMap,
@@ -44,12 +44,20 @@ pub struct Connection<L: Logger, T: Timer> {
4444
last_header: data::Header,
4545

4646
/// 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.
4750
received_packet: bool,
4851

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)>,
5058
}
5159

52-
impl<L: Logger, T: Timer> Connection<L, T> {
60+
impl<L: Logger, T: Timer, R: Transmitter> Connection<L, T, R> {
5361
/// Initializes a connection state according to the `LLData` contained in the `CONNECT_REQ`
5462
/// advertising PDU.
5563
///
@@ -80,6 +88,9 @@ impl<L: Logger, T: Timer> Connection<L, T> {
8088
next_expected_seq_num: SeqNum::ZERO,
8189
last_header: Header::new(Llid::DataCont),
8290
received_packet: false,
91+
next_packet: Pdu::empty(),
92+
wants_to_send: false,
93+
master_md: false,
8394

8495
_p: PhantomData,
8596
};
@@ -104,10 +115,9 @@ impl<L: Logger, T: Timer> Connection<L, T> {
104115
/// Called by the `LinkLayer` when a data channel packet is received.
105116
///
106117
/// 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(
108119
&mut self,
109120
rx_end: Instant,
110-
tx: &mut R,
111121
hw: &mut HwInterface<L, T>,
112122
header: data::Header,
113123
payload: &[u8],
@@ -126,25 +136,12 @@ impl<L: Logger, T: Timer> Connection<L, T> {
126136
// If CRC is bad, this bit could be flipped, so we always retransmit in that case.
127137
if self.received_packet {
128138
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();
143140
} else {
144141
// We've never received (and thus sent) a data packet before, so we can't
145142
// *re*transmit anything. Send empty PDU instead.
146143
self.received_packet = true;
147-
self.send(Pdu::empty(), tx, &mut hw.logger);
144+
self.next_packet = Pdu::empty();
148145
}
149146
} else {
150147
self.received_packet = true;
@@ -154,40 +151,54 @@ impl<L: Logger, T: Timer> Connection<L, T> {
154151

155152
self.transmit_seq_num += SeqNum::ONE;
156153

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();
159156
}
160157

161158
let last_channel = self.channel;
162159

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();
169162

170-
trace!(
163+
/*trace!(
171164
hw.logger,
172165
"DATA({}->{})<- {}{:?}, {:?}",
173166
last_channel.index(),
174167
self.channel.index(),
175168
if crc_ok { "" } else { "BADCRC, " },
176169
header,
177170
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);
180179
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 {
183182
channel: self.channel,
184183
access_address: self.access_address,
185184
crc_init: self.crc_init,
186185
},
187186
})
188187
}
189188

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+
191202
if self.received_packet {
192203
// No packet from master, skip this connection event and listen on the next channel
193204

@@ -249,7 +260,7 @@ impl<L: Logger, T: Timer> Connection<L, T> {
249260
}
250261

251262
/// 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) {
253264
let mut payload_writer = ByteWriter::new(tx.tx_payload_buf());
254265
// Serialize PDU. This should never fail, because the upper layers are supposed to fragment
255266
// packets so they always fit.

‎src/ble/link/mod.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ pub struct HwInterface<L: Logger, T: Timer> {
174174
}
175175

176176
/// Link-Layer state machine, according to the Bluetooth spec.
177-
enum State<L: Logger, T: Timer> {
177+
enum State<L: Logger, T: Timer, R: Transmitter> {
178178
/// Radio silence: Not listening, not transmitting anything.
179179
Standby,
180180

@@ -198,15 +198,15 @@ enum State<L: Logger, T: Timer> {
198198
},
199199

200200
/// Connected with another device.
201-
Connection(Connection<L, T>),
201+
Connection(Connection<L, T, R>),
202202
}
203203

204204
/// Implementation of the BLE Link-Layer logic.
205205
///
206206
/// Users of this struct must provide a way to send and receive Link-Layer PDUs via a `Transmitter`.
207207
pub struct LinkLayer<L: Logger, T: Timer, R: Transmitter> {
208208
dev_addr: DeviceAddress,
209-
state: State<L, T>,
209+
state: State<L, T, R>,
210210
hw: HwInterface<L, T>,
211211
_p: PhantomData<R>,
212212
}
@@ -334,13 +334,12 @@ impl<L: Logger, T: Timer, R: Transmitter> LinkLayer<L, T, R> {
334334
pub fn process_data_packet(
335335
&mut self,
336336
rx_end: Instant,
337-
tx: &mut R,
338337
header: data::Header,
339338
payload: &[u8],
340339
crc_ok: bool,
341340
) -> Cmd {
342341
if let State::Connection(conn) = &mut self.state {
343-
match conn.process_data_packet(rx_end, tx, &mut self.hw, header, payload, crc_ok) {
342+
match conn.process_data_packet(rx_end, &mut self.hw, header, payload, crc_ok) {
344343
Ok(cmd) => cmd,
345344
Err(()) => {
346345
debug!(self.logger(), "connection ended, standby");
@@ -390,7 +389,7 @@ impl<L: Logger, T: Timer, R: Transmitter> LinkLayer<L, T, R> {
390389
next_update: NextUpdate::At(*next_adv),
391390
}
392391
}
393-
State::Connection(conn) => match conn.timer_update(&mut self.hw) {
392+
State::Connection(conn) => match conn.timer_update(tx, &mut self.hw) {
394393
Ok(cmd) => cmd,
395394
Err(()) => {
396395
debug!(self.logger(), "connection ended (timer), standby");
@@ -479,6 +478,12 @@ pub enum RadioCmd {
479478
/// Only the least significant 24 bits are relevant.
480479
crc_init: u32,
481480
},
481+
482+
PrepareTx {
483+
channel: DataChannel,
484+
access_address: u32,
485+
crc_init: u32,
486+
},
482487
}
483488

484489
/// Trait for Link Layer packet transmission.

‎src/ble/time.rs

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use core::{
1616
pub struct Duration(u32);
1717

1818
impl Duration {
19+
/// The interframe spacing used by BLE packets (`T_IFS`).
20+
pub const T_IFS: Self = Duration(150);
21+
1922
/// Creates a `Duration` from a number of microseconds.
2023
pub fn from_micros(micros: u32) -> Self {
2124
Duration(micros)

‎src/radio.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl BleRadio {
170170
self.radio.events_disabled.reset();
171171

172172
match cmd {
173-
RadioCmd::Off => {}
173+
RadioCmd::Off | RadioCmd::PrepareTx { .. } => {}
174174
RadioCmd::ListenAdvertising { channel } => {
175175
self.prepare_txrx_advertising(channel);
176176

@@ -259,7 +259,7 @@ impl BleRadio {
259259
return NextUpdate::Keep;
260260
}
261261
};
262-
let cmd = ll.process_data_packet(timestamp, self, header, payload, crc_ok);
262+
let cmd = ll.process_data_packet(timestamp, header, payload, crc_ok);
263263
self.rx_buf = Some(rx_buf);
264264
cmd
265265
};

0 commit comments

Comments
 (0)
This repository has been archived.