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
//! 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]

#[macro_export]
macro_rules! require_len {
    ($left:expr, $right:expr) => {
        if $left.len() != $right {
            return Err($crate::event::Error::BadLength($left.len(), $right));
        }
    };
}

#[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<!> 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 byteorder::{ByteOrder, LittleEndian};
use core::convert::{TryFrom, TryInto};
use core::fmt::{Debug, Formatter, Result as FmtResult};
use core::marker::{PhantomData, Sized};
use core::mem;
use types::{ConnectionIntervalError, FixedConnectionInterval};

/// 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.
#[derive(Clone, Debug)]
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),

    /// 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;

    /// Enumeration of vendor-specific status codes.
    type Status: TryFrom<u8, Error = ::BadStatusError> + Clone + Debug;

    /// Enumeration of return parameters for vendor-specific commands.
    type ReturnParameters: VendorReturnParameters<Error = Self::Error> + Clone + Debug;

    /// 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)]
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(::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),

    /// 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: ::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)?)),
        _ => 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)]
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: ::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)]
pub enum LinkType {
    /// Synchronous, connection-oriented link
    Sco,
    /// Asynchronous, connection-less link
    Acl,
}

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

    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 = ::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: 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<!>> {
    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)]
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](::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)]
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)]
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<!>;
    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)]
pub struct RemoteVersionInformation<VS> {
    /// Status of the read event.
    pub status: ::Status<VS>,

    /// Connection Handle which was used for the
    /// [`read_remote_version_information`](::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)]
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: ::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: ::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)]
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)]
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<'a>(&'a self) -> NumberOfCompletedPacketsIterator<'a> {
        NumberOfCompletedPacketsIterator {
            event: self,
            next_index: 0,
        }
    }
}

/// Iterator over the connection handle-number of completed packet pairs from the
/// [`NumberOfCompletedPackets`] event.
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)]
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: 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)]
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)]
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](::host::Hci::le_create_connection) command.
///
/// This event indicates to the Host which issued a [LE Create
/// Connection](::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)]
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: ::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)]
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<!>;
    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)]
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<!>;
    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 = ::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: ::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](::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)]
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<'a>(&'a self) -> LeAdvertisingReportIterator<'a> {
        LeAdvertisingReportIterator {
            inner_iter: self.inner_iter(),
        }
    }

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

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.
pub struct LeAdvertisingReportIterator<'a> {
    inner_iter: LeAdvertisingReportInnerIterator<'a, !>,
}

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 = ::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: ::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)]
pub struct LeAdvertisement<'a> {
    /// Advertising respons type
    pub event_type: AdvertisementEvent,
    /// Address of the advertising device
    pub address: ::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)]
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<!>;

    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,
    };
    loop {
        match check_iter.next()? {
            Some(_) => (),
            None => break,
        }
    }

    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_len,
        data_buf: 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`](::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](::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)]
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)]
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: ::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: ::LinkLayerFeature::from_bits(feature_flags)
            .ok_or(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)]
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..]),
    })
}