1use super::VendorReturnParameters;
13use crate::{BadStatusError, ConnectionHandle, Status};
14use byteorder::{ByteOrder, LittleEndian};
15use core::convert::{TryFrom, TryInto};
16use core::fmt::{Debug, Formatter, Result as FmtResult};
17use core::mem;
18
19#[derive(Clone, Debug)]
27pub struct CommandComplete<V>
28where
29 V: super::VendorEvent,
30{
31 pub num_hci_command_packets: u8,
41
42 pub return_params: ReturnParameters<V>,
44}
45
46impl<V> CommandComplete<V>
47where
48 V: super::VendorEvent,
49{
50 pub fn new(bytes: &[u8]) -> Result<CommandComplete<V>, crate::event::Error<V::Error>> {
63 require_len_at_least!(bytes, 3);
64
65 let params = match crate::opcode::Opcode(LittleEndian::read_u16(&bytes[1..])) {
66 crate::opcode::Opcode(0x0000) => ReturnParameters::Spontaneous,
67 crate::opcode::SET_EVENT_MASK => {
68 ReturnParameters::SetEventMask(to_status(&bytes[3..])?)
69 }
70 crate::opcode::RESET => ReturnParameters::Reset(to_status(&bytes[3..])?),
71 crate::opcode::READ_TX_POWER_LEVEL => {
72 ReturnParameters::ReadTxPowerLevel(to_tx_power_level(&bytes[3..])?)
73 }
74 crate::opcode::READ_LOCAL_VERSION_INFO => {
75 ReturnParameters::ReadLocalVersionInformation(to_local_version_info(&bytes[3..])?)
76 }
77 crate::opcode::READ_LOCAL_SUPPORTED_COMMANDS => {
78 ReturnParameters::ReadLocalSupportedCommands(to_supported_commands(&bytes[3..])?)
79 }
80 crate::opcode::READ_LOCAL_SUPPORTED_FEATURES => {
81 ReturnParameters::ReadLocalSupportedFeatures(to_supported_features(&bytes[3..])?)
82 }
83 crate::opcode::READ_BD_ADDR => ReturnParameters::ReadBdAddr(to_bd_addr(&bytes[3..])?),
84 crate::opcode::READ_RSSI => ReturnParameters::ReadRssi(to_read_rssi(&bytes[3..])?),
85 crate::opcode::LE_SET_EVENT_MASK => {
86 ReturnParameters::LeSetEventMask(to_status(&bytes[3..])?)
87 }
88 crate::opcode::LE_READ_BUFFER_SIZE => {
89 ReturnParameters::LeReadBufferSize(to_le_read_buffer_status(&bytes[3..])?)
90 }
91 crate::opcode::LE_READ_LOCAL_SUPPORTED_FEATURES => {
92 ReturnParameters::LeReadLocalSupportedFeatures(to_le_local_supported_features(
93 &bytes[3..],
94 )?)
95 }
96 crate::opcode::LE_SET_RANDOM_ADDRESS => {
97 ReturnParameters::LeSetRandomAddress(to_status(&bytes[3..])?)
98 }
99 crate::opcode::LE_SET_ADVERTISING_PARAMETERS => {
100 ReturnParameters::LeSetAdvertisingParameters(to_status(&bytes[3..])?)
101 }
102 crate::opcode::LE_READ_ADVERTISING_CHANNEL_TX_POWER => {
103 ReturnParameters::LeReadAdvertisingChannelTxPower(
104 to_le_advertising_channel_tx_power(&bytes[3..])?,
105 )
106 }
107 crate::opcode::LE_SET_ADVERTISING_DATA => {
108 ReturnParameters::LeSetAdvertisingData(to_status(&bytes[3..])?)
109 }
110 crate::opcode::LE_SET_SCAN_RESPONSE_DATA => {
111 ReturnParameters::LeSetScanResponseData(to_status(&bytes[3..])?)
112 }
113 crate::opcode::LE_SET_ADVERTISE_ENABLE => {
114 to_le_set_advertise_enable(to_status(&bytes[3..])?)
115 }
116 crate::opcode::LE_SET_SCAN_PARAMETERS => {
117 ReturnParameters::LeSetScanParameters(to_status(&bytes[3..])?)
118 }
119 crate::opcode::LE_SET_SCAN_ENABLE => {
120 ReturnParameters::LeSetScanEnable(to_status(&bytes[3..])?)
121 }
122 crate::opcode::LE_CREATE_CONNECTION_CANCEL => {
123 ReturnParameters::LeCreateConnectionCancel(to_status(&bytes[3..])?)
124 }
125 crate::opcode::LE_READ_WHITE_LIST_SIZE => {
126 ReturnParameters::LeReadWhiteListSize(to_status(&bytes[3..])?, bytes[4] as usize)
127 }
128 crate::opcode::LE_CLEAR_WHITE_LIST => {
129 ReturnParameters::LeClearWhiteList(to_status(&bytes[3..])?)
130 }
131 crate::opcode::LE_ADD_DEVICE_TO_WHITE_LIST => {
132 ReturnParameters::LeAddDeviceToWhiteList(to_status(&bytes[3..])?)
133 }
134 crate::opcode::LE_REMOVE_DEVICE_FROM_WHITE_LIST => {
135 ReturnParameters::LeRemoveDeviceFromWhiteList(to_status(&bytes[3..])?)
136 }
137 crate::opcode::LE_SET_HOST_CHANNEL_CLASSIFICATION => {
138 ReturnParameters::LeSetHostChannelClassification(to_status(&bytes[3..])?)
139 }
140 crate::opcode::LE_READ_CHANNEL_MAP => {
141 ReturnParameters::LeReadChannelMap(to_le_channel_map_parameters(&bytes[3..])?)
142 }
143 crate::opcode::LE_ENCRYPT => {
144 ReturnParameters::LeEncrypt(to_le_encrypted_data(&bytes[3..])?)
145 }
146 crate::opcode::LE_RAND => ReturnParameters::LeRand(to_random_number(&bytes[3..])?),
147 crate::opcode::LE_LTK_REQUEST_REPLY => {
148 ReturnParameters::LeLongTermKeyRequestReply(to_le_ltk_request_reply(&bytes[3..])?)
149 }
150 crate::opcode::LE_LTK_REQUEST_NEGATIVE_REPLY => {
151 ReturnParameters::LeLongTermKeyRequestNegativeReply(to_le_ltk_request_reply(
152 &bytes[3..],
153 )?)
154 }
155 crate::opcode::LE_READ_STATES => {
156 ReturnParameters::LeReadSupportedStates(to_le_read_states(&bytes[3..])?)
157 }
158 crate::opcode::LE_RECEIVER_TEST => {
159 ReturnParameters::LeReceiverTest(to_status(&bytes[3..])?)
160 }
161 crate::opcode::LE_TRANSMITTER_TEST => {
162 ReturnParameters::LeTransmitterTest(to_status(&bytes[3..])?)
163 }
164 crate::opcode::LE_TEST_END => ReturnParameters::LeTestEnd(to_le_test_end(&bytes[3..])?),
165 other => {
166 const VENDOR_OGF: u16 = 0x3F;
167 if other.ogf() != VENDOR_OGF {
168 return Err(crate::event::Error::UnknownOpcode(other));
169 }
170
171 ReturnParameters::Vendor(V::ReturnParameters::new(&bytes)?)
172 }
173 };
174 Ok(CommandComplete::<V> {
175 num_hci_command_packets: bytes[0],
176 return_params: params,
177 })
178 }
179}
180
181#[derive(Copy, Clone, Debug)]
184pub enum ReturnParameters<V>
185where
186 V: super::VendorEvent,
187{
188 Spontaneous,
191
192 SetEventMask(Status<V::Status>),
194
195 Reset(Status<V::Status>),
197
198 ReadTxPowerLevel(TxPowerLevel<V::Status>),
200
201 ReadLocalVersionInformation(LocalVersionInfo<V::Status>),
204
205 ReadLocalSupportedCommands(LocalSupportedCommands<V::Status>),
208
209 ReadLocalSupportedFeatures(LocalSupportedFeatures<V::Status>),
212
213 ReadBdAddr(ReadBdAddr<V::Status>),
215
216 ReadRssi(ReadRssi<V::Status>),
218
219 LeSetEventMask(Status<V::Status>),
221
222 LeReadBufferSize(LeReadBufferSize<V::Status>),
225
226 LeReadLocalSupportedFeatures(LeSupportedFeatures<V::Status>),
229
230 LeSetRandomAddress(Status<V::Status>),
233
234 LeSetAdvertisingParameters(Status<V::Status>),
237
238 LeReadAdvertisingChannelTxPower(LeAdvertisingChannelTxPower<V::Status>),
241
242 LeSetAdvertisingData(Status<V::Status>),
245
246 LeSetScanResponseData(Status<V::Status>),
249
250 #[cfg(not(feature = "version-5-0"))]
253 LeSetAdvertiseEnable(Status<V::Status>),
254
255 #[cfg(feature = "version-5-0")]
258 LeSetAdvertisingEnable(Status<V::Status>),
259
260 LeSetScanParameters(Status<V::Status>),
263
264 LeSetScanEnable(Status<V::Status>),
266
267 LeCreateConnectionCancel(Status<V::Status>),
270
271 LeReadWhiteListSize(Status<V::Status>, usize),
274
275 LeClearWhiteList(Status<V::Status>),
277
278 LeAddDeviceToWhiteList(Status<V::Status>),
281
282 LeRemoveDeviceFromWhiteList(Status<V::Status>),
285
286 LeSetHostChannelClassification(Status<V::Status>),
289
290 LeReadChannelMap(ChannelMapParameters<V::Status>),
293
294 LeEncrypt(EncryptedReturnParameters<V::Status>),
296
297 LeRand(LeRandom<V::Status>),
299
300 LeLongTermKeyRequestReply(LeLongTermRequestReply<V::Status>),
303
304 LeLongTermKeyRequestNegativeReply(LeLongTermRequestReply<V::Status>),
307
308 LeReadSupportedStates(LeReadSupportedStates<V::Status>),
311
312 LeReceiverTest(Status<V::Status>),
314
315 LeTransmitterTest(Status<V::Status>),
317
318 LeTestEnd(LeTestEnd<V::Status>),
320
321 Vendor(V::ReturnParameters),
323}
324
325fn to_status<VE, VS>(bytes: &[u8]) -> Result<Status<VS>, crate::event::Error<VE>>
326where
327 Status<VS>: TryFrom<u8, Error = BadStatusError>,
328{
329 bytes[0].try_into().map_err(super::rewrap_bad_status)
330}
331
332#[derive(Copy, Clone, Debug)]
335pub struct TxPowerLevel<VS> {
336 pub status: Status<VS>,
338
339 pub conn_handle: ConnectionHandle,
341
342 pub tx_power_level_dbm: i8,
346}
347
348fn to_tx_power_level<VE, VS>(bytes: &[u8]) -> Result<TxPowerLevel<VS>, crate::event::Error<VE>>
349where
350 Status<VS>: TryFrom<u8, Error = BadStatusError>,
351{
352 require_len!(bytes, 4);
353 Ok(TxPowerLevel {
354 status: to_status(bytes)?,
355 conn_handle: ConnectionHandle(LittleEndian::read_u16(&bytes[1..])),
356 tx_power_level_dbm: unsafe { mem::transmute::<u8, i8>(bytes[3]) },
357 })
358}
359
360#[derive(Copy, Clone, Debug)]
363pub struct LocalVersionInfo<VS> {
364 pub status: Status<VS>,
366
367 pub hci_version: u8,
372
373 pub hci_revision: u16,
376
377 pub lmp_version: u8,
382
383 pub manufacturer_name: u16,
386
387 pub lmp_subversion: u16,
393}
394
395fn to_local_version_info<VE, VS>(
396 bytes: &[u8],
397) -> Result<LocalVersionInfo<VS>, crate::event::Error<VE>>
398where
399 Status<VS>: TryFrom<u8, Error = BadStatusError>,
400{
401 require_len!(bytes, 9);
402
403 Ok(LocalVersionInfo {
404 status: bytes[0].try_into().map_err(super::rewrap_bad_status)?,
405 hci_version: bytes[1],
406 hci_revision: LittleEndian::read_u16(&bytes[2..]),
407 lmp_version: bytes[4],
408 manufacturer_name: LittleEndian::read_u16(&bytes[5..]),
409 lmp_subversion: LittleEndian::read_u16(&bytes[7..]),
410 })
411}
412
413#[derive(Copy, Clone, Debug)]
416pub struct LocalSupportedCommands<VS> {
417 pub status: Status<VS>,
419
420 pub supported_commands: CommandFlags,
422}
423
424const COMMAND_FLAGS_SIZE: usize = 64;
425
426bitflag_array! {
427 #[derive(Copy, Clone)]
430 pub struct CommandFlags : COMMAND_FLAGS_SIZE;
431 pub struct CommandFlag;
432
433 const INQUIRY = 0, 1 << 0;
435 const INQUIRY_CANCEL = 0, 1 << 1;
437 const PERIODIC_INQUIRY_MODE = 0, 1 << 2;
439 const EXIT_PERIODIC_INQUIRY_MODE = 0, 1 << 3;
441 const CREATE_CONNECTION = 0, 1 << 4;
443 const DISCONNECT = 0, 1 << 5;
445 #[deprecated]
447 const ADD_SCO_CONNECTION = 0, 1 << 6;
448 const CREATE_CONNECTION_CANCEL = 0, 1 << 7;
450 const ACCEPT_CONNECTION_REQUEST = 1, 1 << 0;
452 const REJECT_CONNECTION_REQUEST = 1, 1 << 1;
454 const LINK_KEY_REQUEST_REPLY = 1, 1 << 2;
456 const LINK_KEY_REQUEST_NEGATIVE_REPLY = 1, 1 << 3;
458 const PIN_CODE_REQUEST_REPLY = 1, 1 << 4;
460 const PIN_CODE_REQUEST_NEGATIVE_REPLY = 1, 1 << 5;
462 const CHANGE_CONNECTION_PACKET_TYPE = 1, 1 << 6;
464 const AUTHENTICATION_REQUESTED = 1, 1 << 7;
466 const SET_CONNECTION_ENCRYPTION = 2, 1 << 0;
468 const CHANGE_CONNECTION_LINK_KEY = 2, 1 << 1;
470 const MASTER_LINK_KEY = 2, 1 << 2;
472 const REMOTE_NAME_REQUEST = 2, 1 << 3;
474 const REMOTE_NAME_REQUEST_CANCEL = 2, 1 << 4;
476 const READ_REMOTE_SUPPORTED_FEATURES = 2, 1 << 5;
478 const READ_REMOTE_EXTENDED_FEATURES = 2, 1 << 6;
480 const READ_REMOTE_VERSION_INFORMATION = 2, 1 << 7;
482 const READ_CLOCK_OFFSET = 3, 1 << 0;
484 const READ_LMP_HANDLE = 3, 1 << 1;
486 const HOLD_MODE = 4, 1 << 1;
488 const SNIFF_MODE = 4, 1 << 2;
490 const EXIT_SNIFF_MODE = 4, 1 << 3;
492 const PARK_STATE = 4, 1 << 4;
494 const EXIT_PARK_STATE = 4, 1 << 5;
496 const QOS_SETUP = 4, 1 << 6;
498 const ROLE_DISCOVERY = 4, 1 << 7;
500 const SWITCH_ROLE = 5, 1 << 0;
502 const READ_LINK_POLICY_SETTINGS = 5, 1 << 1;
504 const WRITE_LINK_POLICY_SETTINGS = 5, 1 << 2;
506 const READ_DEFAULT_LINK_POLICY_SETTINGS = 5, 1 << 3;
508 const WRITE_DEFAULT_LINK_POLICY_SETTINGS = 5, 1 << 4;
510 const FLOW_SPECIFICATION = 5, 1 << 5;
512 const SET_EVENT_MASK = 5, 1 << 6;
514 const RESET = 5, 1 << 7;
516 const SET_EVENT_FILTER = 6, 1 << 0;
518 const FLUSH = 6, 1 << 1;
520 const READ_PIN_TYPE = 6, 1 << 2;
522 const WRITE_PIN_TYPE = 6, 1 << 3;
524 const CREATE_NEW_UNIT_KEY = 6, 1 << 4;
526 const READ_STORED_LINK_KEY = 6, 1 << 5;
528 const WRITE_STORED_LINK_KEY = 6, 1 << 6;
530 const DELETE_STORED_LINK_KEY = 6, 1 << 7;
532 const WRITE_LOCAL_NAME = 7, 1 << 0;
534 const READ_LOCAL_NAME = 7, 1 << 1;
536 const READ_CONNECTION_ACCEPT_TIMEOUT = 7, 1 << 2;
538 const WRITE_CONNECTION_ACCEPT_TIMEOUT = 7, 1 << 3;
540 const READ_PAGE_TIMEOUT = 7, 1 << 4;
542 const WRITE_PAGE_TIMEOUT = 7, 1 << 5;
544 const READ_SCAN_ENABLE = 7, 1 << 6;
546 const WRITE_SCAN_ENABLE = 7, 1 << 7;
548 const READ_PAGE_SCAN_ACTIVITY = 8, 1 << 0;
550 const WRITE_PAGE_SCAN_ACTIVITY = 8, 1 << 1;
552 const READ_INQUIRY_SCAN_ACTIVITY = 8, 1 << 2;
554 const WRITE_INQUIRY_SCAN_ACTIVITY = 8, 1 << 3;
556 const READ_AUTHENTICATION_ENABLE = 8, 1 << 4;
558 const WRITE_AUTHENTICATION_ENABLE = 8, 1 << 5;
560 #[deprecated]
562 const READ_ENCRYPTION_MODE = 8, 1 << 6;
563 #[deprecated]
565 const WRITE_ENCRYPTION_MODE = 8, 1 << 7;
566 const READ_CLASS_OF_DEVICE = 9, 1 << 0;
568 const WRITE_CLASS_OF_DEVICE = 9, 1 << 1;
570 const READ_VOICE_SETTING = 9, 1 << 2;
572 const WRITE_VOICE_SETTING = 9, 1 << 3;
574 const READ_AUTOMATIC_FLUSH_TIMEOUT = 9, 1 << 4;
576 const WRITE_AUTOMATIC_FLUSH_TIMEOUT = 9, 1 << 5;
578 const READ_NUM_BROADCAST_RETRANSMISSIONS = 9, 1 << 6;
580 const WRITE_NUM_BROADCAST_RETRANSMISSIONS = 9, 1 << 7;
582 const READ_HOLD_MODE_ACTIVITY = 10, 1 << 0;
584 const WRITE_HOLD_MODE_ACTIVITY = 10, 1 << 1;
586 const READ_TRANSMIT_POWER_LEVEL = 10, 1 << 2;
588 const READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 10, 1 << 3;
590 const WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 10, 1 << 4;
592 const SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 10, 1 << 5;
594 const HOST_BUFFER_SIZE = 10, 1 << 6;
596 const HOST_NUMBER_OF_COMPLETED_PACKETS = 10, 1 << 7;
598 const READ_LINK_SUPERVISION_TIMEOUT = 11, 1 << 0;
600 const WRITE_LINK_SUPERVISION_TIMEOUT = 11, 1 << 1;
602 const READ_NUMBER_OF_SUPPORTED_IAC = 11, 1 << 2;
604 const READ_CURRENT_IAC_LAP = 11, 1 << 3;
606 const WRITE_CURRENT_IAC_LAP = 11, 1 << 4;
608 #[deprecated]
610 const READ_PAGE_SCAN_MODE_PERIOD = 11, 1 << 5;
611 #[deprecated]
613 const WRITE_PAGE_SCAN_MODE_PERIOD = 11, 1 << 6;
614 #[deprecated]
616 const READ_PAGE_SCAN_MODE = 11, 1 << 7;
617 #[deprecated]
619 const WRITE_PAGE_SCAN_MODE = 12, 1 << 0;
620 const SET_AFH_HOST_CHANNEL_CLASSIFICATION = 12, 1 << 1;
622 const READ_INQUIRY_SCAN_TYPE = 12, 1 << 4;
624 const WRITE_INQUIRY_SCAN_TYPE = 12, 1 << 5;
626 const READ_INQUIRY_MODE = 12, 1 << 6;
628 const WRITE_INQUIRY_MODE = 12, 1 << 7;
630 const READ_PAGE_SCAN_TYPE = 13, 1 << 0;
632 const WRITE_PAGE_SCAN_TYPE = 13, 1 << 1;
634 const READ_AFH_CHANNEL_ASSESSMENT_MODE = 13, 1 << 2;
636 const WRITE_AFH_CHANNEL_ASSESSMENT_MODE = 13, 1 << 3;
638 const READ_LOCAL_VERSION_INFORMATION = 14, 1 << 3;
640 const READ_LOCAL_SUPPORTED_FEATURES = 14, 1 << 5;
642 const READ_LOCAL_EXTENDED_FEATURES = 14, 1 << 6;
644 const READ_BUFFER_SIZE = 14, 1 << 7;
646 #[deprecated]
648 const READ_COUNTRY_CODE = 15, 1 << 0;
649 const READ_BD_ADDR = 15, 1 << 1;
651 const READ_FAILED_CONTACT_COUNTER = 15, 1 << 2;
653 const RESET_FAILED_CONTACT_COUNTER = 15, 1 << 3;
655 const READ_LINK_QUALITY = 15, 1 << 4;
657 const READ_RSSI = 15, 1 << 5;
659 const READ_AFH_CHANNEL_MAP = 15, 1 << 6;
661 const READ_CLOCK = 15, 1 << 7;
663 const READ_LOOPBACK_MODE = 16, 1 << 0;
665 const WRITE_LOOPBACK_MODE = 16, 1 << 1;
667 const ENABLE_DEVICE_UNDER_TEST_MODE = 16, 1 << 2;
669 const SETUP_SYNCHRONOUS_CONNECTION_REQUEST = 16, 1 << 3;
671 const ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST = 16, 1 << 4;
673 const REJECT_SYNCHRONOUS_CONNECTION_REQUEST = 16, 1 << 5;
675 const READ_EXTENDED_INQUIRY_RESPONSE = 17, 1 << 0;
677 const WRITE_EXTENDED_INQUIRY_RESPONSE = 17, 1 << 1;
679 const REFRESH_ENCRYPTION_KEY = 17, 1 << 2;
681 const SNIFF_SUBRATING = 17, 1 << 4;
683 const READ_SIMPLE_PAIRING_MODE = 17, 1 << 5;
685 const WRITE_SIMPLE_PAIRING_MODE = 17, 1 << 6;
687 const READ_LOCAL_OOB_DATA = 17, 1 << 7;
689 const READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = 18, 1 << 0;
691 const WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = 18, 1 << 1;
693 const READ_DEFAULT_ERRONEOUS_DATA_REPORTING = 18, 1 << 2;
695 const WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING = 18, 1 << 3;
697 const IO_CAPABILITY_REQUEST_REPLY = 18, 1 << 7;
699 const USER_CONFIRMATION_REQUEST_REPLY = 19, 1 << 0;
701 const USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = 19, 1 << 1;
703 const USER_PASSKEY_REQUEST_REPLY = 19, 1 << 2;
705 const USER_PASSKEY_REQUEST_NEGATIVE_REPLY = 19, 1 << 3;
707 const REMOTE_OOB_DATA_REQUEST_REPLY = 19, 1 << 4;
709 const WRITE_SIMPLE_PAIRING_DEBUG_MODE = 19, 1 << 5;
711 const ENHANCED_FLUSH = 19, 1 << 6;
713 const REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = 19, 1 << 7;
715 const SEND_KEYPRESS_NOTIFICATION = 20, 1 << 2;
717 const IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = 20, 1 << 3;
719 const READ_ENCRYPTION_KEY_SIZE = 20, 1 << 4;
721 const CREATE_PHYSICAL_LINK = 21, 1 << 0;
723 const ACCEPT_PHYSICAL_LINK = 21, 1 << 1;
725 const DISCONNECT_PHYSICAL_LINK = 21, 1 << 2;
727 const CREATE_LOGICAL_LINK = 21, 1 << 3;
729 const ACCEPT_LOGICAL_LINK = 21, 1 << 4;
731 const DISCONNECT_LOGICAL_LINK = 21, 1 << 5;
733 const LOGICAL_LINK_CANCEL = 21, 1 << 6;
735 const FLOW_SPEC_MODIFY = 21, 1 << 7;
737 const READ_LOGICAL_LINK_ACCEPT_TIMEOUT = 22, 1 << 0;
739 const WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT = 22, 1 << 1;
741 const SET_EVENT_MASK_PAGE_2 = 22, 1 << 2;
743 const READ_LOCATION_DATA = 22, 1 << 3;
745 const WRITE_LOCATION_DATA = 22, 1 << 4;
747 const READ_LOCAL_AMP_INFO = 22, 1 << 5;
749 const READ_LOCAL_AMP_ASSOC = 22, 1 << 6;
751 const WRITE_REMOTE_AMP_ASSOC = 22, 1 << 7;
753 const READ_FLOW_CONTROL_MODE = 23, 1 << 0;
755 const WRITE_FLOW_CONTROL_MODE = 23, 1 << 1;
757 const READ_DATA_BLOCK_SIZE = 23, 1 << 2;
759 const ENABLE_AMP_RECEIVER_REPORTS = 23, 1 << 5;
761 const AMP_TEST_END = 23, 1 << 6;
763 const AMP_TEST = 23, 1 << 7;
765 const READ_ENHANCED_TRANSMIT_POWER_LEVEL = 24, 1 << 0;
767 const READ_BEST_EFFORT_FLUSH_TIMEOUT = 24, 1 << 2;
769 const WRITE_BEST_EFFORT_FLUSH_TIMEOUT = 24, 1 << 3;
771 const SHORT_RANGE_MODE = 24, 1 << 4;
773 const READ_LE_HOST_SUPPORT = 24, 1 << 5;
775 const WRITE_LE_HOST_SUPPORT = 24, 1 << 6;
777 const LE_SET_EVENT_MASK = 25, 1 << 0;
779 const LE_READ_BUFFER_SIZE = 25, 1 << 1;
781 const LE_READ_LOCAL_SUPPORTED_FEATURES = 25, 1 << 2;
783 const LE_SET_RANDOM_ADDRESS = 25, 1 << 4;
785 const LE_SET_ADVERTISING_PARAMETERS = 25, 1 << 5;
787 const LE_READ_ADVERTISING_CHANNEL_TX_POWER = 25, 1 << 6;
789 const LE_SET_ADVERTISING_DATA = 25, 1 << 7;
791 const LE_SET_SCAN_RESPONSE_DATA = 26, 1 << 0;
793 const LE_SET_ADVERTISE_ENABLE = 26, 1 << 1;
795 const LE_SET_SCAN_PARAMETERS = 26, 1 << 2;
797 const LE_SET_SCAN_ENABLE = 26, 1 << 3;
799 const LE_CREATE_CONNECTION = 26, 1 << 4;
801 const LE_CREATE_CONNECTION_CANCEL = 26, 1 << 5;
803 const LE_READ_WHITE_LIST_SIZE = 26, 1 << 6;
805 const LE_CLEAR_WHITE_LIST = 26, 1 << 7;
807 const LE_ADD_DEVICE_TO_WHITE_LIST = 27, 1 << 0;
809 const LE_REMOVE_DEVICE_FROM_WHITE_LIST = 27, 1 << 1;
811 const LE_CONNECTION_UPDATE = 27, 1 << 2;
813 const LE_SET_HOST_CHANNEL_CLASSIFICATION = 27, 1 << 3;
815 const LE_READ_CHANNEL_MAP = 27, 1 << 4;
817 const LE_READ_REMOTE_USED_FEATURES = 27, 1 << 5;
819 const LE_ENCRYPT = 27, 1 << 6;
821 const LE_RAND = 27, 1 << 7;
823 const LE_START_ENCRYPTION = 28, 1 << 0;
825 const LE_LONG_TERM_KEY_REQUEST_REPLY = 28, 1 << 1;
827 const LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = 28, 1 << 2;
829 const LE_READ_SUPPORTED_STATES = 28, 1 << 3;
831 const LE_RECEIVER_TEST = 28, 1 << 4;
833 const LE_TRANSMITTER_TEST = 28, 1 << 5;
835 const LE_TEST_END = 28, 1 << 6;
837 const ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = 29, 1 << 3;
839 const ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION = 29, 1 << 4;
841 const READ_LOCAL_SUPPORTED_CODECS = 29, 1 << 5;
843 const SET_MWS_CHANNEL_PARAMETERS_COMMAND = 29, 1 << 6;
845 const SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND = 29, 1 << 7;
847 const SET_MWS_SIGNALING_COMMAND = 30, 1 << 0;
849 const SET_TRANSPORT_LAYER_COMMAND = 30, 1 << 1;
851 const SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND = 30, 1 << 2;
853 const GET_TRANSPORT_LAYER_CONFIGURATION_COMMAND = 30, 1 << 3;
855 const SET_MWS_PATTERN_CONFIGURATION_COMMAND = 30, 1 << 4;
857 const SET_TRIGGERED_CLOCK_CAPTURE = 30, 1 << 5;
859 const TRUNCATED_PAGE = 30, 1 << 6;
861 const TRUNCATED_PAGE_CANCEL = 30, 1 << 7;
863 const SET_CONNECTIONLESS_PERIPHERAL_BROADCAST = 31, 1 << 0;
865 const SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE = 31, 1 << 1;
867 const START_SYNCHRONIZATION_TRAIN = 31, 1 << 2;
869 const RECEIVE_SYNCHRONIZATION_TRAIN = 31, 1 << 3;
871 const SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA = 31, 1 << 6;
873 const READ_SYNCHRONIZATION_TRAIN_PARAMETERS = 31, 1 << 7;
875 const WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS = 32, 1 << 0;
877 const REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY = 32, 1 << 1;
879 const READ_SECURE_CONNECTIONS_HOST_SUPPORT = 32, 1 << 2;
881 const WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = 32, 1 << 3;
883 const READ_AUTHENTICATED_PAYLOAD_TIMEOUT = 32, 1 << 4;
885 const WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT = 32, 1 << 5;
887 const READ_LOCAL_OOB_EXTENDED_DATA = 32, 1 << 6;
889 const WRITE_SECURE_CONNECTIONS_TEST_MODE = 32, 1 << 7;
891 const READ_EXTENDED_PAGE_TIMEOUT = 33, 1 << 0;
893 const WRITE_EXTENDED_PAGE_TIMEOUT = 33, 1 << 1;
895 const READ_EXTENDED_INQUIRY_LENGTH = 33, 1 << 2;
897 const WRITE_EXTENDED_INQUIRY_LENGTH = 33, 1 << 3;
899 const LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND = 33, 1 << 4;
901 const LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND = 33, 1 << 5;
903 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
905 const LE_SET_DATA_LENGTH = 33, 1 << 6;
906 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
908 const LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = 33, 1 << 7;
909 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
911 const LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = 34, 1 << 0;
912 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
914 const LE_READ_LOCAL_P256_PUBLIC_KEY = 34, 1 << 1;
915 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
917 const LE_GENERATE_DH_KEY = 34, 1 << 2;
918 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
920 const LE_ADD_DEVICE_TO_RESOLVING_LIST = 34, 1 << 3;
921 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
923 const LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = 34, 1 << 4;
924 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
926 const LE_CLEAR_RESOLVING_LIST = 34, 1 << 5;
927 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
929 const LE_READ_RESOLVING_LIST_SIZE = 34, 1 << 6;
930 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
932 const LE_READ_PEER_RESOLVABLE_ADDRESS = 34, 1 << 7;
933 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
935 const LE_READ_LOCAL_RESOLVABLE_ADDRESS = 35, 1 << 0;
936 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
938 const LE_SET_ADDRESS_RESOLUTION_ENABLE = 35, 1 << 1;
939 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
941 const LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = 35, 1 << 2;
942 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
944 const LE_READ_MAXIMUM_DATA_LENGTH = 35, 1 << 3;
945 #[cfg(feature = "version-5-0")]
947 const LE_READ_PHY_COMMAND = 35, 1 << 4;
948 #[cfg(feature = "version-5-0")]
950 const LE_SET_DEFAULT_PHY_COMMAND = 35, 1 << 5;
951 #[cfg(feature = "version-5-0")]
953 const LE_SET_PHY_COMMAND = 35, 1 << 6;
954 #[cfg(feature = "version-5-0")]
956 const LE_ENHANCED_RECEIVER_TEST_COMMAND = 35, 1 << 7;
957 #[cfg(feature = "version-5-0")]
959 const LE_ENHANCED_TRANSMITTER_TEST_COMMAND = 36, 1 << 0;
960 #[cfg(feature = "version-5-0")]
962 const LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND = 36, 1 << 1;
963 #[cfg(feature = "version-5-0")]
965 const LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND = 36, 1 << 2;
966 #[cfg(feature = "version-5-0")]
968 const LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND = 36, 1 << 3;
969 #[cfg(feature = "version-5-0")]
971 const LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND = 36, 1 << 4;
972 #[cfg(feature = "version-5-0")]
974 const LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND = 36, 1 << 5;
975 #[cfg(feature = "version-5-0")]
977 const LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND = 36, 1 << 6;
978 #[cfg(feature = "version-5-0")]
980 const LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND = 36, 1 << 7;
981 #[cfg(feature = "version-5-0")]
983 const LE_REMOVE_ADVERTISING_SET_COMMAND = 37, 1 << 0;
984 #[cfg(feature = "version-5-0")]
986 const LE_CLEAR_ADVERTISING_SETS_COMMAND = 37, 1 << 1;
987 #[cfg(feature = "version-5-0")]
989 const LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND = 37, 1 << 2;
990 #[cfg(feature = "version-5-0")]
992 const LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND = 37, 1 << 3;
993 #[cfg(feature = "version-5-0")]
995 const LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND = 37, 1 << 4;
996 #[cfg(feature = "version-5-0")]
998 const LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND = 37, 1 << 5;
999 #[cfg(feature = "version-5-0")]
1001 const LE_SET_EXTENDED_SCAN_ENABLE_COMMAND = 37, 1 << 6;
1002 #[cfg(feature = "version-5-0")]
1004 const LE_EXTENDED_CREATE_CONNECTION_COMMAND = 37, 1 << 7;
1005 #[cfg(feature = "version-5-0")]
1007 const LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND = 38, 1 << 0;
1008 #[cfg(feature = "version-5-0")]
1010 const LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND = 38, 1 << 1;
1011 #[cfg(feature = "version-5-0")]
1013 const LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND = 38, 1 << 2;
1014 #[cfg(feature = "version-5-0")]
1016 const LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND = 38, 1 << 3;
1017 #[cfg(feature = "version-5-0")]
1019 const LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND = 38, 1 << 4;
1020 #[cfg(feature = "version-5-0")]
1022 const LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND = 38, 1 << 5;
1023 #[cfg(feature = "version-5-0")]
1025 const LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND = 38, 1 << 6;
1026 #[cfg(feature = "version-5-0")]
1028 const LE_READ_TRANSMIT_POWER_COMMAND = 38, 1 << 7;
1029 #[cfg(feature = "version-5-0")]
1031 const LE_READ_RF_PATH_COMPENSATION_COMMAND = 39, 1 << 0;
1032 #[cfg(feature = "version-5-0")]
1034 const LE_WRITE_RF_PATH_COMPENSATION_COMMAND = 39, 1 << 1;
1035 #[cfg(feature = "version-5-0")]
1037 const LE_SET_PRIVACY_MODE = 39, 1 << 2;
1038}
1039
1040impl Debug for CommandFlags {
1041 fn fmt(&self, f: &mut Formatter) -> FmtResult {
1042 writeln!(f, "{:?}", &self.0[..16])?;
1043 writeln!(f, "{:?}", &self.0[16..32])?;
1044 writeln!(f, "{:?}", &self.0[32..39])
1045 }
1046}
1047
1048impl<'a> TryFrom<&'a [u8]> for CommandFlags {
1049 type Error = crate::event::Error<crate::event::NeverError>;
1050 fn try_from(value: &[u8]) -> Result<CommandFlags, Self::Error> {
1051 require_len!(value, COMMAND_FLAGS_SIZE);
1052
1053 CommandFlags::from_bits(value).ok_or(crate::event::Error::BadCommandFlag)
1054 }
1055}
1056
1057fn to_supported_commands<VE, VS>(
1058 bytes: &[u8],
1059) -> Result<LocalSupportedCommands<VS>, crate::event::Error<VE>>
1060where
1061 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1062{
1063 require_len!(bytes, 1 + COMMAND_FLAGS_SIZE);
1064 Ok(LocalSupportedCommands {
1065 status: bytes[0].try_into().map_err(super::rewrap_bad_status)?,
1066 supported_commands: bytes[1..=COMMAND_FLAGS_SIZE]
1067 .try_into()
1068 .map_err(|e| match e {
1069 crate::event::Error::BadLength(actual, expected) => {
1070 crate::event::Error::BadLength(actual, expected)
1071 }
1072 crate::event::Error::BadCommandFlag => crate::event::Error::BadCommandFlag,
1073 _ => unreachable!(),
1074 })?,
1075 })
1076}
1077
1078#[derive(Copy, Clone, Debug)]
1081pub struct LocalSupportedFeatures<VS> {
1082 pub status: Status<VS>,
1084
1085 pub supported_features: LmpFeatures,
1087}
1088
1089bitflags! {
1090 pub struct LmpFeatures : u64 {
1092 const THREE_SLOT_PACKETS = 1 << 0;
1094 const FIVE_SLOT_PACKETS = 1 << 1;
1096 const ENCRYPTION = 1 << 2;
1098 const SLOT_OFFSET = 1 << 3;
1100 const TIMING_ACCURACY = 1 << 4;
1102 const ROLE_SWITCH = 1 << 5;
1104 const HOLD_MODE = 1 << 6;
1106 const SNIFF_MODE = 1 << 7;
1108 const POWER_CONTROL_REQUESTS = 1 << 9;
1110 const CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR = 1 << 10;
1112 const SCO_LINK = 1 << 11;
1114 const HV2_PACKETS = 1 << 12;
1116 const HV3_PACKETS = 1 << 13;
1118 const MU_LAW_LOG_SYNCHRONOUS_DATA = 1 << 14;
1120 const A_LAW_LOG_SYNCHRONOUS_DATA = 1 << 15;
1122 const CVSD_SYNCHRONOUS_DATA = 1 << 16;
1124 const PAGING_PARAMETER_NEGOTIATION = 1 << 17;
1126 const POWER_CONTROL = 1 << 18;
1128 const TRANSPARENT_SYNCHRONOUS_DATA = 1 << 19;
1130 const FLOW_CONTROL_LAG_LSB = 1 << 20;
1132 const FLOW_CONTROL_LAG_MID = 1 << 21;
1134 const FLOW_CONTROL_LAG_MSB = 1 << 22;
1136 const BROADCAST_ENCRYPTION = 1 << 23;
1138 const ENHANCED_DATA_RATE_ACL_2_MB_PER_S_MODE = 1 << 25;
1140 const ENHANCED_DATA_RATE_ACL_3_MB_PER_S_MODE = 1 << 26;
1142 const ENHANCED_INQUIRY_SCAN = 1 << 27;
1144 const INTERLACED_INQUIRY_SCAN = 1 << 28;
1146 const INTERLACED_PAGE_SCAN = 1 << 29;
1148 const RSSI_WITH_INQUIRY_RESULTS = 1 << 30;
1150 const EXTENDED_SCO_LINK_EV3_PACKETS = 1 << 31;
1152 const EV4_PACKETS = 1 << 32;
1154 const EV5_PACKETS = 1 << 33;
1156 const AFH_CAPABLE_PERIPHERAL = 1 << 35;
1158 const AFH_CLASSIFICATION_PERIPHERAL = 1 << 36;
1160 const BR_EDR_NOT_SUPPORTED = 1 << 37;
1162 const LE_SUPPORTED_BY_CONTROLLER = 1 << 38;
1164 const THREE_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 1 << 39;
1166 const FIVE_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 1 << 40;
1168 const SNIFF_SUBRATING = 1 << 41;
1170 const PAUSE_ENCRYPTION = 1 << 42;
1172 const AFH_CAPABLE_CENTRAL_DEVICE = 1 << 43;
1174 const AFH_CLASSIFICATION_CENTRAL_DEVICE = 1 << 44;
1176 const ENHANCED_DATA_RATE_ESCO_2_MB_PER_S_MODE = 1 << 45;
1178 const ENHANCED_DATA_RATE_ESCO_3_MB_PER_S_MODE = 1 << 46;
1180 const THREE_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = 1 << 47;
1182 const EXTENDED_INQUIRY_RESPONSE = 1 << 48;
1184 const SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE = 1 << 49;
1186 const SECURE_SIMPLE_PAIRING = 1 << 51;
1188 const ENCAPSULATED_PDU = 1 << 52;
1190 const ERRONEOUS_DATA_REPORTING = 1 << 53;
1192 const NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = 1 << 54;
1194 const LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 1 << 56;
1196 const INQUIRY_TX_POWER_LEVEL = 1 << 57;
1198 const ENHANCED_POWER_CONTROL = 1 << 58;
1200 const EXTENDED_FEATURES = 1 << 63;
1202 }
1203}
1204
1205fn to_supported_features<VE, VS>(
1206 bytes: &[u8],
1207) -> Result<LocalSupportedFeatures<VS>, crate::event::Error<VE>>
1208where
1209 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1210{
1211 require_len!(bytes, 9);
1212 Ok(LocalSupportedFeatures {
1213 status: to_status(bytes)?,
1214 supported_features: LmpFeatures::from_bits_truncate(LittleEndian::read_u64(&bytes[1..])),
1215 })
1216}
1217
1218#[derive(Copy, Clone, Debug)]
1220pub struct ReadBdAddr<VS> {
1221 pub status: Status<VS>,
1223
1224 pub bd_addr: crate::BdAddr,
1226}
1227
1228fn to_bd_addr<VE, VS>(bytes: &[u8]) -> Result<ReadBdAddr<VS>, crate::event::Error<VE>>
1229where
1230 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1231{
1232 require_len!(bytes, 7);
1233 let mut bd_addr = crate::BdAddr([0; 6]);
1234 bd_addr.0.copy_from_slice(&bytes[1..]);
1235 Ok(ReadBdAddr {
1236 status: to_status(bytes)?,
1237 bd_addr,
1238 })
1239}
1240
1241#[derive(Copy, Clone, Debug)]
1243pub struct ReadRssi<VS> {
1244 pub status: Status<VS>,
1246
1247 pub conn_handle: ConnectionHandle,
1252
1253 pub rssi: i8,
1264}
1265
1266fn to_read_rssi<VE, VS>(bytes: &[u8]) -> Result<ReadRssi<VS>, crate::event::Error<VE>>
1267where
1268 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1269{
1270 require_len!(bytes, 4);
1271 Ok(ReadRssi {
1272 status: to_status(bytes)?,
1273 conn_handle: ConnectionHandle(LittleEndian::read_u16(&bytes[1..])),
1274 rssi: unsafe { mem::transmute::<u8, i8>(bytes[3]) },
1275 })
1276}
1277
1278#[derive(Copy, Clone, Debug)]
1280pub struct LeReadBufferSize<VS> {
1281 pub status: Status<VS>,
1283
1284 pub data_packet_length: u16,
1294
1295 pub data_packet_count: u8,
1302}
1303
1304fn to_le_read_buffer_status<VE, VS>(
1305 bytes: &[u8],
1306) -> Result<LeReadBufferSize<VS>, crate::event::Error<VE>>
1307where
1308 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1309{
1310 require_len!(bytes, 4);
1311 Ok(LeReadBufferSize {
1312 status: to_status(bytes)?,
1313 data_packet_length: LittleEndian::read_u16(&bytes[1..]),
1314 data_packet_count: bytes[3],
1315 })
1316}
1317
1318#[derive(Copy, Clone, Debug)]
1321pub struct LeSupportedFeatures<VS> {
1322 pub status: Status<VS>,
1324
1325 pub supported_features: LeFeatures,
1327}
1328
1329bitflags! {
1330 pub struct LeFeatures : u64 {
1335 const ENCRYPTION = 1 << 0;
1337 const CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << 1;
1339 const EXTENDED_REJECT_INDICATION = 1 << 2;
1341 const PERIPHERALINITIATED_FEATURES_EXCHANGE = 1 << 3;
1343 const PING = 1 << 4;
1345 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
1347 const DATA_PACKET_LENGTH_EXTENSION = 1 << 5;
1348 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
1350 const LL_PRIVACY = 1 << 6;
1351 #[cfg(any(feature = "version-4-2", feature = "version-5-0"))]
1353 const EXTENDED_SCANNER_FILTER_POLICIES = 1 << 7;
1354 #[cfg(feature = "version-5-0")]
1356 const PHY_2M = 1 << 8;
1357 #[cfg(feature = "version-5-0")]
1359 const STABLE_MODULATION_INDEX_TX = 1 << 9;
1360 #[cfg(feature = "version-5-0")]
1362 const STABLE_MODULATION_INDEX_RX = 1 << 10;
1363 #[cfg(feature = "version-5-0")]
1365 const CODED_PHY = 1 << 11;
1366 #[cfg(feature = "version-5-0")]
1368 const EXTENDED_ADVERTISING = 1 << 12;
1369 #[cfg(feature = "version-5-0")]
1371 const PERIODIC_ADVERTISING = 1 << 13;
1372 #[cfg(feature = "version-5-0")]
1374 const CHANNEL_SELECTION_ALGORITHM_2 = 1 << 14;
1375 #[cfg(feature = "version-5-0")]
1377 const POWER_CLASS_1 = 1 << 15;
1378 #[cfg(feature = "version-5-0")]
1380 const MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 1 << 16;
1381 }
1382}
1383
1384fn to_le_local_supported_features<VE, VS>(
1385 bytes: &[u8],
1386) -> Result<LeSupportedFeatures<VS>, crate::event::Error<VE>>
1387where
1388 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1389{
1390 require_len!(bytes, 9);
1391 Ok(LeSupportedFeatures {
1392 status: to_status(bytes)?,
1393 supported_features: LeFeatures::from_bits_truncate(LittleEndian::read_u64(&bytes[1..])),
1394 })
1395}
1396
1397#[derive(Copy, Clone, Debug)]
1400pub struct LeAdvertisingChannelTxPower<VS> {
1401 pub status: Status<VS>,
1403 pub power: i8,
1408}
1409
1410fn to_le_advertising_channel_tx_power<VE, VS>(
1411 bytes: &[u8],
1412) -> Result<LeAdvertisingChannelTxPower<VS>, crate::event::Error<VE>>
1413where
1414 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1415{
1416 require_len!(bytes, 2);
1417 Ok(LeAdvertisingChannelTxPower {
1418 status: to_status(bytes)?,
1419 power: unsafe { mem::transmute::<u8, i8>(bytes[1]) },
1420 })
1421}
1422
1423#[cfg(not(feature = "version-5-0"))]
1424fn to_le_set_advertise_enable<V>(status: Status<V::Status>) -> ReturnParameters<V>
1425where
1426 V: super::VendorEvent,
1427{
1428 ReturnParameters::LeSetAdvertiseEnable(status)
1429}
1430
1431#[cfg(feature = "version-5-0")]
1432fn to_le_set_advertise_enable<V>(status: Status<V::Status>) -> ReturnParameters<V>
1433where
1434 V: super::VendorEvent,
1435{
1436 ReturnParameters::LeSetAdvertisingEnable(status)
1437}
1438
1439#[derive(Copy, Clone, Debug)]
1441pub struct ChannelMapParameters<VS> {
1442 pub status: Status<VS>,
1444
1445 pub conn_handle: ConnectionHandle,
1447
1448 pub channel_map: crate::ChannelClassification,
1450}
1451
1452fn to_le_channel_map_parameters<VE, VS>(
1453 bytes: &[u8],
1454) -> Result<ChannelMapParameters<VS>, crate::event::Error<VE>>
1455where
1456 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1457{
1458 require_len!(bytes, 8);
1459
1460 let mut channel_bits = [0; 5];
1461 channel_bits.copy_from_slice(&bytes[3..8]);
1462 let channel_bits = channel_bits;
1463 Ok(ChannelMapParameters {
1464 status: to_status(&bytes[0..])?,
1465 conn_handle: ConnectionHandle(LittleEndian::read_u16(&bytes[1..])),
1466 channel_map: crate::ChannelClassification::from_bits(&bytes[3..])
1467 .ok_or_else(|| crate::event::Error::InvalidChannelMap(channel_bits))?,
1468 })
1469}
1470
1471#[derive(Copy, Clone, Debug)]
1473pub struct EncryptedReturnParameters<VS> {
1474 pub status: Status<VS>,
1476
1477 pub encrypted_data: EncryptedBlock,
1482}
1483
1484#[derive(Copy, Clone)]
1488pub struct EncryptedBlock(pub [u8; 16]);
1489
1490impl Debug for EncryptedBlock {
1491 fn fmt(&self, f: &mut Formatter) -> FmtResult {
1492 writeln!(f, "AES-128 Encrypted Data ({:X?})", &self.0)
1493 }
1494}
1495
1496fn to_le_encrypted_data<VE, VS>(
1497 bytes: &[u8],
1498) -> Result<EncryptedReturnParameters<VS>, crate::event::Error<VE>>
1499where
1500 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1501{
1502 require_len!(bytes, 17);
1503
1504 let mut block = [0; 16];
1505 block.copy_from_slice(&bytes[1..]);
1506 Ok(EncryptedReturnParameters {
1507 status: to_status(&bytes)?,
1508 encrypted_data: EncryptedBlock(block),
1509 })
1510}
1511
1512#[derive(Copy, Clone, Debug)]
1514pub struct LeRandom<VS> {
1515 pub status: Status<VS>,
1517
1518 pub random_number: u64,
1520}
1521
1522fn to_random_number<VE, VS>(bytes: &[u8]) -> Result<LeRandom<VS>, crate::event::Error<VE>>
1523where
1524 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1525{
1526 require_len!(bytes, 9);
1527
1528 Ok(LeRandom {
1529 status: to_status(&bytes)?,
1530 random_number: LittleEndian::read_u64(&bytes[1..]),
1531 })
1532}
1533
1534#[derive(Copy, Clone, Debug)]
1537pub struct LeLongTermRequestReply<VS> {
1538 pub status: Status<VS>,
1540
1541 pub conn_handle: ConnectionHandle,
1543}
1544
1545fn to_le_ltk_request_reply<VE, VS>(
1546 bytes: &[u8],
1547) -> Result<LeLongTermRequestReply<VS>, crate::event::Error<VE>>
1548where
1549 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1550{
1551 require_len!(bytes, 3);
1552
1553 Ok(LeLongTermRequestReply {
1554 status: to_status(&bytes)?,
1555 conn_handle: ConnectionHandle(LittleEndian::read_u16(&bytes[1..])),
1556 })
1557}
1558
1559#[derive(Copy, Clone, Debug)]
1562pub struct LeReadSupportedStates<VS> {
1563 pub status: Status<VS>,
1565
1566 pub supported_states: LeStates,
1569}
1570
1571bitflags! {
1572 pub struct LeStates : u64 {
1575 const NON_CONNECTABLE_ADVERTISING = 1 << 0;
1577 const SCANNABLE_ADVERTISING = 1 << 1;
1579 const CONNECTABLE_ADVERTISING = 1 << 2;
1581 const DIRECTED_ADVERTISING_HIGH_DUTY_CYCLE = 1 << 3;
1583 const PASSIVE_SCANNING = 1 << 4;
1585 const ACTIVE_SCANNING = 1 << 5;
1587 const INITIATING = 1 << 6;
1589 const PERIPHERAL_CONNECTION = 1 << 7;
1591 const NONCONN_AD_AND_PASS_SCAN = 1 << 8;
1593 const SCAN_AD_AND_PASS_SCAN = 1 << 9;
1595 const CONN_AD_AND_PASS_SCAN = 1 << 10;
1597 const DIR_AD_HDC_AND_PASS_SCAN = 1 << 11;
1599 const NONCONN_AD_AND_ACT_SCAN = 1 << 12;
1601 const SCAN_AD_AND_ACT_SCAN = 1 << 13;
1603 const CONN_AD_AND_ACT_SCAN = 1 << 14;
1605 const DIR_AD_HDC_AND_ACT_SCAN = 1 << 15;
1607 const NONCONN_AD_AND_INITIATING = 1 << 16;
1609 const SCAN_AD_AND_INITIATING = 1 << 17;
1611 const NONCONN_AD_AND_CENTRAL_CONN = 1 << 18;
1613 const SCAN_AD_AND_CENTRAL_CONN = 1 << 19;
1615 const NONCONN_AD_AND_PERIPH_CONN = 1 << 20;
1617 const SCAN_AD_AND_PERIPH_CONN = 1 << 21;
1619 const PASS_SCAN_AND_INITIATING = 1 << 22;
1621 const ACT_SCAN_AND_INITIATING = 1 << 23;
1623 const PASS_SCAN_AND_CENTRAL_CONN = 1 << 24;
1625 const ACT_SCAN_AND_CENTRAL_CONN = 1 << 25;
1627 const PASS_SCAN_AND_PERIPH_CONN = 1 << 26;
1629 const ACT_SCAN_AND_PERIPH_CONN = 1 << 27;
1631 const INITIATING_AND_CENTRAL_CONN = 1 << 28;
1633 const DIRECTED_ADVERTISING_LOW_DUTY_CYCLE = 1 << 29;
1635 const DIR_AD_LDC_AND_PASS_SCAN = 1 << 30;
1637 const DIR_AD_LDC_AND_ACT_SCAN = 1 << 31;
1639 const CONN_AD_AND_INITIATING = 1 << 32;
1641 const DIR_AD_HDC_AND_INITIATING = 1 << 33;
1643 const DIR_AD_LDC_AND_INITIATING = 1 << 34;
1645 const CONN_AD_AND_CENTRAL_CONN = 1 << 35;
1647 const DIR_AD_HDC_AND_CENTRAL_CONN = 1 << 36;
1649 const DIR_AD_LDC_AND_CENTRAL_CONN = 1 << 37;
1651 const CONN_AD_AND_PERIPH_CONN = 1 << 38;
1653 const DIR_AD_HDC_AND_PERIPH_CONN = 1 << 39;
1655 const DIR_AD_LDC_AND_PERIPH_CONN = 1 << 40;
1657 const INITIATING_AND_PERIPH_CONN = 1 << 41;
1659 }
1660}
1661
1662fn to_le_read_states<VE, VS>(
1663 bytes: &[u8],
1664) -> Result<LeReadSupportedStates<VS>, crate::event::Error<VE>>
1665where
1666 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1667{
1668 require_len!(bytes, 9);
1669
1670 let bitfield = LittleEndian::read_u64(&bytes[1..]);
1671 Ok(LeReadSupportedStates {
1672 status: to_status(bytes)?,
1673 supported_states: LeStates::from_bits(bitfield)
1674 .ok_or_else(|| crate::event::Error::InvalidLeStates(bitfield))?,
1675 })
1676}
1677
1678#[derive(Copy, Clone, Debug)]
1680pub struct LeTestEnd<VS> {
1681 pub status: Status<VS>,
1683
1684 pub number_of_packets: usize,
1687}
1688
1689fn to_le_test_end<VE, VS>(bytes: &[u8]) -> Result<LeTestEnd<VS>, crate::event::Error<VE>>
1690where
1691 Status<VS>: TryFrom<u8, Error = BadStatusError>,
1692{
1693 require_len!(bytes, 3);
1694
1695 Ok(LeTestEnd {
1696 status: to_status(bytes)?,
1697 number_of_packets: LittleEndian::read_u16(&bytes[1..]) as usize,
1698 })
1699}