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
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
//! Bluetooth events and event deserialization.
//!
//! This module defines all of the HCI events that can be generated by the Bluetooth controller. In
//! addition to all of the event types, the core functionality of the module is the `Event` enum,
//! which converts a byte buffer into an HCI event.

#![macro_use]

/// Verifies that the length of the LHS expression is exactly the RHS expression.  Fails with a
/// [`BadLength`](crate::event::Error::BadLength) error if not.
#[macro_export]
macro_rules! require_len {
    ($left:expr, $right:expr) => {
        if $left.len() != $right {
            return Err($crate::event::Error::BadLength($left.len(), $right));
        }
    };
}

/// Verifies that the length of the LHS expression is greater than or equal to the RHS expression.
/// Fails with a [`BadLength`](crate::event::Error::BadLength) error if not.
#[macro_export]
macro_rules! require_len_at_least {
    ($left:expr, $right:expr) => {
        if $left.len() < $right {
            return Err($crate::event::Error::BadLength($left.len(), $right));
        }
    };
}

/// Converts a specific generic enum value between specializations.  This is used below to convert
/// from [`Error<NeverError>`] to [`Error<VendorError>`] in various places where only one error
/// value is possible (such as from `try_into`).
macro_rules! self_convert {
    ($val:path) => {
        |e| {
            if let $val(value) = e {
                return $val(value);
            }
            unreachable!();
        }
    };
}

pub mod command;

use crate::types::{ConnectionIntervalError, FixedConnectionInterval};
use crate::{BadStatusError, ConnectionHandle, Status};
use byteorder::{ByteOrder, LittleEndian};
use core::convert::{TryFrom, TryInto};
use core::fmt::{Debug, Formatter, Result as FmtResult};
use core::marker::{PhantomData, Sized};
use core::mem;

/// Potential events that can be generated by the controller.
///
/// See the Bluetooth Spec v4.1, Vol 2, Part E, Section 7.7 for a description of each event.  The
/// events are the same for versions 4.1, 4.2, and 5.0 except where noted.
///
/// The spec defines an "LE Meta-Event" event. This event is not exposed directly. Instead,
/// individual LE events are included in this enum.
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Event<V>
where
    V: VendorEvent,
{
    /// Vol 2, Part E, Section 7.7.3
    ConnectionComplete(ConnectionComplete<V::Status>),

    /// Vol 2, Part E, Section 7.7.5
    DisconnectionComplete(DisconnectionComplete<V::Status>),

    /// Vol 2, Part E, Section 7.7.8
    EncryptionChange(EncryptionChange<V::Status>),

    /// Vol 2, Part E, Section 7.7.12
    ReadRemoteVersionInformationComplete(RemoteVersionInformation<V::Status>),

    /// Vol 2, Part E, Section 7.7.14
    CommandComplete(command::CommandComplete<V>),

    /// Vol 2, Part E, Section 7.7.15
    CommandStatus(CommandStatus<V::Status>),

    /// Vol 2, Part E, Section 7.7.16
    HardwareError(HardwareError),

    /// Vol 2, Part E, Section 7.7.19
    NumberOfCompletedPackets(NumberOfCompletedPackets),

    /// Vol 2, Part E, Section 7.7.26
    DataBufferOverflow(DataBufferOverflow),

    /// Vol 2, Part E, Section 7.7.39
    EncryptionKeyRefreshComplete(EncryptionKeyRefreshComplete<V::Status>),

    /// Vol 2, Part E, Section 7.7.65.1
    LeConnectionComplete(LeConnectionComplete<V::Status>),

    /// Vol 2, Part E, Section 7.7.65.2
    LeAdvertisingReport(LeAdvertisingReport),

    /// Vol 2, Part E, Section 7.7.65.3
    LeConnectionUpdateComplete(LeConnectionUpdateComplete<V::Status>),

    /// Vol 2, Part E, Section 7.7.65.4
    LeReadRemoteUsedFeaturesComplete(LeReadRemoteUsedFeaturesComplete<V::Status>),

    /// Vol 2, Part E, Section 7.7.65.5
    LeLongTermKeyRequest(LeLongTermKeyRequest),

    /// Vol 2, Part E, Section 7.7.65.7
    LeDataLengthChangeEvent(LeDataLengthChangeEvent),

    /// Vol 2, Part E, Section 7.7.65.12
    LePhyUpdateComplete(LePhyUpdateComplete<V::Status>),

    /// Vendor-specific events (opcode 0xFF)
    Vendor(V),
}

/// Trait for [vendor-specific events](Event::Vendor).
pub trait VendorEvent {
    /// Enumeration of vendor-specific errors that may occur when deserializing events. Generally,
    /// this means some values in the buffer are out of range for the event.
    type Error;

    #[cfg(not(feature = "defmt"))]
    /// Enumeration of vendor-specific status codes.
    type Status: TryFrom<u8, Error = BadStatusError> + Clone + Debug;

    #[cfg(feature = "defmt")]
    /// Enumeration of vendor-specific status codes.
    type Status: TryFrom<u8, Error = BadStatusError> + Clone + Debug + defmt::Format;

    #[cfg(not(feature = "defmt"))]
    /// Enumeration of return parameters for vendor-specific commands.
    type ReturnParameters: VendorReturnParameters<Error = Self::Error> + Clone + Debug;

    #[cfg(feature = "defmt")]
    /// Enumeration of return parameters for vendor-specific commands.
    type ReturnParameters: VendorReturnParameters<Error = Self::Error>
        + Clone
        + Debug
        + defmt::Format;

    /// Creates a new vendor-specific event from the contents of buffer. The buffer contains only
    /// the payload of the event, which does not include the BLE event type (which must be 0xFF) or
    /// the parameter length (which is provided by `buffer.len()`).
    ///
    /// # Errors
    ///
    /// - Shall return one of the appropriate error types (potentially including vendor-specific
    ///   errors) if the buffer does not describe a valid event.
    fn new(buffer: &[u8]) -> Result<Self, Error<Self::Error>>
    where
        Self: Sized;
}

/// Trait for return parameters for vendor-specific commands.
pub trait VendorReturnParameters {
    /// Enumeration of vendor-specific errors that may occur when deserializing return parameters
    /// for vendor-specific commands.
    type Error;

    /// Deserializes vendor-specific return parameters from the contents of the buffer.  The buffer
    /// is the full payload of the command complete event, starting with the length (1 byte) and
    /// opcode (2 bytes).
    fn new(buffer: &[u8]) -> Result<Self, Error<Self::Error>>
    where
        Self: Sized;
}

/// Errors that may occur when deserializing an event. Must be specialized by the vendor crate to
/// allow for vendor-specific event errors.
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error<V> {
    /// The event type byte was unknown. The byte is provided.
    UnknownEvent(u8),

    /// The buffer provided that is supposed to contain an event does not have the correct
    /// length. Field 0 is the provided length, field 1 is the expected length.
    BadLength(usize, usize),

    /// For all events: The status was not recognized (reserved for future use). Includes the
    /// unrecognized byte.
    BadStatus(u8),

    /// For the [Connection Complete](Event::ConnectionComplete) or [Data Buffer
    /// Overflow](Event::DataBufferOverflow) events: the link type was not recognized (reserved for
    /// future use). Includes the unrecognized byte.
    BadLinkType(u8),

    /// For the [Connection Complete](Event::ConnectionComplete) event: the encryption enabled value
    /// was not recognized (reserved for future use). Includes the unrecognized byte.
    BadEncryptionEnabledValue(u8),

    /// For the [Disconnection Complete](Event::DisconnectionComplete) event: the disconnection
    /// reason was not recognized.  Includes the unrecognized byte.
    BadReason(u8),

    /// For the [Encryption Change](Event::EncryptionChange) event: The encryption type was not
    /// recognized.  Includes the unrecognized byte.
    BadEncryptionType(u8),

    /// For the [Command Complete](Event::CommandComplete) event: The event indicated a command
    /// completed whose opcode was not recognized. Includes the unrecognized opcode.
    UnknownOpcode(crate::opcode::Opcode),

    /// For the [Command Complete](Event::CommandComplete) event, for the Read Local Supported
    /// Commands command return parameters: The returned command flags are invalid (i.e., they
    /// include a flag that is reserved for future use).
    BadCommandFlag,

    /// For the [Command Complete](Event::CommandComplete) event, for the [LE Read Channel
    /// Map](command::ReturnParameters::LeReadChannelMap) command return parameters: The returned
    /// channel map includes a reserved bit.
    InvalidChannelMap([u8; 5]),

    /// For the [Command Complete](Event::CommandComplete) event, for the [LE Read Supported
    /// States](command::ReturnParameters::LeReadSupportedStates) command return parameters: The
    /// returned supported states bitfield includes a reserved bit.
    InvalidLeStates(u64),

    /// For the [LE Connection Complete](Event::LeConnectionComplete) event: The connection role was
    /// not recognized. Includes the unrecognized byte.
    BadLeConnectionRole(u8),

    /// For the [LE Connection Complete](Event::LeConnectionComplete) or [LE Advertising
    /// Report](Event::LeAdvertisingReport) events: The address type was not recognized. Includes
    /// the unrecognized byte.
    BadLeAddressType(u8),

    /// For the [LE Connection Complete](Event::LeConnectionComplete) event: The returned connection
    /// interval was invalid. Includes the error returned when attempting to create the
    /// [FixedConnectionInterval].
    BadConnectionInterval(ConnectionIntervalError),

    /// For the [LE Connection Complete](Event::LeConnectionComplete) event: The central clock
    /// accuracy value was not recognized.  Includes the unrecognized byte.
    BadLeCentralClockAccuracy(u8),

    /// For the [LE Advertising Report](Event::LeAdvertisingReport) event: The packet ended with a
    /// partial report.
    LeAdvertisementReportIncomplete,

    /// For the [LE Advertising Report](Event::LeAdvertisingReport) event: The packet includes an
    /// invalid advertisement type.  Includes the unrecognized byte.
    BadLeAdvertisementType(u8),

    /// For the [LE Read Remote Used Features Complete](Event::LeReadRemoteUsedFeaturesComplete)
    /// event: The response included an invalid bit set for the remote features.  Includes the 8
    /// bytes of flags.
    BadRemoteUsedFeatureFlag(u64),

    /// For the [LE PHY Update Complete](Event::LePhyUpdateComplete) event: The PHY type was not
    /// recognized. Includes the unrecognized byte.
    BadPhy(u8),

    /// A vendor-specific error was detected when deserializing a vendor-specific event.
    Vendor(V),
}

/// Extracts the value from a [`BadStatusError`](BadStatusError) and returns it as a
/// [`BadStatus`](Error::BadStatus) error.
pub fn rewrap_bad_status<VE>(bad_status: BadStatusError) -> Error<VE> {
    let BadStatusError::BadValue(v) = bad_status;
    Error::BadStatus(v)
}

fn rewrap_bad_reason<VE>(bad_status: BadStatusError) -> Error<VE> {
    let BadStatusError::BadValue(v) = bad_status;
    Error::BadReason(v)
}

fn rewrap_bd_addr_type_err<VE>(bad_addr_type: crate::BdAddrTypeError) -> Error<VE> {
    Error::BadLeAddressType(bad_addr_type.0)
}

/// Defines a newtype to indicate that the buffer is supposed to contain an HCI event.
pub struct Packet<'a>(pub &'a [u8]);

impl<'a> Packet<'a> {
    fn full_length(&self) -> usize {
        PACKET_HEADER_LENGTH + self.0[PARAM_LEN_BYTE] as usize
    }
}

const PACKET_HEADER_LENGTH: usize = 2;
const EVENT_TYPE_BYTE: usize = 0;
const PARAM_LEN_BYTE: usize = 1;

impl<V> Event<V>
where
    V: VendorEvent,
{
    /// Deserializes an event from the given packet. The packet should contain all of the data
    /// needed to deserialize the event.
    ///
    /// # Errors
    ///
    /// - [`UnknownEvent`](Error::UnknownEvent) error if the first byte of the header is not a
    ///   recognized event type. This includes events that may be valid BLE events, but are not yet
    ///   be implemented by this crate.
    /// - [`BadLength`](Error::BadLength) error if the length of the packet is not sufficient to
    ///   either (1) contain a packet header, or (2) contain the packet data as defined by the
    ///   header.
    /// - Other errors if the particular event cannot be correctly deserialized from the
    ///   packet. This includes vendor-specific errors for vendor events.
    pub fn new(packet: Packet) -> Result<Event<V>, Error<V::Error>> {
        require_len_at_least!(packet.0, PACKET_HEADER_LENGTH);
        require_len!(packet.0, packet.full_length());

        let event_type = packet.0[EVENT_TYPE_BYTE];
        let payload = &packet.0[PACKET_HEADER_LENGTH..packet.full_length()];

        match event_type {
            0x03 => Ok(Event::ConnectionComplete(to_connection_complete(payload)?)),
            0x05 => Ok(Event::DisconnectionComplete(to_disconnection_complete(
                payload,
            )?)),
            0x08 => Ok(Event::EncryptionChange(to_encryption_change(payload)?)),
            0x0C => Ok(Event::ReadRemoteVersionInformationComplete(
                to_remote_version_info(payload)?,
            )),
            0x0E => Ok(Event::CommandComplete(command::CommandComplete::new(
                payload,
            )?)),
            0x0F => Ok(Event::CommandStatus(to_command_status(payload)?)),
            0x10 => Ok(Event::HardwareError(to_hardware_error(payload)?)),
            0x13 => Ok(Event::NumberOfCompletedPackets(
                to_number_of_completed_packets(payload)?,
            )),
            0x1A => Ok(Event::DataBufferOverflow(to_data_buffer_overflow(payload)?)),
            0x30 => Ok(Event::EncryptionKeyRefreshComplete(
                to_encryption_key_refresh_complete(payload)?,
            )),
            0x3E => to_le_meta_event(payload),
            0xFF => Ok(Event::Vendor(V::new(payload)?)),
            _ => Err(Error::UnknownEvent(event_type)),
        }
    }
}

fn to_le_meta_event<V>(payload: &[u8]) -> Result<Event<V>, Error<V::Error>>
where
    V: VendorEvent,
{
    require_len_at_least!(payload, 1);
    match payload[0] {
        0x01 => Ok(Event::LeConnectionComplete(to_le_connection_complete(
            payload,
        )?)),
        0x02 => Ok(Event::LeAdvertisingReport(to_le_advertising_report(
            payload,
        )?)),
        0x03 => Ok(Event::LeConnectionUpdateComplete(
            to_le_connection_update_complete(payload)?,
        )),
        0x04 => Ok(Event::LeReadRemoteUsedFeaturesComplete(
            to_le_read_remote_used_features_complete(payload)?,
        )),
        0x05 => Ok(Event::LeLongTermKeyRequest(to_le_ltk_request(payload)?)),
        0x07 => Ok(Event::LeDataLengthChangeEvent(
            to_le_data_length_change_event(payload)?,
        )),
        0x0C => Ok(Event::LePhyUpdateComplete(to_le_phy_update_complete(
            payload,
        )?)),
        _ => Err(Error::UnknownEvent(payload[0])),
    }
}

/// The [Connection Complete](Event::ConnectionComplete) event indicates to both of the Hosts
/// forming the connection that a new connection has been established.
///
/// This event also indicates to the Host which issued the connection command and then received a
/// [Command Status](Event::CommandStatus) event, if the issued command failed or was successful.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ConnectionComplete<VS> {
    /// Did the connection attempt fail, and if so, how?
    pub status: Status<VS>,
    /// Identifies a connection between two BR/ EDR Controllers. This is used as an identifier for
    /// transmitting and receiving voice or data.
    pub conn_handle: ConnectionHandle,
    /// BD ADDR of the other connected device forming the connection.
    pub bd_addr: crate::BdAddr,
    /// Type of connection.
    pub link_type: LinkType,
    /// True if the connection is encrypted.
    pub encryption_enabled: bool,
}

/// Permissible values for [`ConnectionComplete::link_type`].
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum LinkType {
    /// Synchronous, connection-oriented link
    Sco,
    /// Asynchronous, connection-less link
    Acl,
}

/// [TODO](https://doc.rust-lang.org/std/primitive.never.html): Replace NeverError with the
/// language's never type (!).
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum NeverError {}

impl TryFrom<u8> for LinkType {
    type Error = Error<NeverError>;

    fn try_from(value: u8) -> Result<LinkType, Self::Error> {
        match value {
            0 => Ok(LinkType::Sco),
            1 => Ok(LinkType::Acl),
            _ => Err(Error::BadLinkType(value)),
        }
    }
}

fn to_connection_complete<VE, VS>(payload: &[u8]) -> Result<ConnectionComplete<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 11);

    let mut bd_addr = crate::BdAddr([0; 6]);
    bd_addr.0.copy_from_slice(&payload[3..9]);
    Ok(ConnectionComplete {
        status: payload[0].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
        bd_addr,
        link_type: payload[9]
            .try_into()
            .map_err(self_convert!(Error::BadLinkType))?,
        encryption_enabled: try_into_encryption_enabled(payload[10])
            .map_err(self_convert!(Error::BadEncryptionEnabledValue))?,
    })
}

fn try_into_encryption_enabled(value: u8) -> Result<bool, Error<NeverError>> {
    match value {
        0 => Ok(false),
        1 => Ok(true),
        _ => Err(Error::BadEncryptionEnabledValue(value)),
    }
}

/// The [Disconnection Complete](Event::DisconnectionComplete) event occurs when a connection is
/// terminated.
///
/// Note: When a physical link fails, one Disconnection Complete event will be returned for each
/// logical channel on the physical link with the corresponding [connection
/// handle](DisconnectionComplete::conn_handle) as a parameter.
///
/// See the Bluetooth v4.1 spec, Vol 2, Part E, Section 7.7.5.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct DisconnectionComplete<VS> {
    /// Indicates if the disconnection was successful or not.
    pub status: Status<VS>,

    /// Connection handle which was disconnected.
    pub conn_handle: ConnectionHandle,

    /// Indicates the reason for the disconnection if the disconnection was successful. If the
    /// disconnection was not successful, the value of the reason parameter can be ignored by the
    /// Host. For example, this can be the case if the Host has issued the
    /// [Disconnect](crate::host::Hci::disconnect) command and there was a parameter error, or the
    /// command was not presently allowed, or a connection handle that didn't correspond to a
    /// connection was given.
    pub reason: Status<VS>,
}

fn to_disconnection_complete<VE, VS>(payload: &[u8]) -> Result<DisconnectionComplete<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 4);

    Ok(DisconnectionComplete {
        status: payload[0].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
        reason: payload[3].try_into().map_err(rewrap_bad_reason)?,
    })
}

/// The [Encryption Change](Event::EncryptionChange) event is used to indicate that the change of
/// the encryption mode has been completed.
///
/// This event will occur on both devices to notify the Hosts when Encryption has changed for the
/// specified connection handle between two devices. Note: This event shall not be generated if
/// encryption is paused or resumed; during a role switch, for example.
///
/// See the Bluetooth v4.1 spec, Vol 2, Part E, Section 7.7.8.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct EncryptionChange<VS> {
    /// Indicates if the encryption change was successful or not.
    pub status: Status<VS>,

    /// Connection handle for which the link layer encryption has been enabled/disabled for all
    /// connection handles with the same BR/EDR Controller endpoint as the specified
    /// connection handle.
    ///
    /// The connection handle will be a connection handle for an ACL connection.
    pub conn_handle: ConnectionHandle,

    /// Specifies the new encryption type parameter for
    /// [`conn_handle`](EncryptionChange::conn_handle).
    pub encryption: Encryption,
}

/// The type of used encryption for the connection.
///
/// The meaning of the encryption type depends on whether the Host has indicated support for Secure
/// Connections in the secure connections host support parameter. When secure connections host
/// support is 'disabled' or the connection handle refers to an LE link, the Controller shall only
/// use values [`Off`](Encryption::Off) and [`On`](Encryption::On). When secure connections host
/// support is 'enabled' and the connection handle refers to a BR/EDR link, the Controller shall set
/// the encryption type [`Off`](Encryption::Off) when encryption is off, to [`On`](Encryption::On)
/// when encryption is on and using E0 and to [`OnAesCcmForBrEdr`](Encryption::OnAesCcmForBrEdr)
/// when encryption is on and using AES-CCM.
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Encryption {
    /// Encryption is disabled.
    Off,
    /// - On a BR/EDR link, encryption is enabled using E0
    /// - On an LE link, encryption is enabled using AES-CCM
    On,
    /// On a BR/EDR link, encryption is enabled using AES-CCM. Unused for LE links.
    OnAesCcmForBrEdr,
}

impl TryFrom<u8> for Encryption {
    type Error = Error<NeverError>;
    fn try_from(value: u8) -> Result<Encryption, Self::Error> {
        match value {
            0x00 => Ok(Encryption::Off),
            0x01 => Ok(Encryption::On),
            0x02 => Ok(Encryption::OnAesCcmForBrEdr),
            _ => Err(Error::BadEncryptionType(value)),
        }
    }
}

fn to_encryption_change<VE, VS>(payload: &[u8]) -> Result<EncryptionChange<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 4);
    Ok(EncryptionChange {
        status: payload[0].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
        encryption: payload[3]
            .try_into()
            .map_err(self_convert!(Error::BadEncryptionType))?,
    })
}

/// Indicates the completion of the process obtaining the version information of the remote
/// Controller specified by [`conn_handle`](RemoteVersionInformation::conn_handle).
///
/// See [`RemoteVersionInformationComplete`](Event::ReadRemoteVersionInformationComplete).
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct RemoteVersionInformation<VS> {
    /// Status of the read event.
    pub status: Status<VS>,

    /// Connection Handle which was used for the
    /// [`read_remote_version_information`](crate::host::Hci::read_remote_version_information)
    /// command.  The connection handle shall be for an ACL connection.
    pub conn_handle: ConnectionHandle,

    /// Version of the Current LMP in the remote Controller. See [LMP] version and [Link Layer]
    /// version in the Bluetooth Assigned Numbers.
    /// - When the connection handle is associated with a BR/EDR ACL-U logical link, the Version
    ///   event parameter shall be LMP version parameter
    /// - When the connection handle is associated with an LE-U logical link, the Version event
    ///   parameter shall be Link Layer version parameter
    ///
    /// [LMP]: https://www.bluetooth.com/specifications/assigned-numbers/link-manager
    /// [Link Layer]: https://www.bluetooth.com/specifications/assigned-numbers/link-layer
    pub version: u8,

    /// Manufacturer name of the remote Controller. See [CompId] in the Bluetooth Assigned Numbers.
    ///
    /// [CompId]: https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
    pub mfgr_name: u16,

    /// Subversion of the [LMP] in the remote Controller. See the Bluetooth Spec, v4.1, Vol 2, Part
    /// C, Table 5.2 and Vol 6, Part B, Section 2.4.2.13 (SubVersNr).  The sections are the same in
    /// v4.2 and v5.0 of the spec.
    ///
    /// This field shall contain a unique value for each implementation or revision of an
    /// implementation of the Bluetooth Controller.
    ///
    /// The meaning of the subversion is implementation-defined.
    ///
    /// [LMP]: https://www.bluetooth.com/specifications/assigned-numbers/link-manager
    pub subversion: u16,
}

fn to_remote_version_info<VE, VS>(payload: &[u8]) -> Result<RemoteVersionInformation<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 8);
    Ok(RemoteVersionInformation {
        status: payload[0].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
        version: payload[3],
        mfgr_name: LittleEndian::read_u16(&payload[4..]),
        subversion: LittleEndian::read_u16(&payload[6..]),
    })
}

/// The [Command Status](Event::CommandStatus) event is used to indicate that the command described
/// by the [`opcode`](CommandStatus::opcode) parameter has been received, and that the Controller is
/// currently performing the task for this command.
///
/// Defined in Vol 2, Part E, Section 7.7.15 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CommandStatus<VS> {
    /// Status of the command that has started.
    pub status: Status<VS>,

    /// Number of HCI Command packets that can be sent to the controller from the host.
    pub num_hci_command_packets: u8,

    /// Opcode of the command that generated this event. The controller can generate a spontaneous
    /// [`Command Status`](Event::CommandStatus) with opcode 0 if the number of allowed HCI commands
    /// has changed.
    pub opcode: crate::opcode::Opcode,
}

fn to_command_status<VE, VS>(buffer: &[u8]) -> Result<CommandStatus<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(buffer, 4);

    Ok(CommandStatus {
        status: buffer[0].try_into().map_err(rewrap_bad_status)?,
        num_hci_command_packets: buffer[1],
        opcode: crate::opcode::Opcode(LittleEndian::read_u16(&buffer[2..])),
    })
}

/// The [Hardware Error](Event::HardwareError) event is used to notify the Host that a hardware
/// failure has occurred in the Controller.
///
/// Defined in Vol 2, Part E, Section 7.7.16 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct HardwareError {
    /// These hardware codes will be implementation-specific, and can be assigned to indicate
    /// various hardware problems.
    pub code: u8,
}

fn to_hardware_error<VE>(payload: &[u8]) -> Result<HardwareError, Error<VE>> {
    require_len!(payload, 1);
    Ok(HardwareError { code: payload[0] })
}

/// The [`Number of Completed Packets`](Event::NumberOfCompletedPackets) event is used by the
/// Controller to indicate to the Host how many HCI Data Packets have been completed (transmitted or
/// flushed) for each connection handle since the previous Number Of Completed Packets event was
/// sent to the Host.
///
/// Defined in Vol 2, Part E, Section 7.7.19 of the spec.
#[derive(Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct NumberOfCompletedPackets {
    /// Number of connection handles whose data is sent in this event.
    num_handles: usize,

    /// Data buffer for the event.
    data_buf: [u8; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN],
}

// The maximum number of bytes in the buffer is the max HCI packet size (255) less the other data in
// the packet.
const NUMBER_OF_COMPLETED_PACKETS_MAX_LEN: usize = 254;

impl Debug for NumberOfCompletedPackets {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        write!(f, "{{")?;
        for pair in self.iter() {
            write!(f, "{:?}", pair)?;
        }
        write!(f, "}}")
    }
}

impl NumberOfCompletedPackets {
    /// Returns an iterator over the connection handle-number of completed packet pairs.
    pub fn iter(&self) -> NumberOfCompletedPacketsIterator {
        NumberOfCompletedPacketsIterator {
            event: self,
            next_index: 0,
        }
    }
}

/// Iterator over the connection handle-number of completed packet pairs from the
/// [`NumberOfCompletedPackets`] event.
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct NumberOfCompletedPacketsIterator<'a> {
    event: &'a NumberOfCompletedPackets,
    next_index: usize,
}

const NUM_COMPLETED_PACKETS_PAIR_LEN: usize = 4;
impl<'a> Iterator for NumberOfCompletedPacketsIterator<'a> {
    type Item = NumberOfCompletedPacketsPair;

    /// Returns the next connection handle-number of completed packets pair from the event.
    fn next(&mut self) -> Option<Self::Item> {
        if self.next_index >= self.event.num_handles * NUM_COMPLETED_PACKETS_PAIR_LEN {
            return None;
        }

        let index = self.next_index;
        self.next_index += NUM_COMPLETED_PACKETS_PAIR_LEN;
        Some(NumberOfCompletedPacketsPair {
            conn_handle: ConnectionHandle(LittleEndian::read_u16(&self.event.data_buf[index..])),
            num_completed_packets: LittleEndian::read_u16(&self.event.data_buf[index + 2..])
                as usize,
        })
    }
}

/// The [`NumberOfCompletedPackets`] event includes a series of connection handle-number of
/// completed packets pairs.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct NumberOfCompletedPacketsPair {
    /// Connection handle
    pub conn_handle: ConnectionHandle,
    /// The number of HCI Data Packets that have been completed (transmitted or flushed) for
    /// [`conn_handle`](NumberOfCompletedPacketsPair::conn_handle) since the previous time the event
    /// was returned.
    pub num_completed_packets: usize,
}

fn to_number_of_completed_packets<VE>(
    payload: &[u8],
) -> Result<NumberOfCompletedPackets, Error<VE>> {
    require_len_at_least!(payload, 1);

    let num_pairs = payload[0] as usize;
    require_len!(payload, 1 + num_pairs * NUM_COMPLETED_PACKETS_PAIR_LEN);

    let mut data_buf = [0; NUMBER_OF_COMPLETED_PACKETS_MAX_LEN];
    data_buf[..num_pairs * NUM_COMPLETED_PACKETS_PAIR_LEN].copy_from_slice(&payload[1..]);
    Ok(NumberOfCompletedPackets {
        num_handles: num_pairs,
        data_buf,
    })
}

/// Indicates that the Controller's data buffers have been overflowed.  This can occur if the Host
/// has sent more packets than allowed.
///
/// Defined in Vol 2, Part E, Section 7.7.26 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct DataBufferOverflow {
    /// Indicates whether the overflow was caused by ACL or synchronous data.
    pub link_type: LinkType,
}

fn to_data_buffer_overflow<VE>(payload: &[u8]) -> Result<DataBufferOverflow, Error<VE>> {
    require_len!(payload, 1);
    Ok(DataBufferOverflow {
        link_type: payload[0]
            .try_into()
            .map_err(self_convert!(Error::BadLinkType))?,
    })
}

/// Indicates to the Host that the encryption key was refreshed.
///
/// The encryption key is refreshed on the given
/// [`conn_handle`](EncryptionKeyRefreshComplete::conn_handle) any time encryption is paused and
/// then resumed. The BR/EDR Controller shall send this event when the encryption key has been
/// refreshed due to encryption being started or resumed.
///
/// If the [Encryption Key Refresh Complete](Event::EncryptionKeyRefreshComplete) event was
/// generated due to an encryption pause and resume operation embedded within a change connection
/// link key procedure, the Encryption Key Refresh Complete event shall be sent prior to the Change
/// Connection Link Key Complete event.
///
/// If the Encryption Key Refresh Complete event was generated due to an encryption pause and resume
/// operation embedded within a role switch procedure, the Encryption Key Refresh Complete event
/// shall be sent prior to the Role Change event.
///
/// Defined in Vol 2, Part E, Section 7.7.39 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct EncryptionKeyRefreshComplete<VS> {
    /// Did the encryption key refresh fail, and if so, how?
    pub status: Status<VS>,
    /// Connection Handle for the ACL connection to have the encryption key refreshed on.
    pub conn_handle: ConnectionHandle,
}

fn to_encryption_key_refresh_complete<VE, VS>(
    payload: &[u8],
) -> Result<EncryptionKeyRefreshComplete<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 3);
    Ok(EncryptionKeyRefreshComplete {
        status: payload[0].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
    })
}

/// Indicates to both of the Hosts forming the connection that a new connection has been
/// created. Upon the creation of the connection a connection handle shall be assigned by the
/// Controller, and passed to the Host in this event. If the connection establishment fails this
/// event shall be provided to the Host that had issued the [LE Create
/// Connection](crate::host::Hci::le_create_connection) command.
///
/// This event indicates to the Host which issued a [LE Create
/// Connection](crate::host::Hci::le_create_connection) command and received a [Command
/// Status](Event::CommandStatus) event if the connection establishment failed or was successful.
///
/// Defined in Vol 2, Part E, Section 7.7.65.1 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeConnectionComplete<VS> {
    /// Did the LE Connection fail, and if so, how?
    pub status: Status<VS>,

    /// Connection handle to be used to identify a connection between two Bluetooth devices. The
    /// connection handle is used as an identifier for transmitting and receiving data.
    pub conn_handle: ConnectionHandle,

    /// Role of the device receiving this event in the connection.
    pub role: ConnectionRole,

    /// Address of the peer device.
    pub peer_bd_addr: crate::BdAddrType,

    /// Connection interval used on this connection.
    pub conn_interval: FixedConnectionInterval,

    /// This is only valid for a peripheral. On a central device, this parameter shall be set to
    /// Ppm500.
    pub central_clock_accuracy: CentralClockAccuracy,
}

/// Connection roles as returned by the [LE Connection Complete](Event::LeConnectionComplete) event.
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ConnectionRole {
    /// The device is the central device for the connection.
    ///
    /// The Bluetooth spec refers to these as "master" devices.
    Central,
    /// The device is a peripheral device for the connection.
    ///
    /// The Bluetooth spec refers to these as "slave" devices.
    Peripheral,
}

impl TryFrom<u8> for ConnectionRole {
    type Error = Error<NeverError>;
    fn try_from(value: u8) -> Result<ConnectionRole, Self::Error> {
        match value {
            0 => Ok(ConnectionRole::Central),
            1 => Ok(ConnectionRole::Peripheral),
            _ => Err(Error::BadLeConnectionRole(value)),
        }
    }
}

/// Values for the central (master) clock accuracy as returned by the [LE Connection
/// Complete](Event::LeConnectionComplete) event.
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CentralClockAccuracy {
    /// The central clock is accurate to at least 500 parts-per-million.  This value is also used
    /// when the device is a central device.
    Ppm500,
    /// The central clock is accurate to at least 250 parts-per-million.
    Ppm250,
    /// The central clock is accurate to at least 150 parts-per-million.
    Ppm150,
    /// The central clock is accurate to at least 100 parts-per-million.
    Ppm100,
    /// The central clock is accurate to at least 75 parts-per-million.
    Ppm75,
    /// The central clock is accurate to at least 50 parts-per-million.
    Ppm50,
    /// The central clock is accurate to at least 30 parts-per-million.
    Ppm30,
    /// The central clock is accurate to at least 20 parts-per-million.
    Ppm20,
}

impl TryFrom<u8> for CentralClockAccuracy {
    type Error = Error<NeverError>;
    fn try_from(value: u8) -> Result<CentralClockAccuracy, Self::Error> {
        match value {
            0 => Ok(CentralClockAccuracy::Ppm500),
            1 => Ok(CentralClockAccuracy::Ppm250),
            2 => Ok(CentralClockAccuracy::Ppm150),
            3 => Ok(CentralClockAccuracy::Ppm100),
            4 => Ok(CentralClockAccuracy::Ppm75),
            5 => Ok(CentralClockAccuracy::Ppm50),
            6 => Ok(CentralClockAccuracy::Ppm30),
            7 => Ok(CentralClockAccuracy::Ppm20),
            _ => Err(Error::BadLeCentralClockAccuracy(value)),
        }
    }
}

fn to_le_connection_complete<VE, VS>(payload: &[u8]) -> Result<LeConnectionComplete<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 19);
    let mut bd_addr = crate::BdAddr([0; 6]);
    bd_addr.0.copy_from_slice(&payload[6..12]);
    Ok(LeConnectionComplete {
        status: payload[1].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
        role: payload[4]
            .try_into()
            .map_err(self_convert!(Error::BadLeConnectionRole))?,
        peer_bd_addr: crate::to_bd_addr_type(payload[5], bd_addr)
            .map_err(rewrap_bd_addr_type_err)?,
        conn_interval: FixedConnectionInterval::from_bytes(&payload[12..18])
            .map_err(Error::BadConnectionInterval)?,
        central_clock_accuracy: payload[18]
            .try_into()
            .map_err(self_convert!(Error::BadLeCentralClockAccuracy))?,
    })
}

/// The [LE Advertising Report](Event::LeAdvertisingReport) event indicates that a Bluetooth device
/// or multiple Bluetooth devices have responded to an active scan or received some information
/// during a passive scan. The Controller may queue these advertising reports and send information
/// from multiple devices in one event.
///
/// For Bluetooth Version 5.0: This event shall only be generated if scanning was enabled using the
/// [LE Set Scan Enable](crate::host::Hci::le_set_scan_enable) command. It only reports advertising
/// events that used legacy advertising PDUs.
///
/// Defined in Vol 2, Part E, Section 7.7.65.2 of the spec.
#[derive(Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeAdvertisingReport {
    data_len: usize,
    data_buf: [u8; MAX_ADVERTISING_REPORT_LEN],
}

const MAX_ADVERTISING_REPORT_LEN: usize = 253;

impl LeAdvertisingReport {
    /// Returns an iterator over the advertisements from the event.
    pub fn iter(&self) -> LeAdvertisingReportIterator {
        LeAdvertisingReportIterator {
            inner_iter: self.inner_iter(),
        }
    }

    fn inner_iter<VE>(&self) -> LeAdvertisingReportInnerIterator<'_, VE> {
        LeAdvertisingReportInnerIterator {
            event_data: &self.data_buf[..self.data_len],
            next_index: 0,
            phantom: PhantomData,
        }
    }
}

/// Collection of functions to aid in external tests.
pub mod test_helpers {
    use super::*;

    /// Create an [`LeAdvertisingReport`] from a slice of [`LeAdvertisement`] structs.
    ///
    /// Panics if the resulting report would be too big to fit in a report event.
    pub fn report_with_advertisements(
        advertisements: &[LeAdvertisement<'_>],
    ) -> LeAdvertisingReport {
        let mut data_len = 0;
        let mut data_buf = [0; MAX_ADVERTISING_REPORT_LEN];

        for advertisement in advertisements {
            let event_type_index = data_len;
            let addr_index = 1 + event_type_index;
            let data_len_index = 7 + addr_index;
            let data_start_index = 1 + data_len_index;
            let rssi_index = data_start_index + advertisement.data.len();

            data_buf[event_type_index] = advertisement.event_type as u8;
            advertisement
                .address
                .copy_into_slice(&mut data_buf[addr_index..data_len_index]);
            data_buf[data_len_index] = advertisement.data.len() as u8;
            data_buf[data_start_index..rssi_index].copy_from_slice(advertisement.data);
            data_buf[rssi_index] =
                unsafe { mem::transmute::<i8, u8>(advertisement.rssi.unwrap_or(127)) };

            data_len = 1 + rssi_index;
        }

        LeAdvertisingReport { data_len, data_buf }
    }
}

impl Debug for LeAdvertisingReport {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        write!(f, "{{")?;
        for report in self.iter() {
            write!(f, "{:?}", report)?;
        }
        write!(f, "}}")
    }
}

/// Iterator over the individual LE advertisement responses in the [LE Advertising
/// Report](Event::LeAdvertisingReport) event.
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeAdvertisingReportIterator<'a> {
    inner_iter: LeAdvertisingReportInnerIterator<'a, NeverError>,
}

#[cfg_attr(feature = "defmt", derive(defmt::Format))]
struct LeAdvertisingReportInnerIterator<'a, VE> {
    event_data: &'a [u8],
    next_index: usize,
    phantom: PhantomData<VE>,
}

impl<'a> Iterator for LeAdvertisingReportIterator<'a> {
    type Item = LeAdvertisement<'a>;

    /// Returns the next connection handle-number of completed packets pair from the event.
    fn next(&mut self) -> Option<Self::Item> {
        self.inner_iter.next().unwrap()
    }
}

impl<'a, VE> LeAdvertisingReportInnerIterator<'a, VE> {
    fn next(&mut self) -> Result<Option<LeAdvertisement<'a>>, Error<VE>> {
        if self.next_index >= self.event_data.len() {
            return Ok(None);
        }

        let event_type_index = self.next_index;
        let addr_type_index = event_type_index + 1;
        let addr_index = addr_type_index + 1;
        let data_len_index = addr_index + 6;
        let data_len = self.event_data[data_len_index] as usize;
        let data_start_index = data_len_index + 1;
        let rssi_index = data_start_index + data_len;
        self.next_index = rssi_index + 1;

        if self.next_index > self.event_data.len() {
            return Err(Error::LeAdvertisementReportIncomplete);
        }

        let mut bd_addr = crate::BdAddr([0; 6]);
        bd_addr
            .0
            .copy_from_slice(&self.event_data[addr_index..data_len_index]);
        Ok(Some(LeAdvertisement {
            event_type: self.event_data[event_type_index]
                .try_into()
                .map_err(self_convert!(Error::BadLeAdvertisementType))?,
            address: crate::to_bd_addr_type(self.event_data[addr_type_index], bd_addr)
                .map_err(rewrap_bd_addr_type_err)?,
            data: &self.event_data[data_start_index..rssi_index],
            rssi: match unsafe { mem::transmute::<u8, i8>(self.event_data[rssi_index]) } {
                127 => None,
                value => Some(value),
            },
        }))
    }
}

/// A single advertising report returned by the [LE Advertising Report](Event::LeAdvertisingReport)
/// event.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeAdvertisement<'a> {
    /// Advertising respons type
    pub event_type: AdvertisementEvent,
    /// Address of the advertising device
    pub address: crate::BdAddrType,
    /// Advertising or scan response data formatted as defined in Vol 3, Part C, Section 11 of the
    /// spec.
    pub data: &'a [u8],
    /// Received signal strength.
    ///
    /// - Range is -128 dBm to 20 dBm.
    /// - If the controller sends the value 127, `None` is returned here, since that value indicates
    ///   "RSSI is not available".
    pub rssi: Option<i8>,
}

/// Types of advertisement reports.
///
/// See [`LeAdvertisement`]($crate::event::LeAdvertisement).
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AdvertisementEvent {
    /// Connectable undirected advertising
    Advertisement,
    /// Connectable directed advertising
    DirectAdvertisement,
    /// Scannable undirected advertising
    Scan,
    /// Non connectable undirected advertising
    NonConnectableAdvertisement,
    /// Scan Response
    ScanResponse,
}

impl TryFrom<u8> for AdvertisementEvent {
    type Error = Error<NeverError>;

    fn try_from(value: u8) -> Result<AdvertisementEvent, Self::Error> {
        match value {
            0 => Ok(AdvertisementEvent::Advertisement),
            1 => Ok(AdvertisementEvent::DirectAdvertisement),
            2 => Ok(AdvertisementEvent::Scan),
            3 => Ok(AdvertisementEvent::NonConnectableAdvertisement),
            4 => Ok(AdvertisementEvent::ScanResponse),
            _ => Err(Error::BadLeAdvertisementType(value)),
        }
    }
}

fn to_le_advertising_report<VE>(payload: &[u8]) -> Result<LeAdvertisingReport, Error<VE>> {
    let mut check_iter = LeAdvertisingReportInnerIterator {
        event_data: &payload[2..],
        next_index: 0,
        phantom: PhantomData,
    };
    while (check_iter.next()?).is_some() {}

    let data_len = payload.len() - 2;
    let mut data_buf = [0; MAX_ADVERTISING_REPORT_LEN];
    data_buf[..data_len].copy_from_slice(&payload[2..]);
    Ok(LeAdvertisingReport { data_len, data_buf })
}

/// Indicates that the Controller process to update the connection has completed.
///
/// On a peripheral, if no connection parameters are updated, then this event shall not
/// be issued.
///
/// On a central device, this event shall be issued if the
/// [`connection_update`](crate::host::Hci::le_connection_update) command was sent.
///
/// Note: This event can be issued autonomously by the central device's Controller if it decides to
/// change the connection interval based on the range of allowable connection intervals for that
/// connection.
///
/// Note: The parameter values returned in this event may be different from the parameter values
/// provided by the Host through the [LE Connection Update](crate::host::Hci::le_connection_update)
/// command or the LE Remote Connection Parameter Request Reply command (Section 7.8.31).
///
/// Defined in Vol 2, Part E, Section 7.7.65.3 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeConnectionUpdateComplete<VS> {
    /// Did the LE Connection Update fail, and if so, how?
    pub status: Status<VS>,

    /// Connection handle to be used to identify a connection between two Bluetooth devices. The
    /// connection handle is used as an identifier for transmitting and receiving data.
    pub conn_handle: ConnectionHandle,

    /// Connection interval used on this connection.
    pub conn_interval: FixedConnectionInterval,
}

fn to_le_connection_update_complete<VE, VS>(
    payload: &[u8],
) -> Result<LeConnectionUpdateComplete<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 10);
    Ok(LeConnectionUpdateComplete {
        status: payload[1].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
        conn_interval: FixedConnectionInterval::from_bytes(&payload[4..10])
            .map_err(Error::BadConnectionInterval)?,
    })
}

/// Indicates the completion of the process of the Controller obtaining the features used on the
/// connection and the features supported by the remote Bluetooth device specified by
/// [`conn_handle`](LeReadRemoteUsedFeaturesComplete::conn_handle).
///
/// Note (v5.0): If the features are requested more than once while a connection exists between the
/// two devices, the second and subsequent requests may report a cached copy of the features rather
/// than fetching the feature mask again.
///
/// Defined in Vol 2, Part E, Section 7.7.65.4 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeReadRemoteUsedFeaturesComplete<VS> {
    /// Did the read fail, and if so, how?
    pub status: Status<VS>,
    /// Connection handle to be used to identify a connection between two Bluetooth devices.
    pub conn_handle: ConnectionHandle,
    /// Bit Mask List of used LE features.
    pub features: crate::LinkLayerFeature,
}

fn to_le_read_remote_used_features_complete<VE, VS>(
    payload: &[u8],
) -> Result<LeReadRemoteUsedFeaturesComplete<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 12);

    let feature_flags = LittleEndian::read_u64(&payload[4..]);
    Ok(LeReadRemoteUsedFeaturesComplete {
        status: payload[1].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
        features: crate::LinkLayerFeature::from_bits(feature_flags)
            .ok_or_else(|| Error::BadRemoteUsedFeatureFlag(feature_flags))?,
    })
}

/// The [LE Long Term Key Request](Event::LeLongTermKeyRequest) event indicates that the master
/// device is attempting to encrypt or re-encrypt the link and is requesting the Long Term Key from
/// the Host. (See Vol 6, Part B, Section 5.1.3).
///
/// Defined in Vol 2, Part E, Section 7.7.65.5 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeLongTermKeyRequest {
    /// Connection handle to be used to identify a connection between two Bluetooth devices.
    pub conn_handle: ConnectionHandle,
    /// 64-bit random number.
    pub random_value: u64,
    /// 16-bit encrypted diversifier
    pub encrypted_diversifier: u16,
}

fn to_le_ltk_request<VE>(payload: &[u8]) -> Result<LeLongTermKeyRequest, Error<VE>> {
    require_len!(payload, 13);

    Ok(LeLongTermKeyRequest {
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),
        random_value: LittleEndian::read_u64(&payload[3..]),
        encrypted_diversifier: LittleEndian::read_u16(&payload[11..]),
    })
}

/// Indicates that either the maximum Payload length of a LL DATA PDU
/// has changed or the maximum transmission time of packets which contain
/// LL Data PDUs.
///
/// This event is only generated if any of the values have changed.
///
/// Defined in Vol 2, Part E, Section 7.7.65.7 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LeDataLengthChangeEvent {
    /// Connection handle to be used to identify a connection between two Bluetooth devices.
    pub conn_handle: ConnectionHandle,
    /// Maximum number of octets in a PDU that the lcoal controller
    /// will send.
    pub max_tx_octets: u16,
    /// Maximum time that the local controller will take to send a link
    /// layer packet.
    pub max_tx_time: u16,
    /// Maximum number of octets in a PDU that the local controller
    /// expects to receive.
    pub max_rx_octets: u16,
    /// Maximum time that the local controller expects to take to receive a link
    /// layer packet.
    pub max_rx_time: u16,
}

fn to_le_data_length_change_event<VE>(
    payload: &[u8],
) -> Result<LeDataLengthChangeEvent, Error<VE>> {
    require_len!(payload, 11);

    Ok(LeDataLengthChangeEvent {
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[1..])),

        max_tx_octets: LittleEndian::read_u16(&payload[3..]),
        max_tx_time: LittleEndian::read_u16(&payload[5..]),

        max_rx_octets: LittleEndian::read_u16(&payload[7..]),
        max_rx_time: LittleEndian::read_u16(&payload[9..]),
    })
}

/// PHY types supported by Bluetooth LE.
///
/// See Vol 1, Part A, Section 3.2.2 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Phy {
    /// The LE 1M PHY supports a datarate of 1 MBit/s.
    Le1M,
    /// The LE 2M PHY supports a datarate of 2 MBit/s.
    Le2M,
    /// The LE Coded PHY supports a datarate of either 125 kBit/s or 500 kBit/s.
    LeCoded,
}

impl TryFrom<u8> for Phy {
    type Error = Error<NeverError>;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Phy::Le1M),
            1 => Ok(Phy::Le2M),
            2 => Ok(Phy::LeCoded),
            other => Err(Error::BadPhy(other)),
        }
    }
}

/// Indicates that the controller has changed the transmitter
/// or receiver PHY in use.
///
/// This is either sent in response to a LE Set Phy command,
/// or when the controller does an autonomous PHY update.
///
/// Defined in Vol 4, Part E, Section 7.7.65.12 of the spec.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LePhyUpdateComplete<VS> {
    /// Connection handle to be used to identify a connection between two Bluetooth devices.
    pub conn_handle: ConnectionHandle,
    /// Status of the PHY update.
    pub status: Status<VS>,
    /// PHY used for transmission.
    pub tx_phy: Phy,
    /// PHY used for reception.
    pub rx_phy: Phy,
}

fn to_le_phy_update_complete<VS, VE>(payload: &[u8]) -> Result<LePhyUpdateComplete<VS>, Error<VE>>
where
    Status<VS>: TryFrom<u8, Error = BadStatusError>,
{
    require_len!(payload, 6);

    Ok(LePhyUpdateComplete {
        status: payload[1].try_into().map_err(rewrap_bad_status)?,
        conn_handle: ConnectionHandle(LittleEndian::read_u16(&payload[2..])),
        tx_phy: Phy::try_from(payload[4]).map_err(self_convert!(Error::BadPhy))?,
        rx_phy: Phy::try_from(payload[5]).map_err(self_convert!(Error::BadPhy))?,
    })
}