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
//! 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)] 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(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), /// 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)?)), _ => 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: 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)] 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)] 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)] 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)] 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<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)] 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)] 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)] 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(&self) -> NumberOfCompletedPacketsIterator { 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, }) } /// 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](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)] 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)] 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)] 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)] 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<'a>( advertisements: &[LeAdvertisement<'a>], ) -> 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. pub struct LeAdvertisingReportIterator<'a> { inner_iter: LeAdvertisingReportInnerIterator<'a, NeverError>, } 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)] 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)] 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 let Some(_) = check_iter.next()? {} 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)] 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: 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)] 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..]), }) }