1use core::fmt::Display;
3use core::mem;
4
5use crate::codec;
6use crate::cursor::{ReadCursor, WriteCursor};
7use crate::types::uuid::*;
8
9pub(crate) const ATT_READ_BY_GROUP_TYPE_REQ: u8 = 0x10;
10pub(crate) const ATT_READ_BY_GROUP_TYPE_RSP: u8 = 0x11;
11pub(crate) const ATT_ERROR_RSP: u8 = 0x01;
12pub(crate) const ATT_READ_BY_TYPE_REQ: u8 = 0x08;
13pub(crate) const ATT_READ_BY_TYPE_RSP: u8 = 0x09;
14pub(crate) const ATT_READ_REQ: u8 = 0x0a;
15pub(crate) const ATT_READ_RSP: u8 = 0x0b;
16pub(crate) const ATT_WRITE_REQ: u8 = 0x12;
17pub(crate) const ATT_WRITE_CMD: u8 = 0x52;
18pub(crate) const ATT_WRITE_RSP: u8 = 0x13;
19pub(crate) const ATT_EXCHANGE_MTU_REQ: u8 = 0x02;
20pub(crate) const ATT_EXCHANGE_MTU_RSP: u8 = 0x03;
21pub(crate) const ATT_FIND_BY_TYPE_VALUE_REQ: u8 = 0x06;
22pub(crate) const ATT_FIND_BY_TYPE_VALUE_RSP: u8 = 0x07;
23pub(crate) const ATT_FIND_INFORMATION_REQ: u8 = 0x04;
24pub(crate) const ATT_FIND_INFORMATION_RSP: u8 = 0x05;
25pub(crate) const ATT_PREPARE_WRITE_REQ: u8 = 0x16;
26pub(crate) const ATT_PREPARE_WRITE_RSP: u8 = 0x17;
27pub(crate) const ATT_EXECUTE_WRITE_REQ: u8 = 0x18;
28pub(crate) const ATT_EXECUTE_WRITE_RSP: u8 = 0x19;
29pub(crate) const ATT_READ_MULTIPLE_REQ: u8 = 0x20;
30pub(crate) const ATT_READ_MULTIPLE_RSP: u8 = 0x21;
31pub(crate) const ATT_READ_BLOB_REQ: u8 = 0x0c;
32pub(crate) const ATT_READ_BLOB_RSP: u8 = 0x0d;
33pub(crate) const ATT_HANDLE_VALUE_NTF: u8 = 0x1b;
34pub(crate) const ATT_HANDLE_VALUE_IND: u8 = 0x1d;
35pub(crate) const ATT_HANDLE_VALUE_CMF: u8 = 0x1e;
36
37#[cfg_attr(feature = "defmt", derive(defmt::Format))]
43#[derive(Debug, PartialEq, Eq, Clone, Copy)]
44pub struct AttErrorCode {
45    value: u8,
46}
47
48impl AttErrorCode {
49    pub const INVALID_HANDLE: Self = Self { value: 0x01 };
51    pub const READ_NOT_PERMITTED: Self = Self { value: 0x02 };
53    pub const WRITE_NOT_PERMITTED: Self = Self { value: 0x03 };
55    pub const INVALID_PDU: Self = Self { value: 0x04 };
57    pub const INSUFFICIENT_AUTHENTICATION: Self = Self { value: 0x05 };
59    pub const REQUEST_NOT_SUPPORTED: Self = Self { value: 0x06 };
61    pub const INVALID_OFFSET: Self = Self { value: 0x07 };
63    pub const INSUFFICIENT_AUTHORISATION: Self = Self { value: 0x08 };
65    pub const PREPARE_QUEUE_FULL: Self = Self { value: 0x09 };
67    pub const ATTRIBUTE_NOT_FOUND: Self = Self { value: 0x0a };
69    pub const ATTRIBUTE_NOT_LONG: Self = Self { value: 0x0b };
71    pub const INSUFFICIENT_ENCRYPTION_KEY_SIZE: Self = Self { value: 0x0c };
73    pub const INVALID_ATTRIBUTE_VALUE_LENGTH: Self = Self { value: 0x0d };
75    pub const UNLIKELY_ERROR: Self = Self { value: 0x0e };
77    pub const INSUFFICIENT_ENCRYPTION: Self = Self { value: 0x0f };
79    pub const UNSUPPORTED_GROUP_TYPE: Self = Self { value: 0x10 };
81    pub const INSUFFICIENT_RESOURCES: Self = Self { value: 0x11 };
83    pub const DATABASE_OUT_OF_SYNC: Self = Self { value: 0x12 };
85    pub const VALUE_NOT_ALLOWED: Self = Self { value: 0x13 };
87
88    pub const WRITE_REQUEST_REJECTED: Self = Self { value: 0xFC };
91    pub const CCCD_IMPROPERLY_CONFIGURED: Self = Self { value: 0xFD };
93    pub const PROCEDURE_ALREADY_IN_PROGRESS: Self = Self { value: 0xFE };
95    pub const OUT_OF_RANGE: Self = Self { value: 0xFF };
97}
98
99impl Display for AttErrorCode {
100    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
101        match self {
102            &Self::INVALID_HANDLE => {
103                f.write_str("invalid handle: Attempted to use a handle that isn't valid on this server")
104            }
105            &Self::READ_NOT_PERMITTED => f.write_str("read not permitted: the attribute cannot be read"),
106            &Self::WRITE_NOT_PERMITTED => f.write_str("write not permitted: the attribute cannot be written due to permissions"),
107            &Self::INVALID_PDU => f.write_str("invalid pdu: the attribute PDU was invalid"),
108            &Self::INSUFFICIENT_AUTHENTICATION => f.write_str(
109                "insufficient authentication: the attribute requires authentication before it can be written",
110            ),
111            &Self::REQUEST_NOT_SUPPORTED => {
112                f.write_str("request not supported: ATT server does not support the request received from the client")
113            }
114            &Self::INVALID_OFFSET => f.write_str("Offset specified was past the end of the attribute"),
115            &Self::INSUFFICIENT_AUTHORISATION => f.write_str(
116                "insufficient authorisation: the attribute requires authorisation before it can be read or written",
117            ),
118            &Self::PREPARE_QUEUE_FULL => f.write_str("prepare queue full: too many prepare writes have been queued"),
119            &Self::ATTRIBUTE_NOT_FOUND => f.write_str("attribute not found: no attribute found within the given attribute handle range"),
120            &Self::ATTRIBUTE_NOT_LONG => f.write_str("The attribute cannot be read using the ATT_READ_BLOB_REQ PDU"),
121            &Self::INSUFFICIENT_ENCRYPTION_KEY_SIZE => f.write_str("insufficient encryption key size: the encryption key size used for encrypting this link is too short"),
122            &Self::INVALID_ATTRIBUTE_VALUE_LENGTH => f.write_str("invalid attribute value length: the attribute value length is invalid for the operation"),
123            &Self::UNLIKELY_ERROR => f.write_str("unlikely error: the attribute request encountered an error that was unlikely, and therefore could not be completed"),
124            &Self::INSUFFICIENT_ENCRYPTION => f.write_str("insufficient encryption: the attribute requires encryption before it can be read or written"),
125            &Self::UNSUPPORTED_GROUP_TYPE => f.write_str("unsupported group type: the attribute type is not a supported grouping attribute as defined by a higher layer specification"),
126            &Self::INSUFFICIENT_RESOURCES => f.write_str("insufficient resources: insufficient resources to complete the request"),
127            &Self::DATABASE_OUT_OF_SYNC => f.write_str("the server requests the client to rediscover the database"),
128            &Self::VALUE_NOT_ALLOWED => f.write_str("value not allowed: the attribute parameter value was not allowed"),
129
130            &Self{value: 0x80..=0x9F} => write!(f, "application error code {}: check the application documentation of the device which produced this error code", self.value),
131
132            &Self::WRITE_REQUEST_REJECTED => f.write_str("write request rejected: the write request could not be fulfilled for reasons other than permissions"),
133            &Self::CCCD_IMPROPERLY_CONFIGURED => f.write_str("CCCD improperly configured: the client characteristic configuration descriptor (CCCD) is not configured according to the requirements of the profile or service"),
134            &Self::PROCEDURE_ALREADY_IN_PROGRESS => f.write_str("procedure already in progress: the profile or service request could not be serviced because an operation that has been previousl triggered is still in progress"),
135            &Self::OUT_OF_RANGE => f.write_str("out of range: the attribute value is out of range as defined by a profile or service specification"),
136
137            other => write!(f, "unknown error code {}: check the most recent bluetooth spec", other), 
138        }
139    }
140}
141
142impl codec::Encode for AttErrorCode {
143    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
144        dest[0] = self.value;
145        Ok(())
146    }
147}
148
149impl codec::Decode<'_> for AttErrorCode {
150    fn decode(src: &[u8]) -> Result<Self, codec::Error> {
151        Ok(Self { value: src[0] })
152    }
153}
154
155impl codec::Type for AttErrorCode {
156    fn size(&self) -> usize {
157        mem::size_of::<u8>()
158    }
159}
160
161#[cfg_attr(feature = "defmt", derive(defmt::Format))]
165#[derive(Debug)]
166pub enum AttClient<'d> {
167    Request(AttReq<'d>),
169    Command(AttCmd<'d>),
171    Confirmation(AttCfm),
173}
174
175#[cfg_attr(feature = "defmt", derive(defmt::Format))]
177#[derive(Debug)]
178pub enum AttReq<'d> {
179    ReadByGroupType {
181        start: u16,
183        end: u16,
185        group_type: Uuid,
187    },
188    ReadByType {
190        start: u16,
192        end: u16,
194        attribute_type: Uuid,
196    },
197    Read {
199        handle: u16,
201    },
202    Write {
204        handle: u16,
206        data: &'d [u8],
208    },
209    ExchangeMtu {
211        mtu: u16,
213    },
214    FindByTypeValue {
216        start_handle: u16,
218        end_handle: u16,
220        att_type: u16,
222        att_value: &'d [u8],
224    },
225    FindInformation {
227        start_handle: u16,
229        end_handle: u16,
231    },
232    PrepareWrite {
234        handle: u16,
236        offset: u16,
238        value: &'d [u8],
240    },
241    ExecuteWrite {
243        flags: u8,
245    },
246    ReadMultiple {
248        handles: &'d [u8],
250    },
251    ReadBlob {
253        handle: u16,
255        offset: u16,
257    },
258}
259
260#[cfg_attr(feature = "defmt", derive(defmt::Format))]
262#[derive(Debug)]
263pub enum AttCmd<'d> {
264    Write {
266        handle: u16,
268        data: &'d [u8],
270    },
271}
272
273#[cfg_attr(feature = "defmt", derive(defmt::Format))]
275#[derive(Debug)]
276pub enum AttCfm {
277    ConfirmIndication,
279}
280
281#[cfg_attr(feature = "defmt", derive(defmt::Format))]
283#[derive(Debug)]
284pub enum AttServer<'d> {
285    Response(AttRsp<'d>),
287    Unsolicited(AttUns<'d>),
289}
290
291#[cfg_attr(feature = "defmt", derive(defmt::Format))]
293#[derive(Debug)]
294pub enum AttRsp<'d> {
295    ExchangeMtu {
297        mtu: u16,
299    },
300    FindByTypeValue {
302        it: FindByTypeValueIter<'d>,
304    },
305    Error {
307        request: u8,
309        handle: u16,
311        code: AttErrorCode,
313    },
314    ReadByType {
316        it: ReadByTypeIter<'d>,
318    },
319    Read {
321        data: &'d [u8],
323    },
324    Write,
326}
327
328#[cfg_attr(feature = "defmt", derive(defmt::Format))]
330#[derive(Debug)]
331pub enum AttUns<'d> {
332    Notify {
334        handle: u16,
336        data: &'d [u8],
338    },
339    Indicate {
341        handle: u16,
343        data: &'d [u8],
345    },
346}
347
348#[cfg_attr(feature = "defmt", derive(defmt::Format))]
350#[derive(Debug)]
351pub enum Att<'d> {
352    Client(AttClient<'d>),
356    Server(AttServer<'d>),
360}
361
362#[cfg_attr(feature = "defmt", derive(defmt::Format))]
364#[derive(Clone, Debug)]
365pub struct FindByTypeValueIter<'d> {
366    cursor: ReadCursor<'d>,
367}
368
369impl FindByTypeValueIter<'_> {
370    #[allow(clippy::should_implement_trait)]
372    pub fn next(&mut self) -> Option<Result<(u16, u16), crate::Error>> {
373        if self.cursor.available() >= 4 {
374            let res = (|| {
375                let handle: u16 = self.cursor.read()?;
376                let end: u16 = self.cursor.read()?;
377                Ok((handle, end))
378            })();
379            Some(res)
380        } else {
381            None
382        }
383    }
384}
385
386#[cfg_attr(feature = "defmt", derive(defmt::Format))]
388#[derive(Clone, Debug)]
389pub struct ReadByTypeIter<'d> {
390    item_len: usize,
391    cursor: ReadCursor<'d>,
392}
393
394impl<'d> ReadByTypeIter<'d> {
395    #[allow(clippy::should_implement_trait)]
397    pub fn next(&mut self) -> Option<Result<(u16, &'d [u8]), crate::Error>> {
398        if self.cursor.available() >= self.item_len {
399            let res = (|| {
400                let handle: u16 = self.cursor.read()?;
401                let item = self.cursor.slice(self.item_len - 2)?;
402                Ok((handle, item))
403            })();
404            Some(res)
405        } else {
406            None
407        }
408    }
409}
410
411impl<'d> AttServer<'d> {
412    fn size(&self) -> usize {
413        match self {
414            Self::Response(rsp) => rsp.size(),
415            Self::Unsolicited(uns) => uns.size(),
416        }
417    }
418
419    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
420        match self {
421            Self::Response(rsp) => rsp.encode(dest),
422            Self::Unsolicited(uns) => uns.encode(dest),
423        }
424    }
425
426    fn decode_with_opcode(opcode: u8, r: ReadCursor<'d>) -> Result<Self, codec::Error> {
427        let decoded = match opcode {
428            ATT_HANDLE_VALUE_NTF | ATT_HANDLE_VALUE_IND => Self::Unsolicited(AttUns::decode_with_opcode(opcode, r)?),
429            _ => Self::Response(AttRsp::decode_with_opcode(opcode, r)?),
430        };
431        Ok(decoded)
432    }
433}
434
435impl<'d> AttRsp<'d> {
436    fn size(&self) -> usize {
437        1 + match self {
438            Self::ExchangeMtu { mtu: u16 } => 2,
439            Self::FindByTypeValue { it } => it.cursor.len(),
440            Self::Error { .. } => 4,
441            Self::Read { data } => data.len(),
442            Self::ReadByType { it } => it.cursor.len(),
443            Self::Write => 0,
444        }
445    }
446
447    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
448        let mut w = WriteCursor::new(dest);
449        match self {
450            Self::ExchangeMtu { mtu } => {
451                w.write(ATT_EXCHANGE_MTU_RSP)?;
452                w.write(*mtu)?;
453            }
454            Self::FindByTypeValue { it } => {
455                w.write(ATT_FIND_BY_TYPE_VALUE_RSP)?;
456                let mut it = it.clone();
457                while let Some(Ok((start, end))) = it.next() {
458                    w.write(start)?;
459                    w.write(end)?;
460                }
461            }
462            Self::Error { request, handle, code } => {
463                w.write(ATT_ERROR_RSP)?;
464                w.write(*request)?;
465                w.write(*handle)?;
466                w.write(*code)?;
467            }
468            Self::ReadByType { it } => {
469                w.write(ATT_READ_BY_TYPE_RSP)?;
470                w.write(it.item_len as u8)?;
471                let mut it = it.clone();
472                while let Some(Ok((handle, item))) = it.next() {
473                    w.write(handle)?;
474                    w.append(item)?;
475                }
476            }
477            Self::Read { data } => {
478                w.write(ATT_READ_RSP)?;
479                w.append(data)?;
480            }
481            Self::Write => {
482                w.write(ATT_WRITE_RSP)?;
483            }
484        }
485        Ok(())
486    }
487
488    fn decode_with_opcode(opcode: u8, mut r: ReadCursor<'d>) -> Result<Self, codec::Error> {
489        match opcode {
490            ATT_FIND_BY_TYPE_VALUE_RSP => Ok(Self::FindByTypeValue {
491                it: FindByTypeValueIter { cursor: r },
492            }),
493            ATT_EXCHANGE_MTU_RSP => {
494                let mtu: u16 = r.read()?;
495                Ok(Self::ExchangeMtu { mtu })
496            }
497            ATT_ERROR_RSP => {
498                let request = r.read()?;
499                let handle = r.read()?;
500                let code = r.read()?;
501                Ok(Self::Error { request, handle, code })
502            }
503            ATT_READ_RSP => Ok(Self::Read { data: r.remaining() }),
504            ATT_READ_BY_TYPE_RSP => {
505                let item_len: u8 = r.read()?;
506                Ok(Self::ReadByType {
507                    it: ReadByTypeIter {
508                        item_len: item_len as usize,
509                        cursor: r,
510                    },
511                })
512            }
513            ATT_WRITE_RSP => Ok(Self::Write),
514            _ => Err(codec::Error::InvalidValue),
515        }
516    }
517}
518
519impl<'d> AttUns<'d> {
520    fn size(&self) -> usize {
521        1 + match self {
522            Self::Notify { data, .. } => 2 + data.len(),
523            Self::Indicate { data, .. } => 2 + data.len(),
524        }
525    }
526
527    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
528        let mut w = WriteCursor::new(dest);
529        match self {
530            Self::Notify { handle, data } => {
531                w.write(ATT_HANDLE_VALUE_NTF)?;
532                w.write(*handle)?;
533                w.append(data)?;
534            }
535            Self::Indicate { handle, data } => {
536                w.write(ATT_HANDLE_VALUE_IND)?;
537                w.write(*handle)?;
538                w.append(data)?;
539            }
540        }
541        Ok(())
542    }
543
544    fn decode_with_opcode(opcode: u8, mut r: ReadCursor<'d>) -> Result<Self, codec::Error> {
545        match opcode {
546            ATT_HANDLE_VALUE_NTF => {
547                let handle = r.read()?;
548                Ok(Self::Notify {
549                    handle,
550                    data: r.remaining(),
551                })
552            }
553            ATT_HANDLE_VALUE_IND => {
554                let handle = r.read()?;
555                Ok(Self::Indicate {
556                    handle,
557                    data: r.remaining(),
558                })
559            }
560            _ => Err(codec::Error::InvalidValue),
561        }
562    }
563}
564
565impl<'d> AttClient<'d> {
566    fn size(&self) -> usize {
567        match self {
568            Self::Request(req) => req.size(),
569            Self::Command(cmd) => cmd.size(),
570            Self::Confirmation(cfm) => cfm.size(),
571        }
572    }
573
574    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
575        match self {
576            Self::Request(req) => req.encode(dest),
577            Self::Command(cmd) => cmd.encode(dest),
578            Self::Confirmation(cfm) => cfm.encode(dest),
579        }
580    }
581
582    fn decode_with_opcode(opcode: u8, r: ReadCursor<'d>) -> Result<Self, codec::Error> {
583        let decoded = match opcode {
584            ATT_WRITE_CMD => Self::Command(AttCmd::decode_with_opcode(opcode, r)?),
585            ATT_HANDLE_VALUE_CMF => Self::Confirmation(AttCfm::decode_with_opcode(opcode, r)?),
586            _ => Self::Request(AttReq::decode_with_opcode(opcode, r)?),
587        };
588        Ok(decoded)
589    }
590}
591
592impl<'d> AttReq<'d> {
593    fn size(&self) -> usize {
594        1 + match self {
595            Self::ExchangeMtu { .. } => 2,
596            Self::FindByTypeValue {
597                start_handle,
598                end_handle,
599                att_type,
600                att_value,
601            } => 6 + att_value.len(),
602            Self::ReadByType {
603                start,
604                end,
605                attribute_type,
606            } => 4 + attribute_type.as_raw().len(),
607            Self::Read { .. } => 2,
608            Self::Write { handle, data } => 2 + data.len(),
609            _ => unimplemented!(),
610        }
611    }
612    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
613        let mut w = WriteCursor::new(dest);
614        match self {
615            Self::ExchangeMtu { mtu } => {
616                w.write(ATT_EXCHANGE_MTU_REQ)?;
617                w.write(*mtu)?;
618            }
619            Self::FindByTypeValue {
620                start_handle,
621                end_handle,
622                att_type,
623                att_value,
624            } => {
625                w.write(ATT_FIND_BY_TYPE_VALUE_REQ)?;
626                w.write(*start_handle)?;
627                w.write(*end_handle)?;
628                w.write(*att_type)?;
629                w.append(att_value)?;
630            }
631            Self::ReadByType {
632                start,
633                end,
634                attribute_type,
635            } => {
636                w.write(ATT_READ_BY_TYPE_REQ)?;
637                w.write(*start)?;
638                w.write(*end)?;
639                w.write_ref(attribute_type)?;
640            }
641            Self::Read { handle } => {
642                w.write(ATT_READ_REQ)?;
643                w.write(*handle)?;
644            }
645            Self::Write { handle, data } => {
646                w.write(ATT_WRITE_REQ)?;
647                w.write(*handle)?;
648                w.append(data)?;
649            }
650            _ => unimplemented!(),
651        }
652        Ok(())
653    }
654
655    fn decode_with_opcode(opcode: u8, r: ReadCursor<'d>) -> Result<Self, codec::Error> {
656        let payload = r.remaining();
657        match opcode {
658            ATT_READ_BY_GROUP_TYPE_REQ => {
659                let start_handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
660                let end_handle = (payload[2] as u16) + ((payload[3] as u16) << 8);
661
662                let group_type = if payload.len() == 6 {
663                    Uuid::Uuid16([payload[4], payload[5]])
664                } else if payload.len() == 20 {
665                    let uuid = payload[4..21].try_into().map_err(|_| codec::Error::InvalidValue)?;
666                    Uuid::Uuid128(uuid)
667                } else {
668                    return Err(codec::Error::InvalidValue);
669                };
670
671                Ok(Self::ReadByGroupType {
672                    start: start_handle,
673                    end: end_handle,
674                    group_type,
675                })
676            }
677            ATT_READ_BY_TYPE_REQ => {
678                let start_handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
679                let end_handle = (payload[2] as u16) + ((payload[3] as u16) << 8);
680
681                let attribute_type = if payload.len() == 6 {
682                    Uuid::Uuid16([payload[4], payload[5]])
683                } else if payload.len() == 20 {
684                    let uuid = payload[4..20].try_into().map_err(|_| codec::Error::InvalidValue)?;
685                    Uuid::Uuid128(uuid)
686                } else {
687                    return Err(codec::Error::InvalidValue);
688                };
689
690                Ok(Self::ReadByType {
691                    start: start_handle,
692                    end: end_handle,
693                    attribute_type,
694                })
695            }
696            ATT_READ_REQ => {
697                let handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
698
699                Ok(Self::Read { handle })
700            }
701            ATT_WRITE_REQ => {
702                let handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
703                let data = &payload[2..];
704
705                Ok(Self::Write { handle, data })
706            }
707            ATT_EXCHANGE_MTU_REQ => {
708                let mtu = (payload[0] as u16) + ((payload[1] as u16) << 8);
709                Ok(Self::ExchangeMtu { mtu })
710            }
711            ATT_FIND_BY_TYPE_VALUE_REQ => {
712                let start_handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
713                let end_handle = (payload[2] as u16) + ((payload[3] as u16) << 8);
714                let att_type = (payload[4] as u16) + ((payload[5] as u16) << 8);
715                let att_value = &payload[6..];
716
717                Ok(Self::FindByTypeValue {
718                    start_handle,
719                    end_handle,
720                    att_type,
721                    att_value,
722                })
723            }
724            ATT_FIND_INFORMATION_REQ => {
725                let start_handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
726                let end_handle = (payload[2] as u16) + ((payload[3] as u16) << 8);
727
728                Ok(Self::FindInformation {
729                    start_handle,
730                    end_handle,
731                })
732            }
733            ATT_PREPARE_WRITE_REQ => {
734                let handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
735                let offset = (payload[2] as u16) + ((payload[3] as u16) << 8);
736                Ok(Self::PrepareWrite {
737                    handle,
738                    offset,
739                    value: &payload[4..],
740                })
741            }
742            ATT_EXECUTE_WRITE_REQ => {
743                let flags = payload[0];
744                Ok(Self::ExecuteWrite { flags })
745            }
746            ATT_READ_MULTIPLE_REQ => Ok(Self::ReadMultiple { handles: payload }),
747            ATT_READ_BLOB_REQ => {
748                let handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
749                let offset = (payload[2] as u16) + ((payload[3] as u16) << 8);
750                Ok(Self::ReadBlob { handle, offset })
751            }
752            code => {
753                warn!("[att] unknown opcode {:x}", code);
754                Err(codec::Error::InvalidValue)
755            }
756        }
757    }
758}
759
760impl<'d> AttCmd<'d> {
761    fn size(&self) -> usize {
762        1 + match self {
763            Self::Write { handle, data } => 2 + data.len(),
764        }
765    }
766
767    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
768        let mut w = WriteCursor::new(dest);
769        match self {
770            Self::Write { handle, data } => {
771                w.write(ATT_WRITE_CMD)?;
772                w.write(*handle)?;
773                w.append(data)?;
774            }
775        }
776        Ok(())
777    }
778
779    fn decode_with_opcode(opcode: u8, r: ReadCursor<'d>) -> Result<Self, codec::Error> {
780        let payload = r.remaining();
781        match opcode {
782            ATT_WRITE_CMD => {
783                let handle = (payload[0] as u16) + ((payload[1] as u16) << 8);
784                let data = &payload[2..];
785
786                Ok(Self::Write { handle, data })
787            }
788            code => {
789                warn!("[att] unknown opcode {:x}", code);
790                Err(codec::Error::InvalidValue)
791            }
792        }
793    }
794}
795
796impl AttCfm {
797    fn size(&self) -> usize {
798        1
799    }
800
801    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
802        let mut w = WriteCursor::new(dest);
803        match self {
804            Self::ConfirmIndication => {
805                w.write(ATT_HANDLE_VALUE_CMF)?;
806            }
807        }
808        Ok(())
809    }
810
811    fn decode_with_opcode(opcode: u8, r: ReadCursor<'_>) -> Result<Self, codec::Error> {
812        let payload = r.remaining();
813        match opcode {
814            ATT_HANDLE_VALUE_CMF => Ok(Self::ConfirmIndication),
815            code => {
816                warn!("[att] unknown opcode {:x}", code);
817                Err(codec::Error::InvalidValue)
818            }
819        }
820    }
821}
822
823impl<'d> Att<'d> {
824    pub fn size(&self) -> usize {
826        match self {
827            Self::Client(client) => client.size(),
828            Self::Server(server) => server.size(),
829        }
830    }
831
832    pub fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
834        match self {
835            Self::Client(client) => client.encode(dest),
836            Self::Server(server) => server.encode(dest),
837        }
838    }
839
840    pub fn decode(data: &'d [u8]) -> Result<Att<'d>, codec::Error> {
842        let mut r = ReadCursor::new(data);
843        let opcode: u8 = r.read()?;
844        if opcode % 2 == 0 {
845            let client = AttClient::decode_with_opcode(opcode, r)?;
846            Ok(Att::Client(client))
847        } else {
848            let server = AttServer::decode_with_opcode(opcode, r)?;
849            Ok(Att::Server(server))
850        }
851    }
852}
853
854impl From<codec::Error> for AttErrorCode {
855    fn from(e: codec::Error) -> Self {
856        AttErrorCode::INVALID_PDU
857    }
858}
859
860impl codec::Type for Att<'_> {
861    fn size(&self) -> usize {
862        Self::size(self)
863    }
864}
865
866impl codec::Encode for Att<'_> {
867    fn encode(&self, dest: &mut [u8]) -> Result<(), codec::Error> {
868        Self::encode(self, dest)
869    }
870}
871
872impl<'d> codec::Decode<'d> for Att<'d> {
873    fn decode(data: &'d [u8]) -> Result<Self, codec::Error> {
874        Self::decode(data)
875    }
876}