1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
//! The Logical Link Control and Adaptation Protocol (L2CAP).
//!
//! Note that LE and Classic Bluetooth differ quite a bit on this layer, even though they're
//! supposed to share L2CAP. We're only implementing the LE bits.
//!
//! L2CAP provides "channels" to the upper layers that are mapped to the physical transport below
//! the L2CAP layer (the LE Link Layer or whatever Classic Bluetooth does). A channel is identified
//! by a 16-bit ID (also see [`Channel`]), a few of which are reserved.
//!
//! A minimal implementation for Classic Bluetooth must support the L2CAP signaling channel
//! (`0x0001`). A minimal implementation for BLE has to support the L2CAP LE signaling channel
//! (`0x0005`), the Attribute Protocol channel (`0x0004`), and the LE Security Manager channel
//! (`0x0006`).
//!
//! Establishing new connection-oriented channels, as well as transferring data over the
//! connectionless channel (`0x0002`) makes use of *Protocol/Service Multiplexers* (PSMs), which are
//! numbers identifying the protocol or service to use. These numbers are either defined by the
//! Bluetooth SIG or allocated dynamically for use with the Service Discovery Protocol (SDP). The
//! preallocated numbers are hosted online [here][l2c].
//!
//! [l2c]: https://www.bluetooth.com/specifications/assigned-numbers/logical-link-control

mod signaling;

use self::signaling::SignalingState;
use crate::att::{self, AttributeProvider, AttributeServer, NoAttributes};
use crate::link::queue::{Consume, Producer};
use crate::link::{data::Llid, MIN_DATA_PAYLOAD_BUF};
use crate::security::{NoSecurity, SecurityLevel, SecurityManager};
use crate::{bytes::*, utils::HexSlice, Error};
use core::fmt;
use core::ops::{Deref, DerefMut};

/// An L2CAP channel identifier (CID).
///
/// Channels are basically like TCP ports. A `Protocol` can listen on a channel and is connected to
/// a channel on the other device to which all responses are addressed.
///
/// A number of channel identifiers are reserved for predefined functions:
///
/// * `0x0000`: The null identifier. Must never be used as a destination endpoint.
/// * `0x0001`: L2CAP signaling channel (Classic Bluetooth only).
/// * `0x0002`: Connectionless channel (Classic Bluetooth only).
/// * `0x0003`: AMP manager (not relevant for Classic and LE Bluetooth).
/// * `0x0004`: Attribute protocol (ATT). BLE only.
/// * `0x0005`: LE L2CAP signaling channel.
/// * `0x0006`: LE Security Manager protocol.
/// * `0x0007`: Classic Bluetooth Security Manager protocol.
/// * `0x0008`-`0x003E`: Reserved.
/// * `0x003F`: AMP test manager (not relevant for Classic and LE Bluetooth).
///
/// For BLE, channels `0x0040`-`0x007F` are dynamically allocated, while `0x0080` and beyond are
/// reserved and should not be used (as of *Bluetooth 4.2*).
///
/// For classic Bluetooth, all channels `0x0040`-`0xFFFF` are available for dynamic allocation.
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
pub struct Channel(u16);

impl Channel {
    /// The null channel identifier. Must not be used as a destination endpoint.
    pub const NULL: Self = Channel(0x0000);

    /// The channel used by the Attribute Protocol (ATT).
    pub const ATT: Self = Channel(0x0004);

    /// LE L2CAP signaling channel (connectionless).
    pub const LE_SIGNALING: Self = Channel(0x0005);

    /// LE Security Manager channel.
    pub const LE_SECURITY_MANAGER: Self = Channel(0x0006);

    /// Returns the channel identifier (CID) as a raw `u16`.
    pub fn as_raw(&self) -> u16 {
        self.0
    }

    /// Returns whether this channel is connection-oriented.
    ///
    /// L2CAP PDUs addressed to connection-oriented channels are called *B-frames* if the channel is
    /// in "Basic Mode", and can be either *S-frames* or *I-frames* if the channel is in
    /// retransmission/flow control/streaming modes.
    pub fn is_connection_oriented(&self) -> bool {
        !self.is_connectionless()
    }

    /// Returns whether this channel is connectionless.
    ///
    /// L2CAP PDUs addressed to connectionless channels are called *G-frames*.
    pub fn is_connectionless(&self) -> bool {
        matches!(self.0, 0x0002 | 0x0001 | 0x0005)
    }
}

impl fmt::Debug for Channel {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:#06X}", self.0)
    }
}

impl defmt::Format for Channel {
    fn format(&self, fmt: defmt::Formatter<'_>) {
        defmt::write!(fmt, "{:#06X}", self.0)
    }
}

impl FromBytes<'_> for Channel {
    fn from_bytes(bytes: &mut ByteReader<'_>) -> Result<Self, Error> {
        Ok(Channel(bytes.read_u16_le()?))
    }
}

impl ToBytes for Channel {
    fn to_bytes(&self, writer: &mut ByteWriter<'_>) -> Result<(), Error> {
        writer.write_u16_le(self.0)
    }
}

/// Trait for L2CAP channel mappers that provide access to the protocol or service behind a CID.
pub trait ChannelMapper {
    /// The attribute provider used by the ATT server.
    type AttributeProvider: AttributeProvider;

    /// Look up what's connected to `channel` (eg. the `Protocol` to which to forward).
    fn lookup(&mut self, channel: Channel) -> Option<ChannelData<'_, dyn ProtocolObj + '_>>;

    /// Returns information about the Attribute Protocol on channel `0x0004`.
    fn att(&mut self) -> ChannelData<'_, AttributeServer<Self::AttributeProvider>>;
}

/// Data associated with a connected L2CAP channel.
pub struct ChannelData<'a, P: ?Sized> {
    /// Channel to which responses should be addressed.
    ///
    /// For fixed, predefined channels, this is always the same value for both devices, but
    /// dynamically allocated channels can have different CIDs on both devices.
    response_channel: Channel,

    /// The protocol listening on this channel.
    protocol: &'a mut P,

    /// Outgoing PDU size of the protocol.
    ///
    /// This is the number of bytes that must be available to the protocol in the TX buffer to
    /// guarantee that all of the protocol's PDUs will fit.
    pdu: u8,
}

impl<'a> ChannelData<'a, dyn ProtocolObj + 'a> {
    /// Creates a `ChannelData` carrying a dynamically-dispatched `dyn ProtocolObj` from a concrete
    /// `Protocol` implementor `T`.
    fn new_dyn<T: Protocol + 'a>(response_channel: Channel, protocol: &'a mut T) -> Self {
        assert!(
            usize::from(T::RSP_PDU_SIZE + Header::SIZE) <= MIN_DATA_PAYLOAD_BUF,
            "protocol min PDU is smaller than data channel PDU (L2CAP reassembly NYI)"
        );

        ChannelData {
            response_channel,
            pdu: T::RSP_PDU_SIZE,
            protocol,
        }
    }
}

impl<'a, P: Protocol> ChannelData<'a, P> {
    fn new(response_channel: Channel, protocol: &'a mut P) -> Self {
        assert!(
            usize::from(P::RSP_PDU_SIZE + Header::SIZE) <= MIN_DATA_PAYLOAD_BUF,
            "protocol min PDU is smaller than data channel PDU (L2CAP reassembly NYI)"
        );

        ChannelData {
            response_channel,
            pdu: P::RSP_PDU_SIZE,
            protocol,
        }
    }
}

impl<'a, P: ?Sized> ChannelData<'a, P> {
    /// Returns the `Channel` to which the response should be sent.
    pub fn response_channel(&self) -> Channel {
        self.response_channel
    }

    /// Returns the PDU size required by the protocol.
    ///
    /// This is the minimum size in Bytes the protocol needs to have provided for any of its
    /// outgoing PDUs. `Protocol` implementations may make use of additional space as well, but this
    /// is the very minimum.
    ///
    /// The L2CAP implementation will not forward incoming PDUs to the protocol unless this amount
    /// of space is available in the TX buffer. This guarantees that the response will always fit.
    pub fn pdu_size(&self) -> u8 {
        self.pdu
    }

    /// Returns the protocol connected to the channel.
    pub fn protocol(&mut self) -> &mut P {
        self.protocol
    }

    /// Consumes `self` and returns the protocol connected to the channel, with lifetime `'a`.
    ///
    /// This can be useful when the lifetime of the reference must not be tied to `self`, as would
    /// be the case with `protocol()`.
    pub fn into_protocol(self) -> &'a mut P {
        self.protocol
    }
}

/// A fixed BLE channel map that provides only the required channel endpoints and does not allow
/// dynamic channels.
///
/// The channels are mapped as follows (no other channels are supported):
///
/// * `0x0004`: Attribute protocol (ATT).
/// * `0x0005`: LE L2CAP signaling channel.
/// * `0x0006`: LE Security Manager protocol.
pub struct BleChannelMap<A: AttributeProvider, S: SecurityLevel> {
    att: AttributeServer<A>,
    signaling: SignalingState,
    sm: SecurityManager<S>,
}

impl BleChannelMap<NoAttributes, NoSecurity> {
    /// Creates a new channel map with no backing data for the connected protocols.
    ///
    /// This means:
    /// * The attribute server on channel `0x0004` will host an empty attribute set.
    /// * The security manager on channel `0x0006` will not support pairing or any security.
    pub fn empty() -> Self {
        Self {
            att: AttributeServer::new(NoAttributes),
            signaling: SignalingState::new(),
            sm: SecurityManager::no_security(),
        }
    }
}

impl<A: AttributeProvider> BleChannelMap<A, NoSecurity> {
    pub fn with_attributes(att: A) -> Self {
        Self {
            att: AttributeServer::new(att),
            signaling: SignalingState::new(),
            sm: SecurityManager::no_security(),
        }
    }

    /// Provides mutable access to the underlying `AttributeProvider`.
    pub fn attribute_provider(&mut self) -> &mut A {
        self.att.provider()
    }
}

impl<A: AttributeProvider, S: SecurityLevel> ChannelMapper for BleChannelMap<A, S> {
    type AttributeProvider = A;

    fn lookup(&mut self, channel: Channel) -> Option<ChannelData<'_, dyn ProtocolObj + '_>> {
        match channel {
            Channel::ATT => Some(ChannelData::new_dyn(channel, &mut self.att)),
            Channel::LE_SIGNALING => Some(ChannelData::new_dyn(channel, &mut self.signaling)),
            Channel::LE_SECURITY_MANAGER => Some(ChannelData::new_dyn(channel, &mut self.sm)),
            _ => None,
        }
    }

    fn att(&mut self) -> ChannelData<'_, AttributeServer<Self::AttributeProvider>> {
        ChannelData::new(Channel::ATT, &mut self.att)
    }
}

/// Trait for protocols that sit on top of L2CAP (object-safe part).
///
/// A protocol can be connected to an L2CAP channel via a `ChannelMapper`.
pub trait ProtocolObj {
    /// Process a message sent to the protocol.
    ///
    /// The message is reassembled by L2CAP already, and the `responder` is guaranteed to fit a
    /// protocol payload of at least `Protocol::RSP_PDU_SIZE` Bytes, as defined by the protocol.
    ///
    /// # Errors
    ///
    /// This method should only return an error when a critical problem occurs that can not be
    /// recovered from and that can not be reported back to the connected device using the protocol.
    /// This means that only things like unrecoverable protocol parsing errors should return an
    /// error here.
    fn process_message(&mut self, message: &[u8], responder: Sender<'_>) -> Result<(), Error>;
}

/// Trait for protocols that sit on top of L2CAP (non-object-safe part).
///
/// This extends the `ProtocolObj` trait with other protocol properties.
pub trait Protocol: ProtocolObj {
    /// Minimum size needed by PDUs sent by this protocol.
    ///
    /// Incoming PDUs will only be forwarded to the protocol if there is at least this much space in
    /// the TX buffer.
    const RSP_PDU_SIZE: u8;
}

/// Header used by *all* L2CAP PDUs.
#[derive(Debug)]
struct Header {
    /// Length of the payload following the length and channel fields (after reassembly).
    length: u16,
    /// Destination endpoint of the PDU.
    channel: Channel,
}

impl Header {
    /// The size of an L2CAP message header in Bytes.
    const SIZE: u8 = 2 + 2;
}

impl<'a> FromBytes<'a> for Header {
    fn from_bytes(bytes: &mut ByteReader<'a>) -> Result<Self, Error> {
        let length = bytes.read_u16_le()?;
        let channel = Channel::from_bytes(bytes)?;
        Ok(Self { length, channel })
    }
}

impl ToBytes for Header {
    fn to_bytes(&self, writer: &mut ByteWriter<'_>) -> Result<(), Error> {
        writer.write_u16_le(self.length)?;
        writer.write_u16_le(self.channel.as_raw())?;
        Ok(())
    }
}

struct Message<P> {
    header: Header,
    payload: P,
}

impl<'a, P: FromBytes<'a>> FromBytes<'a> for Message<P> {
    fn from_bytes(bytes: &mut ByteReader<'a>) -> Result<Self, Error> {
        let header = Header::from_bytes(bytes)?;
        assert_eq!(
            header.length as usize,
            bytes.bytes_left(),
            "L2CAP reassembly not yet implemented"
        );

        Ok(Self {
            header,
            payload: P::from_bytes(bytes)?,
        })
    }
}

impl<P: ToBytes> ToBytes for Message<P> {
    fn to_bytes(&self, writer: &mut ByteWriter<'_>) -> Result<(), Error> {
        self.header.to_bytes(writer)?;
        self.payload.to_bytes(writer)?;
        Ok(())
    }
}

/// L2CAP channel manager and responder.
#[derive(Debug)]
pub struct L2CAPState<M: ChannelMapper> {
    mapper: M,
}

impl<M: ChannelMapper> L2CAPState<M> {
    /// Creates a new L2CAP state using the given channel configuration.
    pub fn new(mapper: M) -> Self {
        Self { mapper }
    }

    /// Gives this instance the ability to transmit packets.
    pub fn tx<'a, P: Producer>(&'a mut self, tx: &'a mut P) -> L2CAPStateTx<'a, M, P> {
        L2CAPStateTx { l2cap: self, tx }
    }

    /// Provides mutable access to the underlying `ChannelMapper`.
    pub fn channel_mapper(&mut self) -> &mut M {
        &mut self.mapper
    }
}

/// Provides a way to send a L2CAP message with preallocated storage.
///
/// This can be done either in response to an incoming packet (via `ProtocolObj::process_msg`), or
/// as a device-initiated packet (eg. an attribute notification).
pub struct Sender<'a> {
    /// The protocol's max. outgoing PDU size.
    pdu: u8,

    /// Data PDU channel.
    tx: &'a mut dyn Producer,

    /// Channel to which the response will be addressed.
    channel: Channel,
}

impl<'a> Sender<'a> {
    /// Creates a `Sender` from a `Producer`, ensuring that sufficient free space is available to
    /// fit a PDU described by `chdata`.
    ///
    /// If there is not enough space in `tx`, returns `None`.
    fn new<T: ?Sized>(chdata: &ChannelData<'_, T>, tx: &'a mut dyn Producer) -> Option<Self> {
        let free = tx.free_space();
        let needed = chdata.pdu_size() + Header::SIZE;
        if free < needed {
            debug!("{} free bytes, need {}", free, needed);
            return None;
        }

        let resp_channel = chdata.response_channel();
        let pdu = chdata.pdu_size();
        Some(Sender {
            pdu,
            tx,
            channel: resp_channel,
        })
    }

    /// Enqueues an L2CAP message to be sent over the data connection.
    ///
    /// L2CAP header (including the destination endpoint's channel) and the data channel PDU header
    /// will be added automatically.
    ///
    /// This will fail if there's not enough space left in the TX queue.
    pub fn send<P: ToBytes>(&mut self, payload: P) -> Result<(), Error> {
        self.send_with(|writer| payload.to_bytes(writer))
    }

    /// Enqueues an L2CAP message encoded by a closure.
    ///
    /// L2CAP header and data channel PDU header will be added automatically. The closure `f` only
    /// has to write the protocol PDU to transmit over L2CAP.
    ///
    /// The L2CAP implementation will ensure that there are exactly `Protocol::RSP_PDU_SIZE` Bytes
    /// available in the `ByteWriter` passed to the closure.
    pub fn send_with<T, E>(
        &mut self,
        f: impl FnOnce(&mut ByteWriter<'_>) -> Result<T, E>,
    ) -> Result<T, E>
    where
        E: From<Error>,
    {
        // FIXME automatic fragmentation is not implemented

        // The payload length goes into the header, so we have to skip that part and write it later
        let mut f = Some(f);
        let channel = self.channel;
        let pdu = self.pdu;
        let mut r = None;
        let r2 = self.tx.produce_dyn(
            pdu + Header::SIZE,
            &mut |writer: &mut ByteWriter<'_>| -> Result<_, Error> {
                let mut header_writer = writer.split_off(usize::from(Header::SIZE))?;

                // The PDU size is determined based on how much space is left in `writer`, so we can't
                // just `split_off` the protocol's PDU size.
                assert!(writer.space_left() >= pdu.into());
                let mut payload_writer = ByteWriter::new(&mut writer.rest()[..pdu.into()]);
                let left = payload_writer.space_left();
                let result = f.take().unwrap()(&mut payload_writer);
                let is_ok = result.is_ok();
                r = Some(result);
                let used = left - payload_writer.space_left();
                writer.skip(used).unwrap();

                assert!(used < 0xFFFF);
                Header {
                    length: used as u16,
                    channel,
                }
                .to_bytes(&mut header_writer)?;

                assert_eq!(header_writer.space_left(), 0);

                if is_ok {
                    Ok(Llid::DataStart)
                } else {
                    // The error returned doesn't matter much. It just has to be an `Err` so the PDU
                    // isn't actually sent.
                    Err(Error::InvalidValue)
                }
            },
        );

        if let Err(e) = r2 {
            if e != Error::InvalidValue {
                // Legitimate error
                return Err(e.into());
            }
        }

        r.unwrap()
    }
}

/// An `L2CAPState` with the ability to transmit packets.
///
/// Derefs to the underlying `L2CAPState`.
pub struct L2CAPStateTx<'a, M: ChannelMapper, P: Producer> {
    l2cap: &'a mut L2CAPState<M>,
    tx: &'a mut P,
}

impl<'a, M: ChannelMapper, P: Producer> L2CAPStateTx<'a, M, P> {
    /// Process the start of a new L2CAP message (or a complete, unfragmented message).
    ///
    /// If the incoming message is unfragmented, it will be forwarded to the protocol listening on
    /// the addressed channel, and a response may be sent.
    pub fn process_start(&mut self, message: &[u8]) -> Consume<()> {
        let msg = match Message::<&[u8]>::from_bytes(&mut ByteReader::new(message)) {
            Ok(msg) => msg,
            Err(e) => return Consume::always(Err(e)),
        };

        if usize::from(msg.header.length) != msg.payload.len() {
            // Lengths mismatch => Reassembly needed
            unimplemented!("L2CAP reassembly");
        }

        self.dispatch(msg.header.channel, msg.payload)
    }

    /// Process continuation of an L2CAP message.
    ///
    /// This is not yet implemented and will always panic.
    pub fn process_cont(&mut self, _data: &[u8]) -> Consume<()> {
        unimplemented!("reassembly")
    }

    /// Dispatches a fully reassembled L2CAP message to the protocol listening on the addressed
    /// channel.
    fn dispatch(&mut self, channel: Channel, payload: &[u8]) -> Consume<()> {
        if let Some(mut chdata) = self.l2cap.mapper.lookup(channel) {
            let sender = if let Some(sender) = Sender::new(&chdata, self.tx) {
                sender
            } else {
                return Consume::never(Ok(()));
            };

            Consume::always(chdata.protocol().process_message(payload, sender))
        } else {
            warn!(
                "ignoring message sent to unconnected channel {:?}: {:?}",
                channel,
                HexSlice(payload)
            );
            Consume::always(Ok(()))
        }
    }

    /// Prepares for sending data using the Attribute Protocol.
    ///
    /// This will reserve sufficient space in the outgoing PDU buffer to send any ATT PDU, and then
    /// return an `AttributeServerTx` instance that can be used to initiate an ATT-specific
    /// procedure.
    ///
    /// Returns `None` if there's not enough space in the TX packet queue to send an ATT PDU. If
    /// that happens, calling this method again at a later time (after the Link-Layer had time to
    /// transmit more packets) might succeed.
    pub fn att(&mut self) -> Option<att::AttributeServerTx<'_, M::AttributeProvider>> {
        let att = self.l2cap.mapper.att();
        Sender::new(&att, self.tx).map(move |sender| att.into_protocol().with_sender(sender))
    }
}

impl<'a, M: ChannelMapper, P: Producer> Deref for L2CAPStateTx<'a, M, P> {
    type Target = L2CAPState<M>;

    fn deref(&self) -> &Self::Target {
        &self.l2cap
    }
}

impl<'a, M: ChannelMapper, P: Producer> DerefMut for L2CAPStateTx<'a, M, P> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.l2cap
    }
}