stm32wb_hci/vendor/event/
mod.rs

1//! Vendor-specific events for BlueNRG controllers.
2//!
3//! The BlueNRG implementation defines several additional events that are packaged as
4//! vendor-specific events by the Bluetooth HCI. This module defines those events and functions to
5//! deserialize buffers into them.
6
7pub mod command;
8
9use byteorder::{ByteOrder, LittleEndian};
10use core::cmp::PartialEq;
11use core::convert::{TryFrom, TryInto};
12use core::fmt::{Debug, Formatter, Result as FmtResult};
13use core::mem;
14use core::time::Duration;
15
16use crate::host::PeerAddrType;
17pub use crate::types::{ConnectionInterval, ConnectionIntervalError};
18use crate::vendor::command::l2cap::L2CapCocReconfig;
19pub use crate::{BdAddr, BdAddrType, ConnectionHandle};
20
21/// Vendor-specific events for the STM32WB5x radio coprocessor.
22#[allow(clippy::large_enum_variant)]
23#[derive(Clone, Copy, Debug)]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25pub enum VendorEvent {
26    /// When the radio coprocessor firmware is started normally, it gives this event to the user to
27    /// indicate the system has started.
28    CoprocessorReady(FirmwareKind),
29
30    /// If the host fails to read events from the controller quickly enough, the controller will
31    /// generate this event. This event is never lost; it is inserted as soon as space is available
32    /// in the Tx queue.
33    EventsLost(EventFlags),
34
35    /// The fault data event is automatically sent after the
36    /// [HalInitialized](VendorEvent::HalInitialized) event in case of
37    /// [NMI or Hard fault](ResetReason::Crash).
38    // CrashReport(FaultData),
39
40    /// This event is generated by the controller when the limited discoverable mode ends due to
41    /// timeout (180 seconds).
42    GapLimitedDiscoverableTimeout,
43
44    /// This event is generated when the pairing process has completed successfully or a pairing
45    /// procedure timeout has occurred or the pairing has failed.  This is to notify the application
46    /// that we have paired with a remote device so that it can take further actions or to notify
47    /// that a timeout has occurred so that the upper layer can decide to disconnect the link.
48    GapPairingComplete(GapPairingComplete),
49
50    /// This event is generated by the Security manager to the application when a pass key is
51    /// required for pairing.  When this event is received, the application has to respond with the
52    /// `gap_pass_key_response` command.
53    GapPassKeyRequest(ConnectionHandle),
54
55    /// This event is generated by the Security manager to the application when the application has
56    /// set that authorization is required for reading/writing of attributes. This event will be
57    /// generated as soon as the pairing is complete. When this event is received,
58    /// `gap_authorization_response` command should be used by the application.
59    GapAuthorizationRequest(ConnectionHandle),
60
61    /// This event is generated when the peripheral security request is successfully sent to the
62    /// central device.
63    GapPeripheralSecurityInitiated,
64
65    /// This event is generated on the peripheral when a `gap_peripheral_security_request` is called
66    /// to reestablish the bond with the central device but the central device has lost the
67    /// bond. When this event is received, the upper layer has to issue the command
68    /// `gap_allow_rebond` in order to allow the peripheral to continue the pairing process with the
69    /// central device. On the central device, this event is raised when `gap_send_pairing_request`
70    /// is called to reestablish a bond with a peripheral but the peripheral has lost the bond. In
71    /// order to create a new bond the central device has to launch `gap_send_pairing_request` with
72    /// `force_rebond` set to `true`.
73    GapBondLost,
74
75    /// The event is given by the GAP layer to the upper layers when a device is discovered during
76    /// scanning as a consequence of one of the GAP procedures started by the upper layers.
77    GapDeviceFound(GapDeviceFound),
78
79    /// This event is sent by the GAP to the upper layers when a procedure previously started has
80    /// been terminated by the upper layer or has completed for any other reason
81    GapProcedureComplete(GapProcedureComplete),
82
83    /// This event is sent only by a privacy enabled peripheral. with a non-empty bonded device list
84    ///  The event is sent to the application when the peripheral is unsuccessful in resolving
85    /// the resolvable address of the peer device after connecting to it.
86    GapAddressNotResolved(ConnectionHandle),
87
88    /// This event is sent only during SC Pairing, when Numeric Comparison
89    /// Association model is selected, in order to show the Numeric Value generated,
90    /// and to ask for Confirmation to the User. When this event is received, the
91    /// application has to respond with the
92    /// [numeric_comparison_value_confirm_yes_no](super::command::gap::GapCommands::numeric_comparison_value_confirm_yes_no)
93    /// command.
94    GapNumericComparisonValue(GapNumericComparisonValue),
95
96    /// This event is sent only during SC Pairing, when Keypress Notifications are
97    /// supported, in order to show the input type signaled by the peer device,
98    /// having Keyboard only I/O capabilities. When this event is received, no
99    /// action is required to the User.
100    GapKeypressNotification(GapKeypressNotification),
101
102    /// This event is generated when the central device responds to the L2CAP connection update
103    /// request packet. For more info see
104    /// [ConnectionParameterUpdateResponse](crate::vendor::command::l2cap::ConnectionParameterUpdateResponse)
105    /// and CommandReject in Bluetooth Core v4.0 spec.
106    L2CapConnectionUpdateResponse(L2CapConnectionUpdateResponse),
107
108    /// This event is generated when the central device does not respond to the connection update
109    /// request within 30 seconds.
110    L2CapProcedureTimeout(ConnectionHandle),
111
112    /// The event is given by the L2CAP layer when a connection update request is received from the
113    /// peripheral. The application has to respond by calling
114    /// [l2cap_connection_parameter_update_response](crate::vendor::command::l2cap::L2capCommands::connection_parameter_update_response).
115    L2CapConnectionUpdateRequest(L2CapConnectionUpdateRequest),
116
117    /// This event is generated upon receipt of a valid Command Reject packet (e.g.
118    /// when the Central responds to the Connection Update Request packet with a
119    /// Command Reject packet).
120    L2CapCommandReject(L2CapCommandReject),
121
122    /// This event is generated when receiving a valid Credit Based Connection Request packet.
123    ///
124    /// See Bluetooth spec. v.5.4 [Vol 3, Part A].
125    L2CapCocConnect(L2CapCocConnect),
126
127    /// This event is generated when receiving a valid Credit Based Connection Response packet.
128    ///
129    /// See Bluetooth spec. v.5.4 [Vol 3, Part A].
130    L2CapCocConnectConfirm(L2CapCocConnectConfirm),
131
132    /// This event is generated when receiving a valid Credit Based Reconfigure Request packet.
133    ///
134    /// See Bluetooth spec. v.5.4 [Vol 3, Part A].
135    L2CapCocReconfig(L2CapCocReconfig),
136
137    /// This event is generated when receiving a valid Credit Based Reconfigure Response packet.
138    ///
139    /// See Bluetooth spec. v.5.4 [Vol 3, Part A].
140    L2CapCocReconfigConfirm(L2CapCocReconfigConfirm),
141
142    /// This event is generated when a connection-oriented channel is disconnected following an
143    /// L2CAP channel termination procedure.
144    ///
145    /// Includes the channel index of the connection oriented channel for which the primitive applies
146    ///
147    /// See Bluetooth spec. v.5.4 [Vol 3, Part A].
148    L2CapCocDisconnect(u8),
149
150    /// This event is generated when receiving a valid Flow Control Credit signaling packet.
151    ///
152    /// See Bluetooth spec. v.5.4 [Vol 3, Part A].
153    L2CapCocFlowControl(L2CapCocFlowControl),
154
155    /// This event is generated when receiving a valid K-frame packet on a connection-oriented channel
156    ///
157    /// See Bluetooth spec. v.5.4 [Vol 3, Part A].
158    ///
159    /// # Note:
160    /// For the first K-frame of the SDU, the information data contains the L2CAP SDU length coded in
161    /// two octets followed by the K-frame information payload. For the next K-frames of the SDU, the
162    /// information data only contains the K-frame information payload.
163    L2CapCocRxData(L2CapCocRxData),
164
165    /// Each time the [L2CAO COC Tx Data](crate::vendor::command::l2cap::L2capCommands::coc_tx_data) command
166    /// raises the error code [Insufficient Resources](VendorStatus::InsufficientResources) (0x64), this event
167    /// is generated as soon as there is a free buffer available for sending K-frames.
168    L2CapCocTxPoolAvailable,
169
170    /// This event is generated to the application by the ATT server when a client modifies any
171    /// attribute on the server, as consequence of one of the following ATT procedures:
172    /// - write without response
173    /// - signed write without response
174    /// - write characteristic value
175    /// - write long characteristic value
176    /// - reliable write
177    GattAttributeModified(GattAttributeModified),
178
179    /// This event is generated when a ATT client procedure completes either with error or
180    /// successfully.
181    GattProcedureTimeout(ConnectionHandle),
182
183    /// This event is generated in response to an Exchange MTU request.
184    AttExchangeMtuResponse(AttExchangeMtuResponse),
185
186    /// This event is generated in response to a Find Information Request. See Find Information
187    /// Response in Bluetooth Core v4.0 spec.
188    AttFindInformationResponse(AttFindInformationResponse),
189
190    /// This event is generated in response to a Find By Type Value Request.
191    AttFindByTypeValueResponse(AttFindByTypeValueResponse),
192
193    /// This event is generated in response to a Read by Type Request.
194    AttReadByTypeResponse(AttReadByTypeResponse),
195
196    /// This event is generated in response to a Read Request.
197    AttReadResponse(AttReadResponse),
198
199    /// This event is generated in response to a Read Blob Request. The value in the response is the
200    /// partial value starting from the offset in the request. See the Bluetooth Core v4.1 spec, Vol
201    /// 3, section 3.4.4.5 and 3.4.4.6.
202    AttReadBlobResponse(AttReadResponse),
203
204    /// This event is generated in response to a Read Multiple Request. The value in the response is
205    /// the set of values requested from the request. See the Bluetooth Core v4.1 spec, Vol 3,
206    /// section 3.4.4.7 and 3.4.4.8.
207    AttReadMultipleResponse(AttReadResponse),
208
209    /// This event is generated in response to a Read By Group Type Request. See the Bluetooth Core
210    /// v4.1 spec, Vol 3, section 3.4.4.9 and 3.4.4.10.
211    AttReadByGroupTypeResponse(AttReadByGroupTypeResponse),
212
213    /// This event is generated in response to a Prepare Write Request. See the Bluetooth Core v4.1
214    /// spec, Vol 3, Part F, section 3.4.6.1 and 3.4.6.2
215    AttPrepareWriteResponse(AttPrepareWriteResponse),
216
217    /// This event is generated in response to an Execute Write Request. See the Bluetooth Core v4.1
218    /// spec, Vol 3, Part F, section 3.4.6.3 and 3.4.6.4
219    AttExecuteWriteResponse(ConnectionHandle),
220
221    /// This event is generated when an indication is received from the server.
222    GattIndication(AttributeValue),
223
224    /// This event is generated when an notification is received from the server.
225    GattNotification(AttributeValue),
226
227    /// This event is generated when a GATT client procedure completes either with error or
228    /// successfully.
229    GattProcedureComplete(GattProcedureComplete),
230
231    /// This event is generated when an Error Response is received from the server. The error
232    /// response can be given by the server at the end of one of the GATT discovery procedures. This
233    /// does not mean that the procedure ended with an error, but this error event is part of the
234    /// procedure itself.
235    AttErrorResponse(AttErrorResponse),
236
237    /// This event can be generated during a "Discover Characteristics by UUID" procedure or a "Read
238    /// using Characteristic UUID" procedure. The attribute value will be a service declaration as
239    /// defined in Bluetooth Core v4.0 spec, Vol 3, Part G, section 3.3.1), when a "Discover
240    /// Characteristics By UUID" has been started. It will be the value of the Characteristic if a
241    /// "Read using Characteristic UUID" has been performed.
242    ///
243    /// See the Bluetooth Core v4.1 spec, Vol 3, Part G, section 4.6.2 (discover characteristics by
244    /// UUID), and section 4.8.2 (read using characteristic using UUID).
245    GattDiscoverOrReadCharacteristicByUuidResponse(AttributeValue),
246
247    /// This event is given to the application when a write request, write command or signed write
248    /// command is received by the server from the client. This event will be given to the
249    /// application only if the event bit for this event generation is set when the characteristic
250    /// was added. When this event is received, the application has to check whether the value being
251    /// requested for write is allowed to be written and respond with a GATT Write Response. If the
252    /// write is rejected by the application, then the value of the attribute will not be
253    /// modified. In case of a write request, an error response will be sent to the client, with the
254    /// error code as specified by the application. In case of write/signed write commands, no
255    /// response is sent to the client but the attribute is not modified.
256    ///
257    /// See the Bluetooth Core v4.1 spec, Vol 3, Part F, section 3.4.5.
258    AttWritePermitRequest(AttributeValue),
259
260    /// This event is given to the application when a read request or read blob request is received
261    /// by the server from the client. This event will be given to the application only if the event
262    /// bit for this event generation is set when the characteristic was added. On receiving this
263    /// event, the application can update the value of the handle if it desires and when done it has
264    /// to use the [`allow_read`](crate::vendor::command::gatt::GattCommands::allow_read) command to indicate to the
265    /// stack that it can send the response to the client.
266    ///
267    /// See the Bluetooth Core v4.1 spec, Vol 3, Part F, section 3.4.4.
268    AttReadPermitRequest(AttReadPermitRequest),
269
270    /// This event is given to the application when a read multiple request or read by type request
271    /// is received by the server from the client. This event will be given to the application only
272    /// if the event bit for this event generation is set when the characteristic was added.  On
273    /// receiving this event, the application can update the values of the handles if it desires and
274    /// when done it has to send the [`allow_read`](crate::vendor::command::gatt::GattCommands::allow_read) command to
275    /// indicate to the stack that it can send the response to the client.
276    ///
277    /// See the Bluetooth Core v4.1 spec, Vol 3, Part F, section 3.4.4.
278    AttReadMultiplePermitRequest(AttReadMultiplePermitRequest),
279
280    /// This event is raised when the number of available TX buffers is above a threshold TH (TH =
281    /// 2).  The event will be given only if a previous ACI command returned with
282    /// [InsufficientResources](AttError::InsufficientResources).  On receiving this event, the
283    /// application can continue to send notifications by calling `gatt_update_char_value`.
284    GattTxPoolAvailable(GattTxPoolAvailable),
285
286    /// This event is raised on the server when the client confirms the reception of an indication.
287    GattServerConfirmation(ConnectionHandle),
288
289    /// This event is given to the application when a prepare write request is received by the
290    /// server from the client. This event will be given to the application only if the event bit
291    /// for this event generation is set when the characteristic was added.  When this event is
292    /// received, the application has to check whether the value being requested for write is
293    /// allowed to be written and respond with the command `gatt_write_response`.  Based on the
294    /// response from the application, the attribute value will be modified by the stack.  If the
295    /// write is rejected by the application, then the value of the attribute will not be modified
296    /// and an error response will be sent to the client, with the error code as specified by the
297    /// application.
298    AttPrepareWritePermitRequest(AttPrepareWritePermitRequest),
299
300    /// This event informs the application of a change in status of the enhanced ATT bearer handled
301    /// by the special L2CAP channel.
302    GattEattBrearer(GattEattBrearer),
303
304    /// This event is generated when a Multiple Handle Value Notification is received from the server.
305    GattMultiNotification(GattMultiNotification),
306
307    /// This event is generated on server side after the transmission of all notifications linked with
308    /// the a local update of a characteristic value (if it is enabled at the creation of the characteristic
309    /// with [GATT Notify Notification Completion](crate::vendor::command::gatt::CharacteristicEvent) mask
310    /// and if the characteristic supports notifications).
311    GattNotificationComplete(AttributeHandle),
312
313    /// When it is enabled with [set_event_mast](crate::vendor::command::gatt::GattCommands::set_event_mask),
314    /// this event is generated instead of [ATT Read Response](VendorEvent::AttReadResponse) /
315    /// [ATT Read Blob Response](VendorEvent::AttReadBlobResponse) /
316    /// [ATT Read Multiple Response](VendorEvent::AttReadMultipleResponse).
317    ///
318    /// This event should be used instead of those events when `ATT_MTU >
319    /// (BLE_EVT_MAX_PARAM_LEN - 4)` i.e. `ATT_MTU > 251` for `BLE_EVT_MAX_PARAM_LEN`
320    /// default value.
321    GattReadExt(GattReadExt),
322
323    /// When it is enabled with [set_event_mast](crate::vendor::command::gatt::GattCommands::set_event_mask),
324    /// this event is generated instead of [GATT Indication](VendorEvent::GattIndication) event.
325    ///
326    /// This event should be used instead of `ACI_GATT_INDICATION_EVENT` when `ATT_MTU
327    /// > (BLE_EVT_MAX_PARAM_LEN - 4)` i.e. `ATT_MTU > 251` for `BLE_EVT_MAX_PARAM_LEN`
328    /// default value.
329    GattIndicationExt(AttributeValueExt),
330
331    /// When it is enabled with [set_event_mast](crate::vendor::command::gatt::GattCommands::set_event_mask),
332    /// this event is generated instead of [GATT Notification](VendorEvent::GattNotification) event.
333    ///
334    /// This event should be used instead of `ACI_GATT_INDICATION_EVENT` when `ATT_MTU
335    /// > (BLE_EVT_MAX_PARAM_LEN - 4)` i.e. `ATT_MTU > 251` for `BLE_EVT_MAX_PARAM_LEN`
336    /// default value.
337    GattNotificationExt(AttributeValueExt),
338
339    /// This event is generated when teh device completes a radio activity and provide information when
340    /// a new radio activity will be performed.
341    ///
342    /// Information provided includes type of radio activity and absolute time in system ticks when a
343    /// radio acitivity is scheduled, if any. The application can use this information to schedule user
344    /// activities synchronous to selected radio activities. A command
345    /// [Set Radio Activity Mask](crate::vendor::command::hal::HalCommands::set_radio_activity_mask) is
346    /// provided to enable radio activity events of user interests, by default no events are enabled.
347    ///
348    /// The user should take into account that enabling radio events in an application with intense
349    /// radio activity could lead to a fairly high rate of events generated.
350    ///
351    /// Application use cases indlude synchronizing notifications with connection intervals, switching
352    /// antenna at the end of advertising or performing flash erase while radio is idle.
353    HalEndOfRadioActivity(HalEndOfRadioActivity),
354
355    /// This event is reported to the application after a scan request is received and a scan response is
356    /// scheduled to be transmitted.
357    ///
358    /// Note: RSSI in this event is valid only when privacy is not used
359    HalScanReqReport(HalScanReqReport),
360
361    /// This event is generated to report firmware error information
362    HalFirmwareError(HalFirmwareError),
363}
364
365/// Enumeration of vendor-specific status codes.
366#[derive(Copy, Clone, Debug, PartialEq)]
367#[repr(u8)]
368#[cfg_attr(feature = "defmt", derive(defmt::Format))]
369pub enum VendorStatus {
370    /// The command cannot be executed due to the current state of the device.
371    Failed = 0x41,
372    /// Some parameters are invalid.
373    InvalidParameters = 0x42,
374    /// It is not allowed to start the procedure (e.g. another the procedure is ongoing or cannot be
375    /// started on the given handle).
376    NotAllowed = 0x46,
377    /// Unexpected error.
378    Error = 0x47,
379    /// The address was not resolved.
380    AddressNotResolved = 0x48,
381    /// Failed to read from flash.
382    FlashReadFailed = 0x49,
383    /// Failed to write to flash.
384    FlashWriteFailed = 0x4A,
385    /// Failed to erase flash.
386    FlashEraseFailed = 0x4B,
387    /// Invalid CID
388    InvalidCid = 0x50,
389    /// Timer is not valid
390    TimerNotValidLayer = 0x54,
391    /// Insufficient resources to create the timer
392    TimerInsufficientResources = 0x55,
393    /// Connection signature resolving key (CSRK) is not found.
394    CsrkNotFound = 0x5A,
395    /// Identity resolving key (IRK) is not found
396    IrkNotFound = 0x5B,
397    /// The device is not in the security database.
398    DeviceNotFoundInDatabase = 0x5C,
399    /// The security database is full.
400    SecurityDatabaseFull = 0x5D,
401    /// The device is not bonded.
402    DeviceNotBonded = 0x5E,
403    /// The device is blacklisted.
404    DeviceInBlacklist = 0x5F,
405    /// The handle (service, characteristic, or descriptor) is invalid.
406    InvalidHandle = 0x60,
407    /// A parameter is invalid
408    InvalidParameter = 0x61,
409    /// The characteristic handle is not part of the service.
410    OutOfHandle = 0x62,
411    /// The operation is invalid
412    InvalidOperation = 0x63,
413    /// Insufficient resources to complete the operation.
414    InsufficientResources = 0x64,
415    /// The encryption key size is too small
416    InsufficientEncryptionKeySize = 0x65,
417    /// The characteristic already exists.
418    CharacteristicAlreadyExists = 0x66,
419    /// Returned when no valid slots are available (e.g. when there are no available state
420    /// machines).
421    NoValidSlot = 0x82,
422    /// Returned when a scan window shorter than minimum allowed value has been requested
423    /// (i.e. 2ms). The Rust API should prevent this error from occurring.
424    ScanWindowTooShort = 0x83,
425    /// Returned when the maximum requested interval to be allocated is shorter then the current
426    /// anchor period and a there is no submultiple for the current anchor period that is between
427    /// the minimum and the maximum requested intervals.
428    NewIntervalFailed = 0x84,
429    /// Returned when the maximum requested interval to be allocated is greater than the current
430    /// anchor period and there is no multiple of the anchor period that is between the minimum and
431    /// the maximum requested intervals.
432    IntervalTooLarge = 0x85,
433    /// Returned when the current anchor period or a new one can be found that is compatible to the
434    /// interval range requested by the new slot but the maximum available length that can be
435    /// allocated is less than the minimum requested slot length.
436    LengthFailed = 0x86,
437    /// MCU Library timed out.
438    Timeout = 0xFF,
439    /// MCU library: profile already initialized.
440    ProfileAlreadyInitialized = 0xF0,
441    /// MCU library: A parameter was null.
442    NullParameter = 0xF1,
443}
444
445impl TryFrom<u8> for VendorStatus {
446    type Error = crate::BadStatusError;
447
448    fn try_from(value: u8) -> Result<Self, <Self as TryFrom<u8>>::Error> {
449        match value {
450            0x41 => Ok(VendorStatus::Failed),
451            0x42 => Ok(VendorStatus::InvalidParameters),
452            0x46 => Ok(VendorStatus::NotAllowed),
453            0x47 => Ok(VendorStatus::Error),
454            0x48 => Ok(VendorStatus::AddressNotResolved),
455            0x49 => Ok(VendorStatus::FlashReadFailed),
456            0x4A => Ok(VendorStatus::FlashWriteFailed),
457            0x4B => Ok(VendorStatus::FlashEraseFailed),
458            0x50 => Ok(VendorStatus::InvalidCid),
459            0x54 => Ok(VendorStatus::TimerNotValidLayer),
460            0x55 => Ok(VendorStatus::TimerInsufficientResources),
461            0x5A => Ok(VendorStatus::CsrkNotFound),
462            0x5B => Ok(VendorStatus::IrkNotFound),
463            0x5C => Ok(VendorStatus::DeviceNotFoundInDatabase),
464            0x5D => Ok(VendorStatus::SecurityDatabaseFull),
465            0x5E => Ok(VendorStatus::DeviceNotBonded),
466            0x5F => Ok(VendorStatus::DeviceInBlacklist),
467            0x60 => Ok(VendorStatus::InvalidHandle),
468            0x61 => Ok(VendorStatus::InvalidParameter),
469            0x62 => Ok(VendorStatus::OutOfHandle),
470            0x63 => Ok(VendorStatus::InvalidOperation),
471            0x64 => Ok(VendorStatus::InsufficientResources),
472            0x65 => Ok(VendorStatus::InsufficientEncryptionKeySize),
473            0x66 => Ok(VendorStatus::CharacteristicAlreadyExists),
474            0x82 => Ok(VendorStatus::NoValidSlot),
475            0x83 => Ok(VendorStatus::ScanWindowTooShort),
476            0x84 => Ok(VendorStatus::NewIntervalFailed),
477            0x85 => Ok(VendorStatus::IntervalTooLarge),
478            0x86 => Ok(VendorStatus::LengthFailed),
479            0xFF => Ok(VendorStatus::Timeout),
480            0xF0 => Ok(VendorStatus::ProfileAlreadyInitialized),
481            0xF1 => Ok(VendorStatus::NullParameter),
482            _ => Err(crate::BadStatusError::BadValue(value)),
483        }
484    }
485}
486
487impl From<VendorStatus> for u8 {
488    fn from(val: VendorStatus) -> Self {
489        val as u8
490    }
491}
492
493/// Enumeration of potential errors when sending commands or deserializing events.
494#[derive(Clone, Copy, Debug, PartialEq)]
495#[cfg_attr(feature = "defmt", derive(defmt::Format))]
496pub enum VendorError {
497    /// The event is not recognized. Includes the unknown opcode.
498    UnknownEvent(u16),
499
500    /// For the [CoprocessorReady](VendorEvent::CoprocessorReady) event: the kind of firmware
501    /// running on radio coprocessor is not recognized.
502    UnknownFirmwareKind(u8),
503
504    /// For the [GAP Pairing Complete](VendorEvent::GapPairingComplete) event: The status was not
505    /// recognized. Includes the unrecognized byte.
506    BadGapPairingStatus(u8),
507
508    /// For the [GAP Pairing Complete](VendorEvent::GapPairingComplete) event: The error reason
509    /// was not recognized. Includes the unrecognized byte.
510    BadGapPairingErrorReason(u8),
511
512    /// For the [GAP Device Found](VendorEvent::GapDeviceFound) event: the type of event was not
513    /// recognized. Includes the unrecognized byte.
514    BadGapDeviceFoundEvent(u8),
515
516    /// For the [GAP Device Found](VendorEvent::GapDeviceFound) event: the type of BDADDR was not
517    /// recognized. Includes the unrecognized byte.
518    BadGapBdAddrType(u8),
519
520    /// For the [GAP Procedure Complete](VendorEvent::GapProcedureComplete) event: The procedure
521    /// code was not recognized. Includes the unrecognized byte.
522    BadGapProcedure(u8),
523
524    /// For the [GAP Procedure Complete](VendorEvent::GapProcedureComplete) event: The procedure
525    /// status was not recognized. Includes the unrecognized byte.
526    BadGapProcedureStatus(u8),
527
528    /// For any L2CAP event: The event data length did not match the expected length. The first
529    /// field is the required length, and the second is the actual length.
530    BadL2CapDataLength(u8, u8),
531
532    /// For any L2CAP event: The L2CAP length did not match the expected length. The first field is
533    /// the required length, and the second is the actual length.
534    BadL2CapLength(u16, u16),
535
536    /// For any L2CAP response event: The L2CAP command was rejected, but the rejection reason was
537    /// not recognized. Includes the unknown value.
538    BadL2CapRejectionReason(u16),
539
540    /// For the [L2CAP Connection Update Response](VendorEvent::L2CapConnectionUpdateResponse)
541    /// event: The code byte did not indicate either Rejected or Updated. Includes the invalid byte.
542    BadL2CapConnectionResponseCode(u8),
543
544    /// For the [L2CAP Connection Update Response](VendorEvent::L2CapConnectionUpdateResponse)
545    /// event: The command was accepted, but the result was not recognized. It did not indicate the
546    /// parameters were either updated or rejected. Includes the unknown value.
547    BadL2CapConnectionResponseResult(u16),
548
549    /// For the [L2CAP Connection Update Request](VendorEvent::L2CapConnectionUpdateRequest) event:
550    /// The provided connection interval is invalid. Includes the underlying error.
551    BadConnectionInterval(ConnectionIntervalError),
552
553    /// For the [L2CAP Connection Update Request](VendorEvent::L2CapConnectionUpdateRequest) event:
554    /// The provided interval is invalid. Potential errors:
555    /// - Either the minimum or maximum is out of range. The minimum value for either is 7.5 ms, and
556    ///   the maximum is 4 s.
557    /// - The min is greater than the max
558    ///
559    /// See the Bluetooth specification, Vol 3, Part A, Section 4.20. Versions 4.1, 4.2 and 5.0.
560    ///
561    /// Inclues the provided minimum and maximum, respectively.
562    BadL2CapConnectionUpdateRequestInterval(Duration, Duration),
563
564    /// For the [L2CAP Connection Update Request](VendorEvent::L2CapConnectionUpdateRequest) event:
565    /// The provided connection latency is invalid. The maximum value for connection latency is
566    /// defined in terms of the timeout and maximum connection interval.
567    /// - `connIntervalMax = Interval Max`
568    /// - `connSupervisionTimeout = Timeout`
569    /// - `maxConnLatency = min(500, ((connSupervisionTimeout / (2 * connIntervalMax)) - 1))`
570    ///
571    /// See the Bluetooth specification, Vol 3, Part A, Section 4.20. Versions 4.1, 4.2 and 5.0.
572    ///
573    /// Inclues the provided value and maximum allowed value, respectively.
574    BadL2CapConnectionUpdateRequestLatency(u16, u16),
575
576    /// For the [L2CAP Connection Update Request](VendorEvent::L2CapConnectionUpdateRequest) event:
577    /// The provided timeout is invalid. The timeout field shall have a value in the range of 100 ms
578    /// to 32 seconds (inclusive).
579    ///
580    /// See the Bluetooth specification, Vol 3, Part A, Section 4.20. Versions 4.1, 4.2 and 5.0.
581    ///
582    /// Inclues the provided value.
583    BadL2CapConnectionUpdateRequestTimeout(Duration),
584
585    /// For the [ATT Find Information Response](VendorEvent::AttFindInformationResponse) event: The
586    /// format code is invalid. Includes the unrecognized byte.
587    BadAttFindInformationResponseFormat(u8),
588
589    /// For the [ATT Find Information Response](VendorEvent::AttFindInformationResponse) event: The
590    /// format code indicated 16-bit UUIDs, but the packet ends with a partial pair.
591    AttFindInformationResponsePartialPair16,
592
593    /// For the [ATT Find Information Response](VendorEvent::AttFindInformationResponse) event: The
594    /// format code indicated 128-bit UUIDs, but the packet ends with a partial pair.
595    AttFindInformationResponsePartialPair128,
596
597    /// For the [ATT Find by Type Value Response](VendorEvent::AttFindByTypeValueResponse) event:
598    /// The packet ends with a partial attribute pair.
599    AttFindByTypeValuePartial,
600
601    /// For the [ATT Read by Type Response](VendorEvent::AttReadByTypeResponse) event: The packet
602    /// ends with a partial attribute handle-value pair.
603    AttReadByTypeResponsePartial,
604
605    /// For the [ATT Read by Group Type Response](VendorEvent::AttReadByGroupTypeResponse) event:
606    /// The packet ends with a partial attribute data group.
607    AttReadByGroupTypeResponsePartial,
608
609    /// For the [GATT Procedure Complete](VendorEvent::GattProcedureComplete) event: The status
610    /// code was not recognized. Includes the unrecognized byte.
611    BadGattProcedureStatus(u8),
612
613    /// For the [ATT Error Response](VendorEvent::AttErrorResponse) event: The request opcode was
614    /// not recognized. Includes the unrecognized byte.
615    BadAttRequestOpcode(u8),
616
617    /// For the [ATT Error Response](VendorEvent::AttErrorResponse) event: The error code was not
618    /// recognized. Includes the unrecognized byte.
619    BadAttError(u8),
620
621    /// For the [ATT Read Multiple Permit Request](VendorEvent::AttReadMultiplePermitRequest)
622    /// event: The packet ends with a partial attribute handle.
623    AttReadMultiplePermitRequestPartial,
624
625    /// For the [HAL Read Config Data](crate::vendor::command::hal::HalCommands::read_config_data) command complete
626    /// [event](crate::vendor::event::command::VendorReturnParameters::HalReadConfigData): The returned value has a length that
627    /// does not correspond to a requested parameter. Known lengths are 1, 2, 6, or 16. Includes the
628    /// number of bytes returned.
629    BadConfigParameterLength(usize),
630
631    /// For the [HAL Get Link Status](crate::vendor::command::hal::HalCommands::get_link_status) command complete
632    /// [event](crate::vendor::event::command::VendorReturnParameters::HalGetLinkStatus): One of the bytes representing a link
633    /// state does not represent a known link state. Returns the unknown value.
634    UnknownLinkState(u8),
635
636    /// For the [GAP Get Security Level](crate::vendor::command::gap::GapCommands::get_security_level) command complete
637    /// [event](crate::vendor::event::command::VendorReturnParameters::GapGetSecurityLevel): One of the boolean values
638    /// ([`mitm_protection_required`](command::GapSecurityLevel::mitm_protection_required),
639    /// [`bonding_required`](command::GapSecurityLevel::bonding_required), or
640    /// [`out_of_band_data_present`](command::GapSecurityLevel::out_of_band_data_present)) was
641    /// neither 0 nor 1. The unknown value is provided.
642    BadBooleanValue(u8),
643
644    /// For the [GAP Get Security Level](crate::vendor::command::gap::GapCommands::get_security_level) command complete
645    /// [event](crate::vendor::event::command::VendorReturnParameters::GapGetSecurityLevel): the pass key requirement field was
646    /// an invalid value. The unknown byte is provided.
647    BadPassKeyRequirement(u8),
648
649    /// For the [GAP Get Bonded Devices](crate::vendor::command::gap::GapCommands::get_bonded_devices) command complete
650    /// [event](crate::vendor::event::command::VendorReturnParameters::GapGetBondedDevices): the packat was not long enough to
651    /// contain the number of addresses it claimed to contain.
652    PartialBondedDeviceAddress,
653
654    /// For the [GAP Get Bonded Devices](crate::vendor::command::gap::GapCommands::get_bonded_devices) command complete
655    /// [event](crate::vendor::event::command::VendorReturnParameters::GapGetBondedDevices): one of the address type bytes was
656    /// invalid. Includes the invalid byte.
657    BadBdAddrType(u8),
658
659    /// For the [GATT EAT Bearer](crate::vendor::event::VendorEvent::GattEattBrearer) event: The EAB state was not recognized.
660    BadEabState(u8),
661
662    /// For the [HAL End Of Radio Activity](VendorEvent::HalEndOfRadioActivity) event: The Radio Event code was not recognized.
663    BadRadioEvent(u8),
664
665    /// For the [HAL Firmware Error](VendorEvent::HalFirmareError) event: The Radio Event code was not recognized.
666    BadFirmwareError(u8),
667}
668
669macro_rules! require_len {
670    ($left:expr, $right:expr) => {
671        if $left.len() != $right {
672            return Err(crate::event::Error::BadLength($left.len(), $right));
673        }
674    };
675}
676
677macro_rules! require_len_at_least {
678    ($left:expr, $right:expr) => {
679        if $left.len() < $right {
680            return Err(crate::event::Error::BadLength($left.len(), $right));
681        }
682    };
683}
684
685fn first_16<T>(buffer: &[T]) -> &[T] {
686    if buffer.len() < 16 {
687        buffer
688    } else {
689        &buffer[..16]
690    }
691}
692
693impl VendorEvent {
694    pub fn new(buffer: &[u8]) -> Result<Self, crate::event::Error> {
695        require_len_at_least!(buffer, 2);
696
697        let event_code = LittleEndian::read_u16(&buffer[0..=1]);
698
699        match event_code {
700            // SHCI "C2 Ready" event
701            0x9200 => Ok(VendorEvent::CoprocessorReady(to_coprocessor_ready(buffer)?)),
702
703            0x0004 => Ok(VendorEvent::HalEndOfRadioActivity(
704                to_hal_end_of_radio_activity(buffer)?,
705            )),
706            0x0005 => Ok(VendorEvent::HalScanReqReport(to_hal_scan_req_report(
707                buffer,
708            )?)),
709            0x0006 => Ok(VendorEvent::HalFirmwareError(to_hal_firmware_error(
710                buffer,
711            )?)),
712            0x0400 => Ok(VendorEvent::GapLimitedDiscoverableTimeout),
713            0x0401 => Ok(VendorEvent::GapPairingComplete(to_gap_pairing_complete(
714                buffer,
715            )?)),
716            0x0402 => Ok(VendorEvent::GapPassKeyRequest(to_conn_handle(buffer)?)),
717            0x0403 => Ok(VendorEvent::GapAuthorizationRequest(to_conn_handle(
718                buffer,
719            )?)),
720            0x0404 => Ok(VendorEvent::GapPeripheralSecurityInitiated),
721            0x0405 => Ok(VendorEvent::GapBondLost),
722            0x0406 => Ok(VendorEvent::GapDeviceFound(to_gap_device_found(buffer)?)),
723            0x0407 => Ok(VendorEvent::GapProcedureComplete(
724                to_gap_procedure_complete(buffer)?,
725            )),
726            0x0408 => Ok(VendorEvent::GapAddressNotResolved(to_conn_handle(buffer)?)),
727            0x0409 => Ok(VendorEvent::GapNumericComparisonValue(
728                to_numeric_comparison_value(buffer)?,
729            )),
730            0x040A => Ok(VendorEvent::GapKeypressNotification(
731                to_keypress_notification(buffer)?,
732            )),
733            0x0800 => Ok(VendorEvent::L2CapConnectionUpdateResponse(
734                to_l2cap_connection_update_response(buffer)?,
735            )),
736            0x0801 => Ok(VendorEvent::L2CapProcedureTimeout(
737                to_l2cap_procedure_timeout(buffer)?,
738            )),
739            0x0802 => Ok(VendorEvent::L2CapConnectionUpdateRequest(
740                to_l2cap_connection_update_request(buffer)?,
741            )),
742            0x080A => Ok(VendorEvent::L2CapCommandReject(to_l2cap_command_reject(
743                buffer,
744            )?)),
745            0x0810 => Ok(VendorEvent::L2CapCocConnect(to_l2cap_coc_connect(buffer)?)),
746            0x0811 => Ok(VendorEvent::L2CapCocConnectConfirm(
747                to_l2cap_coc_connect_confirm(buffer)?,
748            )),
749            0x0812 => Ok(VendorEvent::L2CapCocReconfig(to_l2cap_coc_reconfig(
750                buffer,
751            )?)),
752            0x0813 => Ok(VendorEvent::L2CapCocReconfigConfirm(
753                to_l2cap_coc_reconfig_confirm(buffer)?,
754            )),
755            0x0814 => Ok(VendorEvent::L2CapCocDisconnect({
756                require_len!(buffer, 1);
757                buffer[0]
758            })),
759            0x0815 => Ok(VendorEvent::L2CapCocFlowControl(to_l2cap_coc_flow_control(
760                buffer,
761            )?)),
762            0x0816 => Ok(VendorEvent::L2CapCocRxData(to_l2cap_coc_rx_data(buffer)?)),
763            0x0817 => Ok(VendorEvent::L2CapCocTxPoolAvailable),
764            0x0C01 => Ok(VendorEvent::GattAttributeModified(
765                to_gatt_attribute_modified(buffer)?,
766            )),
767            0x0C02 => Ok(VendorEvent::GattProcedureTimeout(to_conn_handle(buffer)?)),
768            0x0C03 => Ok(VendorEvent::AttExchangeMtuResponse(
769                to_att_exchange_mtu_resp(buffer)?,
770            )),
771            0x0C04 => Ok(VendorEvent::AttFindInformationResponse(
772                to_att_find_information_response(buffer)?,
773            )),
774            0x0C05 => Ok(VendorEvent::AttFindByTypeValueResponse(
775                to_att_find_by_value_type_response(buffer)?,
776            )),
777            0x0C06 => Ok(VendorEvent::AttReadByTypeResponse(
778                to_att_read_by_type_response(buffer)?,
779            )),
780            0x0C07 => Ok(VendorEvent::AttReadResponse(to_att_read_response(buffer)?)),
781            0x0C08 => Ok(VendorEvent::AttReadBlobResponse(to_att_read_response(
782                buffer,
783            )?)),
784            0x0C09 => Ok(VendorEvent::AttReadMultipleResponse(to_att_read_response(
785                buffer,
786            )?)),
787            0x0C0A => Ok(VendorEvent::AttReadByGroupTypeResponse(
788                to_att_read_by_group_type_response(buffer)?,
789            )),
790            0x0C0C => Ok(VendorEvent::AttPrepareWriteResponse(
791                to_att_prepare_write_response(buffer)?,
792            )),
793            0x0C0D => Ok(VendorEvent::AttExecuteWriteResponse(to_conn_handle(
794                buffer,
795            )?)),
796            0x0C0E => Ok(VendorEvent::GattIndication(to_attribute_value(buffer)?)),
797            0x0C0F => Ok(VendorEvent::GattNotification(to_attribute_value(buffer)?)),
798            0x0C10 => Ok(VendorEvent::GattProcedureComplete(
799                to_gatt_procedure_complete(buffer)?,
800            )),
801            0x0C11 => Ok(VendorEvent::AttErrorResponse(to_att_error_response(
802                buffer,
803            )?)),
804            0x0C12 => Ok(VendorEvent::GattDiscoverOrReadCharacteristicByUuidResponse(
805                to_attribute_value(buffer)?,
806            )),
807            0x0C13 => Ok(VendorEvent::AttWritePermitRequest(to_write_permit_request(
808                buffer,
809            )?)),
810            0x0C14 => Ok(VendorEvent::AttReadPermitRequest(
811                to_att_read_permit_request(buffer)?,
812            )),
813            0x0C15 => Ok(VendorEvent::AttReadMultiplePermitRequest(
814                to_att_read_multiple_permit_request(buffer)?,
815            )),
816            0x0C16 => Ok(VendorEvent::GattTxPoolAvailable(to_gatt_tx_pool_available(
817                buffer,
818            )?)),
819            0x0C17 => Ok(VendorEvent::GattServerConfirmation(to_conn_handle(buffer)?)),
820            0x0C18 => Ok(VendorEvent::AttPrepareWritePermitRequest(
821                to_att_prepare_write_permit_request(buffer)?,
822            )),
823            0x0C19 => Ok(VendorEvent::GattEattBrearer(to_gatt_eatt_bearer(buffer)?)),
824            0x0C1A => Ok(VendorEvent::GattMultiNotification(
825                to_gatt_multi_notification(buffer)?,
826            )),
827            0x0C1B => Ok(VendorEvent::GattNotificationComplete({
828                require_len!(buffer, 2);
829                AttributeHandle(LittleEndian::read_u16(buffer))
830            })),
831            0x0C1D => Ok(VendorEvent::GattReadExt(to_gatt_read_ext(buffer)?)),
832            0x0C1E => Ok(VendorEvent::GattIndicationExt(to_attribute_value_ext(
833                buffer,
834            )?)),
835            0x0C1F => Ok(VendorEvent::GattNotificationExt(to_attribute_value_ext(
836                buffer,
837            )?)),
838            _ => Err(crate::event::Error::Vendor(VendorError::UnknownEvent(
839                event_code,
840            ))),
841        }
842    }
843}
844
845/// Potential firmware kinds for [`CoprocessorReady`](VendorEvent::CoprocessorReady)
846/// event.
847#[derive(Clone, Copy, Debug, PartialEq)]
848#[cfg_attr(feature = "defmt", derive(defmt::Format))]
849pub enum FirmwareKind {
850    /// Wireless firmware (BLE, Thread, etc.)
851    Wireless,
852
853    /// RCC firmware.
854    Rcc,
855}
856
857impl TryFrom<u8> for FirmwareKind {
858    type Error = VendorError;
859
860    fn try_from(value: u8) -> Result<Self, Self::Error> {
861        match value {
862            0 => Ok(FirmwareKind::Wireless),
863            1 => Ok(FirmwareKind::Rcc),
864            _ => Err(VendorError::UnknownFirmwareKind(value)),
865        }
866    }
867}
868
869/// Convert a buffer to the `CoprocessorReady` `VendorEvent`.
870///
871/// # Errors
872///
873/// - Returns a `BadLength` HCI error if the buffer is not exactly 3 bytes long
874/// - Returns a `UnknownFirmwareKind` CPU2 error if the firmware kind is not recognized.
875fn to_coprocessor_ready(buffer: &[u8]) -> Result<FirmwareKind, crate::event::Error> {
876    require_len!(buffer, 3);
877
878    buffer[0].try_into().map_err(crate::event::Error::Vendor)
879}
880
881macro_rules! require_l2cap_event_data_len {
882    ($left:expr, $right:expr) => {
883        let actual = $left[4];
884        if actual != $right {
885            return Err(crate::event::Error::Vendor(
886                VendorError::BadL2CapDataLength(actual, $right),
887            ));
888        }
889    };
890}
891
892macro_rules! require_l2cap_len {
893    ($actual:expr, $expected:expr) => {
894        if $actual != $expected {
895            return Err(crate::event::Error::Vendor(VendorError::BadL2CapLength(
896                $actual, $expected,
897            )));
898        }
899    };
900}
901
902/// This event is generated when the central device responds to the L2CAP connection update request
903/// packet.
904///
905/// For more info see connection parameter update response and command reject in Bluetooth Core v4.0
906/// spec.
907#[derive(Copy, Clone, Debug)]
908#[cfg_attr(feature = "defmt", derive(defmt::Format))]
909pub struct L2CapConnectionUpdateResponse {
910    /// The connection handle related to the event
911    pub conn_handle: ConnectionHandle,
912
913    /// The result of the update request, including details about the result.
914    pub result: L2CapConnectionUpdateResult,
915}
916
917/// Reasons why an L2CAP command was rejected. see the Bluetooth specification, v4.1, Vol 3, Part A,
918/// Section 4.1.
919#[derive(Copy, Clone, Debug, PartialEq)]
920#[cfg_attr(feature = "defmt", derive(defmt::Format))]
921pub enum L2CapRejectionReason {
922    /// The controller sent an unknown command.
923    CommandNotUnderstood,
924    /// When multiple commands are included in an L2CAP packet and the packet exceeds the signaling
925    /// MTU (MTUsig) of the receiver, a single Command Reject packet shall be sent in response.
926    SignalingMtuExceeded,
927    /// Invalid CID in request
928    InvalidCid,
929}
930
931impl TryFrom<u16> for L2CapRejectionReason {
932    type Error = VendorError;
933
934    fn try_from(value: u16) -> Result<Self, Self::Error> {
935        match value {
936            0 => Ok(L2CapRejectionReason::CommandNotUnderstood),
937            1 => Ok(L2CapRejectionReason::SignalingMtuExceeded),
938            2 => Ok(L2CapRejectionReason::InvalidCid),
939            _ => Err(VendorError::BadL2CapRejectionReason(value)),
940        }
941    }
942}
943
944/// Potential results that can be used in the L2CAP connection update response.
945#[derive(Copy, Clone, Debug, PartialEq)]
946#[cfg_attr(feature = "defmt", derive(defmt::Format))]
947pub enum L2CapConnectionUpdateResult {
948    /// The update request was rejected. The code indicates the reason for the rejection.
949    CommandRejected(L2CapRejectionReason),
950
951    /// The L2CAP connection update response is valid. The code indicates if the parameters were
952    /// rejected.
953    ParametersRejected,
954
955    /// The L2CAP connection update response is valid. The code indicates if the parameters were
956    /// updated.
957    ParametersUpdated,
958}
959
960fn to_l2cap_connection_update_accepted_result(
961    value: u16,
962) -> Result<L2CapConnectionUpdateResult, VendorError> {
963    match value {
964        0x0000 => Ok(L2CapConnectionUpdateResult::ParametersUpdated),
965        0x0001 => Ok(L2CapConnectionUpdateResult::ParametersRejected),
966        _ => Err(VendorError::BadL2CapConnectionResponseResult(value)),
967    }
968}
969
970fn extract_l2cap_connection_update_response_result(
971    buffer: &[u8],
972) -> Result<L2CapConnectionUpdateResult, VendorError> {
973    match buffer[5] {
974        0x01 => Ok(L2CapConnectionUpdateResult::CommandRejected(
975            LittleEndian::read_u16(&buffer[9..]).try_into()?,
976        )),
977        0x13 => to_l2cap_connection_update_accepted_result(LittleEndian::read_u16(&buffer[9..])),
978        _ => Err(VendorError::BadL2CapConnectionResponseCode(buffer[5])),
979    }
980}
981
982fn to_l2cap_connection_update_response(
983    buffer: &[u8],
984) -> Result<L2CapConnectionUpdateResponse, crate::event::Error> {
985    require_len!(buffer, 11);
986    require_l2cap_event_data_len!(buffer, 6);
987    require_l2cap_len!(LittleEndian::read_u16(&buffer[7..]), 2);
988
989    Ok(L2CapConnectionUpdateResponse {
990        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
991        result: extract_l2cap_connection_update_response_result(buffer)
992            .map_err(crate::event::Error::Vendor)?,
993    })
994}
995
996/// This event is generated when the central device does not respond to the connection update
997/// request within 30 seconds.
998#[derive(Copy, Clone, Debug)]
999#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1000pub struct L2CapProcedureTimeout {
1001    /// The connection handle related to the event.
1002    pub conn_handle: ConnectionHandle,
1003}
1004
1005fn to_l2cap_procedure_timeout(buffer: &[u8]) -> Result<ConnectionHandle, crate::event::Error> {
1006    require_len!(buffer, 5);
1007    require_l2cap_event_data_len!(buffer, 0);
1008
1009    Ok(ConnectionHandle(LittleEndian::read_u16(&buffer[2..])))
1010}
1011
1012/// The event is given by the L2CAP layer when a connection update request is received from the
1013/// peripheral.
1014///
1015/// The application has to respond by calling
1016/// [`l2cap_connection_parameter_update_response`](crate::vendor::command::l2cap::L2capCommands::connection_parameter_update_response).
1017///
1018/// Defined in Vol 3, Part A, section 4.20 of the Bluetooth specification.
1019#[derive(Copy, Clone, Debug)]
1020#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1021pub struct L2CapConnectionUpdateRequest {
1022    /// Handle of the connection for which the connection update request has been received.  The
1023    /// [same handle](crate::vendor::command::l2cap::ConnectionParameterUpdateResponse::conn_handle) has to be
1024    /// returned while responding to the event with the command
1025    /// [`l2cap_connection_parameter_update_response`](crate::vendor::command::l2cap::L2capCommands::connection_parameter_update_response).
1026    pub conn_handle: ConnectionHandle,
1027
1028    /// This is the identifier which associates the request to the response. The
1029    /// [same identifier](crate::vendor::command::l2cap::ConnectionParameterUpdateResponse::identifier) has to be returned
1030    /// by the upper layer in the command
1031    /// [`l2cap_connection_parameter_update_response`](crate::vendor::command::l2cap::L2capCommands::connection_parameter_update_response).
1032    pub identifier: u8,
1033
1034    /// Defines the range of the connection interval, the latency, and the supervision timeout.
1035    pub conn_interval: ConnectionInterval,
1036}
1037
1038fn to_l2cap_connection_update_request(
1039    buffer: &[u8],
1040) -> Result<L2CapConnectionUpdateRequest, crate::event::Error> {
1041    require_len!(buffer, 16);
1042    require_l2cap_event_data_len!(buffer, 11);
1043    require_l2cap_len!(LittleEndian::read_u16(&buffer[6..]), 8);
1044
1045    let interval = ConnectionInterval::from_bytes(&buffer[8..16])
1046        .map_err(VendorError::BadConnectionInterval)
1047        .map_err(crate::event::Error::Vendor)?;
1048
1049    Ok(L2CapConnectionUpdateRequest {
1050        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
1051        identifier: buffer[5],
1052        conn_interval: interval,
1053    })
1054}
1055
1056/// This event is generated when the pairing process has completed successfully or a pairing
1057/// procedure timeout has occurred or the pairing has failed. This is to notify the application that
1058/// we have paired with a remote device so that it can take further actions or to notify that a
1059/// timeout has occurred so that the upper layer can decide to disconnect the link.
1060#[derive(Copy, Clone, Debug)]
1061#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1062pub struct GapPairingComplete {
1063    /// Connection handle on which the pairing procedure completed
1064    pub conn_handle: ConnectionHandle,
1065
1066    /// Reason the pairing is complete.
1067    pub status: GapPairingStatus,
1068
1069    /// Pairing failed reason code (valid in case of pairing failed status)
1070    pub reason: GapPairingReason,
1071}
1072
1073/// Reasons the [GAP Pairing Complete](VendorEvent::GapPairingComplete) event was generated.
1074#[derive(Copy, Clone, Debug, PartialEq)]
1075#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1076pub enum GapPairingStatus {
1077    /// Pairing with a remote device was successful.
1078    Success,
1079    /// The SMP timeout has elapsed and no further SMP commands will be processed until
1080    /// reconnection.
1081    Timeout,
1082    /// The pairing failed with the remote device.
1083    Failed,
1084}
1085
1086impl TryFrom<u8> for GapPairingStatus {
1087    type Error = VendorError;
1088
1089    fn try_from(value: u8) -> Result<Self, Self::Error> {
1090        match value {
1091            0 => Ok(GapPairingStatus::Success),
1092            1 => Ok(GapPairingStatus::Timeout),
1093            2 => Ok(GapPairingStatus::Failed),
1094            _ => Err(VendorError::BadGapPairingStatus(value)),
1095        }
1096    }
1097}
1098
1099/// Reasons the [GAP Pairing Complete](VendorEvent::GapPairingComplete) event failed.
1100#[derive(Copy, Clone, Debug, PartialEq)]
1101#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1102pub enum GapPairingReason {
1103    PasskeyEntryFailed = 0x01,
1104    OobNotAvailable = 0x02,
1105    AuthRequirements = 0x03,
1106    ConfirmValueFailed = 0x04,
1107    PairingNotSupported = 0x05,
1108    EncryptionKeySize = 0x06,
1109    CommandNotSupported = 0x07,
1110    Unspecified = 0x08,
1111    RepeatedAttemptes = 0x09,
1112    InvalidParams = 0x0A,
1113    DHKeyCheckFailed = 0x0B,
1114    NumericComparisonFailed = 0x0C,
1115    KeyRejected = 0x0F,
1116}
1117
1118impl TryFrom<u8> for GapPairingReason {
1119    type Error = VendorError;
1120
1121    fn try_from(value: u8) -> Result<Self, Self::Error> {
1122        match value {
1123            0x01 => Ok(GapPairingReason::PasskeyEntryFailed),
1124            0x02 => Ok(GapPairingReason::OobNotAvailable),
1125            0x03 => Ok(GapPairingReason::AuthRequirements),
1126            0x04 => Ok(GapPairingReason::ConfirmValueFailed),
1127            0x05 => Ok(GapPairingReason::PairingNotSupported),
1128            0x06 => Ok(GapPairingReason::EncryptionKeySize),
1129            0x07 => Ok(GapPairingReason::CommandNotSupported),
1130            0x08 => Ok(GapPairingReason::Unspecified),
1131            0x09 => Ok(GapPairingReason::RepeatedAttemptes),
1132            0x0A => Ok(GapPairingReason::InvalidParams),
1133            0x0B => Ok(GapPairingReason::DHKeyCheckFailed),
1134            0x0C => Ok(GapPairingReason::NumericComparisonFailed),
1135            0x0F => Ok(GapPairingReason::KeyRejected),
1136            _ => Err(VendorError::BadGapPairingErrorReason(value)),
1137        }
1138    }
1139}
1140
1141fn to_gap_pairing_complete(buffer: &[u8]) -> Result<GapPairingComplete, crate::event::Error> {
1142    require_len!(buffer, 6);
1143    Ok(GapPairingComplete {
1144        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
1145        status: buffer[4].try_into().map_err(crate::event::Error::Vendor)?,
1146        reason: buffer[5].try_into().map_err(crate::event::Error::Vendor)?,
1147    })
1148}
1149
1150fn to_conn_handle(buffer: &[u8]) -> Result<ConnectionHandle, crate::event::Error> {
1151    require_len_at_least!(buffer, 4);
1152    Ok(ConnectionHandle(LittleEndian::read_u16(&buffer[2..])))
1153}
1154
1155/// The event is given by the GAP layer to the upper layers when a device is discovered during
1156/// scanning as a consequence of one of the GAP procedures started by the upper layers.
1157#[derive(Copy, Clone, Debug)]
1158#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1159pub struct GapDeviceFound {
1160    /// Type of event
1161    pub event: GapDeviceFoundEvent,
1162
1163    /// Address of the peer device found during scanning
1164    pub bdaddr: BdAddrType,
1165
1166    // Length of significant data
1167    data_len: usize,
1168
1169    // Advertising or scan response data.
1170    data_buf: [u8; 31],
1171
1172    /// Received signal strength indicator (range: -127 - 20).
1173    pub rssi: Option<i8>,
1174}
1175
1176impl GapDeviceFound {
1177    /// Returns the valid scan response data.
1178    pub fn data(&self) -> &[u8] {
1179        &self.data_buf[..self.data_len]
1180    }
1181}
1182
1183pub use crate::event::AdvertisementEvent as GapDeviceFoundEvent;
1184
1185use super::command::gap::EventFlags;
1186use super::command::l2cap::{
1187    L2CapCocConnect, L2CapCocConnectConfirm, L2CapCocFlowControl, L2CapCocReconfigConfirm,
1188};
1189
1190fn to_gap_device_found(buffer: &[u8]) -> Result<GapDeviceFound, crate::event::Error> {
1191    const RSSI_UNAVAILABLE: i8 = 127;
1192
1193    require_len_at_least!(buffer, 12);
1194
1195    let data_len = buffer[10] as usize;
1196    require_len!(buffer, 12 + data_len);
1197
1198    let rssi = unsafe { mem::transmute::<u8, i8>(buffer[buffer.len() - 1]) };
1199
1200    let mut addr = BdAddr([0; 6]);
1201    addr.0.copy_from_slice(&buffer[4..10]);
1202    let mut event = GapDeviceFound {
1203        event: buffer[2].try_into().map_err(|e| {
1204            if let crate::event::Error::BadLeAdvertisementType(code) = e {
1205                crate::event::Error::Vendor(VendorError::BadGapDeviceFoundEvent(code))
1206            } else {
1207                unreachable!()
1208            }
1209        })?,
1210        bdaddr: crate::to_bd_addr_type(buffer[3], addr)
1211            .map_err(|e| crate::event::Error::Vendor(VendorError::BadGapBdAddrType(e.0)))?,
1212        data_len,
1213        data_buf: [0; 31],
1214        rssi: if rssi == RSSI_UNAVAILABLE {
1215            None
1216        } else {
1217            Some(rssi)
1218        },
1219    };
1220    event.data_buf[..event.data_len].copy_from_slice(&buffer[11..buffer.len() - 1]);
1221
1222    Ok(event)
1223}
1224
1225/// This event is sent by the GAP to the upper layers when a procedure previously started has been
1226/// terminated by the upper layer or has completed for any other reason
1227#[derive(Copy, Clone, Debug)]
1228#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1229pub struct GapProcedureComplete {
1230    /// Type of procedure that completed
1231    pub procedure: GapProcedure,
1232    /// Status of the procedure
1233    pub status: GapProcedureStatus,
1234}
1235
1236/// Maximum length of the name returned in the [`NameDiscovery`](GapProcedure::NameDiscovery)
1237/// procedure.
1238pub const MAX_NAME_LEN: usize = 248;
1239
1240/// Newtype for the name buffer returned after successful
1241/// [`NameDiscovery`](GapProcedure::NameDiscovery).
1242#[derive(Copy, Clone)]
1243#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1244pub struct NameBuffer(pub [u8; MAX_NAME_LEN]);
1245
1246impl Debug for NameBuffer {
1247    fn fmt(&self, f: &mut Formatter) -> FmtResult {
1248        first_16(&self.0).fmt(f)
1249    }
1250}
1251
1252impl PartialEq<NameBuffer> for NameBuffer {
1253    fn eq(&self, other: &Self) -> bool {
1254        if self.0.len() != other.0.len() {
1255            return false;
1256        }
1257
1258        for (a, b) in self.0.iter().zip(other.0.iter()) {
1259            if a != b {
1260                return false;
1261            }
1262        }
1263
1264        true
1265    }
1266}
1267
1268/// Procedures whose completion may be reported by
1269/// [`GapProcedureComplete`](VendorEvent::GapProcedureComplete).
1270#[allow(clippy::large_enum_variant)]
1271#[derive(Copy, Clone, Debug, PartialEq)]
1272#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1273pub enum GapProcedure {
1274    /// See Vol 3, Part C, section 9.2.5.
1275    LimitedDiscovery,
1276    /// See Vol 3, Part C, section 9.2.6.
1277    GeneralDiscovery,
1278    /// See Vol 3, Part C, section 9.2.7. Contains the number of valid bytes and buffer with enough
1279    /// space for the maximum length of the name that can be retuned.
1280    NameDiscovery(usize, NameBuffer),
1281    /// See Vol 3, Part C, section 9.3.5.
1282    AutoConnectionEstablishment,
1283    /// See Vol 3, Part C, section 9.3.6. Contains the reconnection address.
1284    GeneralConnectionEstablishment,
1285    /// See Vol 3, Part C, section 9.3.7.
1286    SelectiveConnectionEstablishment,
1287    /// See Vol 3, Part C, section 9.3.8.
1288    DirectConnectionEstablishment,
1289    Observation,
1290}
1291
1292/// Possible results of a [GAP procedure](VendorEvent::GapProcedureComplete).
1293#[derive(Copy, Clone, Debug, PartialEq)]
1294#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1295pub enum GapProcedureStatus {
1296    /// BLE Status Success.
1297    Success,
1298    /// BLE Status Failed.
1299    Failed,
1300    /// Procedure failed due to authentication requirements.
1301    AuthFailure,
1302}
1303
1304impl TryFrom<u8> for GapProcedureStatus {
1305    type Error = VendorError;
1306
1307    fn try_from(value: u8) -> Result<Self, Self::Error> {
1308        match value {
1309            0x00 => Ok(GapProcedureStatus::Success),
1310            0x41 => Ok(GapProcedureStatus::Failed),
1311            0x05 => Ok(GapProcedureStatus::AuthFailure),
1312            _ => Err(VendorError::BadGapProcedureStatus(value)),
1313        }
1314    }
1315}
1316
1317fn to_gap_procedure_complete(buffer: &[u8]) -> Result<GapProcedureComplete, crate::event::Error> {
1318    require_len_at_least!(buffer, 4);
1319
1320    let procedure = match buffer[2] {
1321        0x01 => GapProcedure::LimitedDiscovery,
1322        0x02 => GapProcedure::GeneralDiscovery,
1323        0x04 => {
1324            require_len_at_least!(buffer, 5);
1325            let name_len = buffer.len() - 4;
1326            let mut name = NameBuffer([0; MAX_NAME_LEN]);
1327            name.0[..name_len].copy_from_slice(&buffer[4..]);
1328
1329            GapProcedure::NameDiscovery(name_len, name)
1330        }
1331        0x08 => GapProcedure::AutoConnectionEstablishment,
1332        0x10 => GapProcedure::GeneralConnectionEstablishment,
1333        0x20 => GapProcedure::SelectiveConnectionEstablishment,
1334        0x40 => GapProcedure::DirectConnectionEstablishment,
1335        0x80 => GapProcedure::Observation,
1336        _ => {
1337            return Err(crate::event::Error::Vendor(VendorError::BadGapProcedure(
1338                buffer[2],
1339            )));
1340        }
1341    };
1342
1343    Ok(GapProcedureComplete {
1344        procedure,
1345        status: buffer[3].try_into().map_err(crate::event::Error::Vendor)?,
1346    })
1347}
1348
1349/// This event is generated to the application by the ATT server when a client modifies any
1350/// attribute on the server, as consequence of one of the following ATT procedures:
1351/// - write without response
1352/// - signed write without response
1353/// - write characteristic value
1354/// - write long characteristic value
1355/// - reliable write
1356#[derive(Copy, Clone)]
1357#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1358pub struct GattAttributeModified {
1359    /// The connection handle which modified the attribute
1360    pub conn_handle: ConnectionHandle,
1361    ///  Handle of the attribute that was modified
1362    pub attr_handle: AttributeHandle,
1363
1364    offset: u16,
1365
1366    /// Number of valid bytes in |data|.
1367    data_len: usize,
1368    /// The new attribute value, starting from the given offset. If compiling with "ms" support, the
1369    /// offset is 0.
1370    data_buf: [u8; MAX_ATTRIBUTE_LEN],
1371}
1372
1373impl GattAttributeModified {
1374    /// Returns the valid attribute data returned by the ATT attribute modified event as a slice of
1375    /// bytes.
1376    pub fn data(&self) -> &[u8] {
1377        &self.data_buf[..self.data_len]
1378    }
1379}
1380
1381/// Newtype for an attribute handle. These handles are IDs, not general integers, and should not be
1382/// manipulated as such.
1383#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
1384#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1385pub struct AttributeHandle(pub u16);
1386
1387// Defines the maximum length of a ATT attribute value field. This is determined by the max packet
1388// size (255) less the minimum number of bytes used by other fields in any packet.
1389const MAX_ATTRIBUTE_LEN: usize = 248;
1390
1391impl Debug for GattAttributeModified {
1392    fn fmt(&self, f: &mut Formatter) -> FmtResult {
1393        f.debug_struct("GattAttributeModified")
1394            .field("conn_handle", &self.conn_handle)
1395            .field("attr_handle", &self.attr_handle)
1396            .field("offset", &self.offset)
1397            .field("data", &first_16(self.data()))
1398            .finish()
1399    }
1400}
1401
1402fn to_gatt_attribute_modified(buffer: &[u8]) -> Result<GattAttributeModified, crate::event::Error> {
1403    require_len_at_least!(buffer, 10);
1404
1405    let data_len = LittleEndian::read_u16(&buffer[8..]) as usize;
1406    require_len!(buffer, 10 + data_len);
1407
1408    let mut data = [0; MAX_ATTRIBUTE_LEN];
1409    data[..data_len].copy_from_slice(&buffer[10..]);
1410
1411    let offset_field = LittleEndian::read_u16(&buffer[6..]);
1412    Ok(GattAttributeModified {
1413        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
1414        attr_handle: AttributeHandle(LittleEndian::read_u16(&buffer[4..])),
1415        offset: (offset_field & 0x7FFF),
1416        data_len,
1417        data_buf: data,
1418    })
1419}
1420
1421/// This event is generated in response to an Exchange MTU request.
1422#[derive(Copy, Clone, Debug)]
1423#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1424pub struct AttExchangeMtuResponse {
1425    ///  The connection handle related to the response.
1426    pub conn_handle: ConnectionHandle,
1427
1428    /// Attribute server receive MTU size.
1429    pub server_rx_mtu: usize,
1430}
1431
1432fn to_att_exchange_mtu_resp(buffer: &[u8]) -> Result<AttExchangeMtuResponse, crate::event::Error> {
1433    require_len!(buffer, 6);
1434    Ok(AttExchangeMtuResponse {
1435        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
1436        server_rx_mtu: LittleEndian::read_u16(&buffer[4..]) as usize,
1437    })
1438}
1439
1440/// This event is generated in response to a Find Information Request. See Find Information Response
1441/// in Bluetooth Core v4.0 spec.
1442#[derive(Copy, Clone, Debug)]
1443#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1444pub struct AttFindInformationResponse {
1445    /// The connection handle related to the response
1446    pub conn_handle: ConnectionHandle,
1447    /// The Find Information Response shall have complete handle-UUID pairs. Such pairs shall not be
1448    /// split across response packets; this also implies that a handleUUID pair shall fit into a
1449    /// single response packet. The handle-UUID pairs shall be returned in ascending order of
1450    /// attribute handles.
1451    handle_uuid_pairs: HandleUuidPairs,
1452}
1453
1454impl AttFindInformationResponse {
1455    /// The Find Information Response shall have complete handle-UUID pairs. Such pairs shall not be
1456    /// split across response packets; this also implies that a handleUUID pair shall fit into a
1457    /// single response packet. The handle-UUID pairs shall be returned in ascending order of
1458    /// attribute handles.
1459    pub fn handle_uuid_pair_iter(&self) -> HandleUuidPairIterator {
1460        match self.handle_uuid_pairs {
1461            HandleUuidPairs::Format16(count, ref data) => {
1462                HandleUuidPairIterator::Format16(HandleUuid16PairIterator {
1463                    data,
1464                    count,
1465                    next_index: 0,
1466                })
1467            }
1468            HandleUuidPairs::Format128(count, ref data) => {
1469                HandleUuidPairIterator::Format128(HandleUuid128PairIterator {
1470                    data,
1471                    count,
1472                    next_index: 0,
1473                })
1474            }
1475        }
1476    }
1477}
1478
1479// Assuming a maximum HCI packet size of 255, these are the maximum number of handle-UUID pairs for
1480// each format that can be in one packet.  Formats cannot be mixed in a single packet.
1481//
1482// Packets have 6 other bytes of data preceding the handle-UUID pairs.
1483//
1484// max = floor((255 - 6) / pair_length)
1485const MAX_FORMAT16_PAIR_COUNT: usize = 62;
1486const MAX_FORMAT128_PAIR_COUNT: usize = 13;
1487
1488/// One format of the handle-UUID pairs in the [`AttFindInformationResponse`] event. The UUIDs are
1489/// 16 bits.
1490#[derive(Copy, Clone, Debug)]
1491#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1492pub struct HandleUuid16Pair {
1493    /// Attribute handle
1494    pub handle: AttributeHandle,
1495    /// Attribute UUID
1496    pub uuid: Uuid16,
1497}
1498
1499/// One format of the handle-UUID pairs in the [`AttFindInformationResponse`] event. The UUIDs are
1500/// 128 bits.
1501#[derive(Copy, Clone, Debug)]
1502#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1503pub struct HandleUuid128Pair {
1504    /// Attribute handle
1505    pub handle: AttributeHandle,
1506    /// Attribute UUID
1507    pub uuid: Uuid128,
1508}
1509
1510/// Newtype for the 16-bit UUID buffer.
1511#[derive(Copy, Clone, Debug, PartialEq)]
1512#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1513pub struct Uuid16(pub u16);
1514
1515/// Newtype for the 128-bit UUID buffer.
1516#[derive(Copy, Clone, Debug, PartialEq)]
1517#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1518pub struct Uuid128(pub [u8; 16]);
1519
1520#[derive(Copy, Clone)]
1521#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1522enum HandleUuidPairs {
1523    Format16(usize, [HandleUuid16Pair; MAX_FORMAT16_PAIR_COUNT]),
1524    Format128(usize, [HandleUuid128Pair; MAX_FORMAT128_PAIR_COUNT]),
1525}
1526
1527impl Debug for HandleUuidPairs {
1528    fn fmt(&self, f: &mut Formatter) -> FmtResult {
1529        write!(f, "{{")?;
1530        match *self {
1531            HandleUuidPairs::Format16(count, pairs) => {
1532                for handle_uuid_pair in &pairs[..count] {
1533                    write!(
1534                        f,
1535                        "{{{:?}, {:?}}}",
1536                        handle_uuid_pair.handle, handle_uuid_pair.uuid
1537                    )?
1538                }
1539            }
1540            HandleUuidPairs::Format128(count, pairs) => {
1541                for handle_uuid_pair in &pairs[..count] {
1542                    write!(
1543                        f,
1544                        "{{{:?}, {:?}}}",
1545                        handle_uuid_pair.handle, handle_uuid_pair.uuid
1546                    )?
1547                }
1548            }
1549        }
1550        write!(f, "}}")
1551    }
1552}
1553
1554/// Possible iterators over handle-UUID pairs that can be returnedby the
1555/// [ATT find information response](AttFindInformationResponse). All pairs from the same event have the same format.
1556#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1557pub enum HandleUuidPairIterator<'a> {
1558    /// The event contains 16-bit UUIDs.
1559    Format16(HandleUuid16PairIterator<'a>),
1560    /// The event contains 128-bit UUIDs.
1561    Format128(HandleUuid128PairIterator<'a>),
1562}
1563
1564/// Iterator over handle-UUID pairs for 16-bit UUIDs.
1565#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1566pub struct HandleUuid16PairIterator<'a> {
1567    data: &'a [HandleUuid16Pair; MAX_FORMAT16_PAIR_COUNT],
1568    count: usize,
1569    next_index: usize,
1570}
1571
1572impl<'a> Iterator for HandleUuid16PairIterator<'a> {
1573    type Item = HandleUuid16Pair;
1574    fn next(&mut self) -> Option<Self::Item> {
1575        if self.next_index >= self.count {
1576            return None;
1577        }
1578
1579        let index = self.next_index;
1580        self.next_index += 1;
1581        Some(self.data[index])
1582    }
1583}
1584
1585/// Iterator over handle-UUID pairs for 128-bit UUIDs.
1586#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1587pub struct HandleUuid128PairIterator<'a> {
1588    data: &'a [HandleUuid128Pair; MAX_FORMAT128_PAIR_COUNT],
1589    count: usize,
1590    next_index: usize,
1591}
1592
1593impl<'a> Iterator for HandleUuid128PairIterator<'a> {
1594    type Item = HandleUuid128Pair;
1595    fn next(&mut self) -> Option<Self::Item> {
1596        if self.next_index >= self.count {
1597            return None;
1598        }
1599
1600        let index = self.next_index;
1601        self.next_index += 1;
1602        Some(self.data[index])
1603    }
1604}
1605
1606fn to_att_find_information_response(
1607    buffer: &[u8],
1608) -> Result<AttFindInformationResponse, crate::event::Error> {
1609    require_len_at_least!(buffer, 4);
1610
1611    let data_len = buffer[5] as usize;
1612    require_len!(buffer, 6 + data_len);
1613
1614    Ok(AttFindInformationResponse {
1615        conn_handle: to_conn_handle(buffer)?,
1616        handle_uuid_pairs: match buffer[4] {
1617            1 => to_handle_uuid16_pairs(&buffer[6..]).map_err(crate::event::Error::Vendor)?,
1618            2 => to_handle_uuid128_pairs(&buffer[6..]).map_err(crate::event::Error::Vendor)?,
1619            _ => {
1620                return Err(crate::event::Error::Vendor(
1621                    VendorError::BadAttFindInformationResponseFormat(buffer[4]),
1622                ));
1623            }
1624        },
1625    })
1626}
1627
1628// [0x4, 0xc, 0x1, 0x8, 0x1, 0x8, 0x12, 0x0, 0x3, 0x5, 0x13, 0x0, 0x2, 0x29]
1629
1630fn to_handle_uuid16_pairs(buffer: &[u8]) -> Result<HandleUuidPairs, VendorError> {
1631    const PAIR_LEN: usize = 4;
1632    if buffer.len() % PAIR_LEN != 0 {
1633        return Err(VendorError::AttFindInformationResponsePartialPair16);
1634    }
1635
1636    let count = buffer.len() / PAIR_LEN;
1637    let mut pairs = [HandleUuid16Pair {
1638        handle: AttributeHandle(0),
1639        uuid: Uuid16(0),
1640    }; MAX_FORMAT16_PAIR_COUNT];
1641    for (i, pair) in pairs.iter_mut().enumerate().take(count) {
1642        let index = i * PAIR_LEN;
1643        pair.handle = AttributeHandle(LittleEndian::read_u16(&buffer[index..]));
1644        pair.uuid = Uuid16(LittleEndian::read_u16(&buffer[2 + index..]));
1645    }
1646
1647    Ok(HandleUuidPairs::Format16(count, pairs))
1648}
1649
1650fn to_handle_uuid128_pairs(buffer: &[u8]) -> Result<HandleUuidPairs, VendorError> {
1651    const PAIR_LEN: usize = 18;
1652    if buffer.len() % PAIR_LEN != 0 {
1653        return Err(VendorError::AttFindInformationResponsePartialPair128);
1654    }
1655
1656    let count = buffer.len() / PAIR_LEN;
1657    let mut pairs = [HandleUuid128Pair {
1658        handle: AttributeHandle(0),
1659        uuid: Uuid128([0; 16]),
1660    }; MAX_FORMAT128_PAIR_COUNT];
1661    for (i, pair) in pairs.iter_mut().enumerate().take(count) {
1662        let index = i * PAIR_LEN;
1663        let next_index = (i + 1) * PAIR_LEN;
1664        pair.handle = AttributeHandle(LittleEndian::read_u16(&buffer[index..]));
1665        pair.uuid.0.copy_from_slice(&buffer[2 + index..next_index]);
1666    }
1667
1668    Ok(HandleUuidPairs::Format128(count, pairs))
1669}
1670
1671/// This event is generated in response to a Find By Type Value Request.
1672#[derive(Copy, Clone)]
1673#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1674pub struct AttFindByTypeValueResponse {
1675    /// The connection handle related to the response.
1676    pub conn_handle: ConnectionHandle,
1677
1678    /// The number of valid pairs that follow.
1679    handle_pair_count: usize,
1680
1681    /// Handles Information List as defined in Bluetooth Core v4.1 spec.
1682    handles: [HandleInfoPair; MAX_HANDLE_INFO_PAIR_COUNT],
1683}
1684
1685impl AttFindByTypeValueResponse {
1686    /// Returns an iterator over the Handles Information List as defined in Bluetooth Core v4.1
1687    /// spec.
1688    pub fn handle_pairs_iter(&self) -> HandleInfoPairIterator {
1689        HandleInfoPairIterator {
1690            event: self,
1691            next_index: 0,
1692        }
1693    }
1694}
1695
1696impl Debug for AttFindByTypeValueResponse {
1697    fn fmt(&self, f: &mut Formatter) -> FmtResult {
1698        write!(f, "{{.conn_handle = {:?}, ", self.conn_handle)?;
1699        for handle_pair in self.handle_pairs_iter() {
1700            write!(f, "{:?}", handle_pair)?;
1701        }
1702        write!(f, "}}")
1703    }
1704}
1705
1706// Assuming a maximum HCI packet size of 255, these are the maximum number of handle pairs that can
1707// be in one packet.
1708//
1709// Packets have 5 other bytes of data preceding the handle-UUID pairs.
1710//
1711// max = floor((255 - 5) / 4)
1712const MAX_HANDLE_INFO_PAIR_COUNT: usize = 62;
1713
1714/// Simple container for the handle information returned in [`AttFindByTypeValueResponse`].
1715#[derive(Copy, Clone, Debug)]
1716#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1717pub struct HandleInfoPair {
1718    /// Attribute handle
1719    pub attribute: AttributeHandle,
1720    /// Group End handle
1721    pub group_end: GroupEndHandle,
1722}
1723
1724/// Newtype for Group End handles
1725#[derive(Copy, Clone, Debug, PartialEq)]
1726#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1727pub struct GroupEndHandle(pub u16);
1728
1729/// Iterator into valid [`HandleInfoPair`] structs returned in the
1730/// [ATT Find By Type Value Response](AttFindByTypeValueResponse) event.
1731#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1732pub struct HandleInfoPairIterator<'a> {
1733    event: &'a AttFindByTypeValueResponse,
1734    next_index: usize,
1735}
1736
1737impl<'a> Iterator for HandleInfoPairIterator<'a> {
1738    type Item = HandleInfoPair;
1739
1740    fn next(&mut self) -> Option<Self::Item> {
1741        if self.next_index >= self.event.handle_pair_count {
1742            return None;
1743        }
1744
1745        let index = self.next_index;
1746        self.next_index += 1;
1747        Some(self.event.handles[index])
1748    }
1749}
1750
1751fn to_att_find_by_value_type_response(
1752    buffer: &[u8],
1753) -> Result<AttFindByTypeValueResponse, crate::event::Error> {
1754    const PAIR_LEN: usize = 4;
1755
1756    require_len_at_least!(buffer, 5);
1757
1758    let data_len = buffer[4] as usize;
1759    require_len!(buffer, 5 + data_len);
1760
1761    let pair_buffer = &buffer[5..];
1762    if pair_buffer.len() % PAIR_LEN != 0 {
1763        return Err(crate::event::Error::Vendor(
1764            VendorError::AttFindByTypeValuePartial,
1765        ));
1766    }
1767
1768    let count = pair_buffer.len() / PAIR_LEN;
1769    let mut pairs = [HandleInfoPair {
1770        attribute: AttributeHandle(0),
1771        group_end: GroupEndHandle(0),
1772    }; MAX_HANDLE_INFO_PAIR_COUNT];
1773    for (i, pair) in pairs.iter_mut().enumerate().take(count) {
1774        let index = i * PAIR_LEN;
1775        pair.attribute = AttributeHandle(LittleEndian::read_u16(&pair_buffer[index..]));
1776        pair.group_end = GroupEndHandle(LittleEndian::read_u16(&pair_buffer[2 + index..]));
1777    }
1778    Ok(AttFindByTypeValueResponse {
1779        conn_handle: to_conn_handle(buffer)?,
1780        handle_pair_count: count,
1781        handles: pairs,
1782    })
1783}
1784
1785/// This event is generated in response to a Read By Type Request.
1786#[derive(Copy, Clone)]
1787#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1788pub struct AttReadByTypeResponse {
1789    /// The connection handle related to the response.
1790    pub conn_handle: ConnectionHandle,
1791
1792    // Number of valid bytes in `handle_value_pair_buf`
1793    data_len: usize,
1794    // Length of each value in `handle_value_pair_buf`
1795    value_len: usize,
1796    // Raw data of the response. Contains 2 octets for the attribute handle followed by `value_len`
1797    // octets of value data. These pairs repeat for `data_len` bytes.
1798    handle_value_pair_buf: [u8; MAX_HANDLE_VALUE_PAIR_BUF_LEN],
1799}
1800
1801// The maximum amount of data in the buffer is the max HCI packet size (255) less the other data in
1802// the packet.
1803const MAX_HANDLE_VALUE_PAIR_BUF_LEN: usize = 249;
1804
1805impl Debug for AttReadByTypeResponse {
1806    fn fmt(&self, f: &mut Formatter) -> FmtResult {
1807        write!(f, "{{.conn_handle = {:?}, ", self.conn_handle)?;
1808        for handle_value_pair in self.handle_value_pair_iter() {
1809            write!(
1810                f,
1811                "{{handle: {:?}, value: {:?}}}",
1812                handle_value_pair.handle,
1813                first_16(handle_value_pair.value)
1814            )?;
1815        }
1816        write!(f, "}}")
1817    }
1818}
1819
1820impl AttReadByTypeResponse {
1821    /// Return an iterator over all valid handle-value pairs returned with the response.
1822    pub fn handle_value_pair_iter(&self) -> HandleValuePairIterator {
1823        HandleValuePairIterator {
1824            event: self,
1825            index: 0,
1826        }
1827    }
1828}
1829
1830/// Iterator over the valid handle-value pairs returned with the
1831/// [ATT Read by Type response](AttReadByTypeResponse).
1832#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1833pub struct HandleValuePairIterator<'a> {
1834    event: &'a AttReadByTypeResponse,
1835    index: usize,
1836}
1837
1838impl<'a> Iterator for HandleValuePairIterator<'a> {
1839    type Item = HandleValuePair<'a>;
1840    fn next(&mut self) -> Option<Self::Item> {
1841        if self.index >= self.event.data_len {
1842            return None;
1843        }
1844
1845        let handle_index = self.index;
1846        let value_index = self.index + 2;
1847        self.index += 2 + self.event.value_len;
1848        let next_index = self.index;
1849        Some(HandleValuePair {
1850            handle: AttributeHandle(LittleEndian::read_u16(
1851                &self.event.handle_value_pair_buf[handle_index..],
1852            )),
1853            value: &self.event.handle_value_pair_buf[value_index..next_index],
1854        })
1855    }
1856}
1857
1858/// A single handle-value pair returned by the [ATT Read by Type response](AttReadByTypeResponse).
1859#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1860pub struct HandleValuePair<'a> {
1861    /// Attribute handle
1862    pub handle: AttributeHandle,
1863    /// Attribute value. The caller must interpret the value correctly, depending on the expected
1864    /// type of the attribute.
1865    pub value: &'a [u8],
1866}
1867
1868impl<'a> HandleValuePair<'a> {
1869    pub fn uuid(&self) -> u16 {
1870        LittleEndian::read_u16(&self.value[3..])
1871    }
1872}
1873
1874fn to_att_read_by_type_response(
1875    buffer: &[u8],
1876) -> Result<AttReadByTypeResponse, crate::event::Error> {
1877    require_len_at_least!(buffer, 6);
1878
1879    let data_len = buffer[5] as usize;
1880    require_len!(buffer, 6 + data_len);
1881
1882    let handle_value_pair_len = buffer[4] as usize;
1883    let handle_value_pair_buf = &buffer[6..];
1884    if handle_value_pair_buf.len() % handle_value_pair_len != 0 {
1885        return Err(crate::event::Error::Vendor(
1886            VendorError::AttReadByTypeResponsePartial,
1887        ));
1888    }
1889
1890    let mut full_handle_value_pair_buf = [0; MAX_HANDLE_VALUE_PAIR_BUF_LEN];
1891    full_handle_value_pair_buf[..handle_value_pair_buf.len()]
1892        .copy_from_slice(handle_value_pair_buf);
1893
1894    Ok(AttReadByTypeResponse {
1895        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
1896        data_len: handle_value_pair_buf.len(),
1897        value_len: handle_value_pair_len - 2,
1898        handle_value_pair_buf: full_handle_value_pair_buf,
1899    })
1900}
1901
1902/// This event is generated in response to a Read Request.
1903#[derive(Copy, Clone)]
1904#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1905pub struct AttReadResponse {
1906    /// The connection handle related to the response.
1907    pub conn_handle: ConnectionHandle,
1908
1909    /// The number of valid bytes in the value buffer.
1910    value_len: usize,
1911
1912    /// Buffer containing the value data.
1913    value_buf: [u8; MAX_READ_RESPONSE_LEN],
1914}
1915
1916// The maximum amount of data in the buffer is the max HCI packet size (255) less the other data in
1917// the packet.
1918const MAX_READ_RESPONSE_LEN: usize = 250;
1919
1920impl Debug for AttReadResponse {
1921    fn fmt(&self, f: &mut Formatter) -> FmtResult {
1922        write!(
1923            f,
1924            "{{.conn_handle = {:?}, value = {:?}}}",
1925            self.conn_handle,
1926            first_16(self.value())
1927        )
1928    }
1929}
1930
1931impl AttReadResponse {
1932    /// Returns the valid part of the value data.
1933    pub fn value(&self) -> &[u8] {
1934        &self.value_buf[..self.value_len]
1935    }
1936}
1937
1938fn to_att_read_response(buffer: &[u8]) -> Result<AttReadResponse, crate::event::Error> {
1939    require_len_at_least!(buffer, 5);
1940
1941    let data_len = buffer[4] as usize;
1942    require_len!(buffer, 5 + data_len);
1943
1944    let mut value_buf = [0; MAX_READ_RESPONSE_LEN];
1945    value_buf[..data_len].copy_from_slice(&buffer[5..]);
1946
1947    Ok(AttReadResponse {
1948        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
1949        value_len: data_len,
1950        value_buf,
1951    })
1952}
1953
1954/// This event is generated in response to a Read By Group Type Request. See the Bluetooth Core v4.1
1955/// spec, Vol 3, section 3.4.4.9 and 3.4.4.10.
1956#[derive(Copy, Clone)]
1957#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1958pub struct AttReadByGroupTypeResponse {
1959    ///  The connection handle related to the response.
1960    pub conn_handle: ConnectionHandle,
1961
1962    // Length of the attribute data group in `attribute_data_buf`, including the attribute and group
1963    // end handles.
1964    attribute_group_len: usize,
1965
1966    // Number of valid bytes in `attribute_data_buf`
1967    data_len: usize,
1968
1969    // List of attribute data which is a repetition of:
1970    // 1. 2 octets for attribute handle.
1971    // 2. 2 octets for end group handle.
1972    // 3. (attribute_group_len - 4) octets for attribute value.
1973    attribute_data_buf: [u8; MAX_ATTRIBUTE_DATA_BUF_LEN],
1974}
1975
1976// The maximum amount of data in the buffer is the max HCI packet size (255) less the other data in
1977// the packet.
1978const MAX_ATTRIBUTE_DATA_BUF_LEN: usize = 249;
1979
1980impl AttReadByGroupTypeResponse {
1981    /// Create and return an iterator for the attribute data returned with the response.
1982    pub fn attribute_data_iter(&self) -> AttributeDataIterator {
1983        AttributeDataIterator {
1984            event: self,
1985            next_index: 0,
1986        }
1987    }
1988}
1989
1990impl Debug for AttReadByGroupTypeResponse {
1991    fn fmt(&self, f: &mut Formatter) -> FmtResult {
1992        write!(f, "{{.conn_handle = {:?}, ", self.conn_handle)?;
1993        for attribute_data in self.attribute_data_iter() {
1994            write!(
1995                f,
1996                "{{.attribute_handle = {:?}, .attribute_end_handle = {:?}, .value = {:?}}}",
1997                attribute_data.attribute_handle,
1998                attribute_data.attribute_end_handle,
1999                first_16(attribute_data.value)
2000            )?;
2001        }
2002        write!(f, "}}")
2003    }
2004}
2005
2006/// Iterator over the attribute data returned in the [`AttReadByGroupTypeResponse`].
2007#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2008pub struct AttributeDataIterator<'a> {
2009    event: &'a AttReadByGroupTypeResponse,
2010    next_index: usize,
2011}
2012
2013impl<'a> Iterator for AttributeDataIterator<'a> {
2014    type Item = AttributeData<'a>;
2015    fn next(&mut self) -> Option<Self::Item> {
2016        if self.next_index >= self.event.data_len {
2017            return None;
2018        }
2019
2020        let attr_handle_index = self.next_index;
2021        let group_end_index = 2 + attr_handle_index;
2022        let value_index = 2 + group_end_index;
2023        self.next_index += self.event.attribute_group_len;
2024        Some(AttributeData {
2025            attribute_handle: AttributeHandle(LittleEndian::read_u16(
2026                &self.event.attribute_data_buf[attr_handle_index..],
2027            )),
2028            attribute_end_handle: AttributeHandle(LittleEndian::read_u16(
2029                &self.event.attribute_data_buf[group_end_index..],
2030            )),
2031            value: &self.event.attribute_data_buf[value_index..self.next_index],
2032        })
2033    }
2034}
2035
2036/// Attribute data returned in the [`AttReadByGroupTypeResponse`] event.
2037#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2038pub struct AttributeData<'a> {
2039    /// Attribute handle
2040    pub attribute_handle: AttributeHandle,
2041    /// Group end handle
2042    pub attribute_end_handle: AttributeHandle,
2043    /// Attribute value
2044    pub value: &'a [u8],
2045}
2046
2047impl<'a> AttributeData<'a> {
2048    pub fn uuid(&self) -> u16 {
2049        LittleEndian::read_u16(&self.value[0..])
2050    }
2051}
2052
2053fn to_att_read_by_group_type_response(
2054    buffer: &[u8],
2055) -> Result<AttReadByGroupTypeResponse, crate::event::Error> {
2056    require_len_at_least!(buffer, 6);
2057
2058    let data_len = buffer[5] as usize;
2059    require_len!(buffer, 6 + data_len);
2060
2061    let attribute_group_len = buffer[4] as usize;
2062
2063    if buffer[6..].len() % attribute_group_len != 0 {
2064        return Err(crate::event::Error::Vendor(
2065            VendorError::AttReadByGroupTypeResponsePartial,
2066        ));
2067    }
2068
2069    let mut attribute_data_buf = [0; MAX_ATTRIBUTE_DATA_BUF_LEN];
2070    attribute_data_buf[..data_len].copy_from_slice(&buffer[6..]);
2071    Ok(AttReadByGroupTypeResponse {
2072        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2073        data_len, // lose 1 byte to attribute_group_len
2074        attribute_group_len,
2075        attribute_data_buf,
2076    })
2077}
2078
2079/// This event is generated in response to a Prepare Write Request. See the Bluetooth Core v4.1
2080/// spec, Vol 3, Part F, section 3.4.6.1 and 3.4.6.2
2081#[derive(Copy, Clone)]
2082#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2083pub struct AttPrepareWriteResponse {
2084    /// The connection handle related to the response.
2085    pub conn_handle: ConnectionHandle,
2086    /// The handle of the attribute to be written.
2087    pub attribute_handle: AttributeHandle,
2088    /// The offset of the first octet to be written.
2089    pub offset: usize,
2090
2091    /// Number of valid bytes in |value_buf|
2092    value_len: usize,
2093    value_buf: [u8; MAX_WRITE_RESPONSE_VALUE_LEN],
2094}
2095
2096// The maximum amount of data in the buffer is the max HCI packet size (255) less the other data in
2097// the packet.
2098const MAX_WRITE_RESPONSE_VALUE_LEN: usize = 246;
2099
2100impl Debug for AttPrepareWriteResponse {
2101    fn fmt(&self, f: &mut Formatter) -> FmtResult {
2102        write!(
2103            f,
2104            "{{.conn_handle = {:?}, .attribute_handle = {:?}, .offset = {}, .value = {:?}}}",
2105            self.conn_handle,
2106            self.attribute_handle,
2107            self.offset,
2108            first_16(self.value())
2109        )
2110    }
2111}
2112
2113impl AttPrepareWriteResponse {
2114    /// Returns the partial value of the attribute to be written.
2115    pub fn value(&self) -> &[u8] {
2116        &self.value_buf[..self.value_len]
2117    }
2118}
2119
2120fn to_att_prepare_write_response(
2121    buffer: &[u8],
2122) -> Result<AttPrepareWriteResponse, crate::event::Error> {
2123    require_len_at_least!(buffer, 9);
2124
2125    let data_len = buffer[4] as usize;
2126    require_len!(buffer, 5 + data_len);
2127
2128    let value_len = data_len - 4;
2129    let mut value_buf = [0; MAX_WRITE_RESPONSE_VALUE_LEN];
2130    value_buf[..value_len].copy_from_slice(&buffer[9..]);
2131    Ok(AttPrepareWriteResponse {
2132        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2133        attribute_handle: AttributeHandle(LittleEndian::read_u16(&buffer[5..])),
2134        offset: LittleEndian::read_u16(&buffer[7..]) as usize,
2135        value_len,
2136        value_buf,
2137    })
2138}
2139
2140/// Defines the attribute value returned by a [GATT Indication](VendorEvent::GattIndication) or
2141/// [GATT Notification](VendorEvent::GattNotification) event.
2142#[derive(Copy, Clone)]
2143#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2144pub struct AttributeValue {
2145    /// The connection handle related to the event.
2146    pub conn_handle: ConnectionHandle,
2147    /// The handle of the attribute.
2148    pub attribute_handle: AttributeHandle,
2149
2150    // Number of valid bytes in value_buf
2151    value_len: usize,
2152    // Current value of the attribute. Only the first value_len bytes are valid.
2153    value_buf: [u8; MAX_ATTRIBUTE_VALUE_LEN],
2154}
2155
2156// The maximum amount of data in the buffer is the max HCI packet size (255) less the other data in
2157// the packet.
2158const MAX_ATTRIBUTE_VALUE_LEN: usize = 248;
2159
2160impl Debug for AttributeValue {
2161    fn fmt(&self, f: &mut Formatter) -> FmtResult {
2162        write!(
2163            f,
2164            "{{.conn_handle = {:?}, .attribute_handle = {:?}, .value = {:?}}}",
2165            self.conn_handle,
2166            self.attribute_handle,
2167            first_16(self.value())
2168        )
2169    }
2170}
2171
2172impl AttributeValue {
2173    /// Returns the current value of the attribute.
2174    pub fn value(&self) -> &[u8] {
2175        &self.value_buf[..self.value_len]
2176    }
2177}
2178
2179fn to_attribute_value(buffer: &[u8]) -> Result<AttributeValue, crate::event::Error> {
2180    require_len_at_least!(buffer, 7);
2181
2182    let data_len = buffer[4] as usize;
2183    require_len!(buffer, 5 + data_len);
2184
2185    let value_len = data_len - 2;
2186    let mut value_buf = [0; MAX_ATTRIBUTE_VALUE_LEN];
2187    value_buf[..value_len].copy_from_slice(&buffer[7..]);
2188    Ok(AttributeValue {
2189        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2190        attribute_handle: AttributeHandle(LittleEndian::read_u16(&buffer[5..])),
2191        value_len,
2192        value_buf,
2193    })
2194}
2195
2196fn to_write_permit_request(buffer: &[u8]) -> Result<AttributeValue, crate::event::Error> {
2197    require_len_at_least!(buffer, 7);
2198
2199    let data_len = buffer[6] as usize;
2200    require_len!(buffer, 7 + data_len);
2201
2202    let value_len = data_len;
2203    let mut value_buf = [0; MAX_ATTRIBUTE_VALUE_LEN];
2204    value_buf[..value_len].copy_from_slice(&buffer[7..]);
2205    Ok(AttributeValue {
2206        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2207        attribute_handle: AttributeHandle(LittleEndian::read_u16(&buffer[4..])),
2208        value_len,
2209        value_buf,
2210    })
2211}
2212
2213/// This event is generated when a GATT client procedure completes either with error or
2214/// successfully.
2215#[derive(Copy, Clone, Debug)]
2216#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2217pub struct GattProcedureComplete {
2218    /// The connection handle for which the GATT procedure has completed.
2219    pub conn_handle: ConnectionHandle,
2220
2221    /// Indicates whether the procedure completed with [error](GattProcedureStatus::Failed) or was
2222    /// [successful](GattProcedureStatus::Success).
2223    pub status: GattProcedureStatus,
2224}
2225
2226/// Allowed status codes for the [GATT Procedure Complete](VendorEvent::GattProcedureComplete)
2227/// event.
2228#[derive(Copy, Clone, Debug, PartialEq)]
2229#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2230pub enum GattProcedureStatus {
2231    /// BLE Status Success
2232    Success,
2233    /// BLE Status Failed
2234    Failed,
2235}
2236
2237impl TryFrom<u8> for GattProcedureStatus {
2238    type Error = crate::event::Error;
2239
2240    fn try_from(value: u8) -> Result<Self, Self::Error> {
2241        match value {
2242            0x00 => Ok(GattProcedureStatus::Success),
2243            0x41 => Ok(GattProcedureStatus::Failed),
2244            _ => Err(crate::event::Error::Vendor(
2245                VendorError::BadGattProcedureStatus(value),
2246            )),
2247        }
2248    }
2249}
2250
2251fn to_gatt_procedure_complete(buffer: &[u8]) -> Result<GattProcedureComplete, crate::event::Error> {
2252    require_len!(buffer, 5);
2253
2254    Ok(GattProcedureComplete {
2255        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2256        status: buffer[4].try_into()?,
2257    })
2258}
2259
2260/// The Error Response is used to state that a given request cannot be performed, and to provide the
2261/// reason. See the Bluetooth Core Specification, v4.1, Vol 3, Part F, Section 3.4.1.1.
2262#[derive(Copy, Clone, Debug)]
2263#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2264pub struct AttErrorResponse {
2265    /// The connection handle related to the event.
2266    pub conn_handle: ConnectionHandle,
2267    /// The request that generated this error response.
2268    pub request: AttRequest,
2269    ///The attribute handle that generated this error response.
2270    pub attribute_handle: AttributeHandle,
2271    /// The reason why the request has generated an error response.
2272    pub error: AttError,
2273}
2274
2275/// Potential error codes for the [ATT Error Response](VendorEvent::AttErrorResponse). See Table
2276/// 3.3 in the Bluetooth Core Specification, v4.1, Vol 3, Part F, Section 3.4.1.1 and The Bluetooth
2277/// Core Specification Supplement, Table 1.1.
2278#[repr(u8)]
2279#[derive(Copy, Clone, Debug, PartialEq)]
2280#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2281pub enum AttError {
2282    /// The attribute handle given was not valid on this server.
2283    InvalidHandle = 0x01,
2284    /// The attribute cannot be read.
2285    ReadNotPermitted = 0x02,
2286    /// The attribute cannot be written.
2287    WriteNotPermitted = 0x03,
2288    /// The attribute PDU was invalid.
2289    InvalidPdu = 0x04,
2290    /// The attribute requires authentication before it can be read or written.
2291    InsufficientAuthentication = 0x05,
2292    /// Attribute server does not support the request received from the client.
2293    RequestNotSupported = 0x06,
2294    /// Offset specified was past the end of the attribute.
2295    InvalidOffset = 0x07,
2296    /// The attribute requires authorization before it can be read or written.
2297    InsufficientAuthorization = 0x08,
2298    /// Too many prepare writes have been queued.
2299    PrepareQueueFull = 0x09,
2300    /// No attribute found within the given attribute handle range.
2301    AttributeNotFound = 0x0A,
2302    /// The attribute cannot be read or written using the Read Blob Request.
2303    AttributeNotLong = 0x0B,
2304    /// The Encryption Key Size used for encrypting this link is insufficient.
2305    InsufficientEncryptionKeySize = 0x0C,
2306    /// The attribute value length is invalid for the operation.
2307    InvalidAttributeValueLength = 0x0D,
2308    /// The attribute request that was requested has encountered an error that was unlikely, and
2309    /// therefore could not be completed as requested.
2310    UnlikelyError = 0x0E,
2311    /// The attribute requires encryption before it can be read or written.
2312    InsufficientEncryption = 0x0F,
2313    /// The attribute type is not a supported grouping attribute as defined by a higher layer
2314    /// specification.
2315    UnsupportedGroupType = 0x10,
2316    /// Insufficient Resources to complete the request.
2317    InsufficientResources = 0x11,
2318    /// Database out of sync
2319    DatabaseOutOfSync = 0x12,
2320    /// Value not allowed
2321    ValueNotAllowed = 0x13,
2322    /// Application error code defined by a higher layer specification.
2323    ApplicationError0x80 = 0x80,
2324    /// Application error code defined by a higher layer specification.
2325    ApplicationError0x81 = 0x81,
2326    /// Application error code defined by a higher layer specification.
2327    ApplicationError0x82 = 0x82,
2328    /// Application error code defined by a higher layer specification.
2329    ApplicationError0x83 = 0x83,
2330    /// Application error code defined by a higher layer specification.
2331    ApplicationError0x84 = 0x84,
2332    /// Application error code defined by a higher layer specification.
2333    ApplicationError0x85 = 0x85,
2334    /// Application error code defined by a higher layer specification.
2335    ApplicationError0x86 = 0x86,
2336    /// Application error code defined by a higher layer specification.
2337    ApplicationError0x87 = 0x87,
2338    /// Application error code defined by a higher layer specification.
2339    ApplicationError0x88 = 0x88,
2340    /// Application error code defined by a higher layer specification.
2341    ApplicationError0x89 = 0x89,
2342    /// Application error code defined by a higher layer specification.
2343    ApplicationError0x8A = 0x8A,
2344    /// Application error code defined by a higher layer specification.
2345    ApplicationError0x8B = 0x8B,
2346    /// Application error code defined by a higher layer specification.
2347    ApplicationError0x8C = 0x8C,
2348    /// Application error code defined by a higher layer specification.
2349    ApplicationError0x8D = 0x8D,
2350    /// Application error code defined by a higher layer specification.
2351    ApplicationError0x8E = 0x8E,
2352    /// Application error code defined by a higher layer specification.
2353    ApplicationError0x8F = 0x8F,
2354    /// Application error code defined by a higher layer specification.
2355    ApplicationError0x90 = 0x90,
2356    /// Application error code defined by a higher layer specification.
2357    ApplicationError0x91 = 0x91,
2358    /// Application error code defined by a higher layer specification.
2359    ApplicationError0x92 = 0x92,
2360    /// Application error code defined by a higher layer specification.
2361    ApplicationError0x93 = 0x93,
2362    /// Application error code defined by a higher layer specification.
2363    ApplicationError0x94 = 0x94,
2364    /// Application error code defined by a higher layer specification.
2365    ApplicationError0x95 = 0x95,
2366    /// Application error code defined by a higher layer specification.
2367    ApplicationError0x96 = 0x96,
2368    /// Application error code defined by a higher layer specification.
2369    ApplicationError0x97 = 0x97,
2370    /// Application error code defined by a higher layer specification.
2371    ApplicationError0x98 = 0x98,
2372    /// Application error code defined by a higher layer specification.
2373    ApplicationError0x99 = 0x99,
2374    /// Application error code defined by a higher layer specification.
2375    ApplicationError0x9A = 0x9A,
2376    /// Application error code defined by a higher layer specification.
2377    ApplicationError0x9B = 0x9B,
2378    /// Application error code defined by a higher layer specification.
2379    ApplicationError0x9C = 0x9C,
2380    /// Application error code defined by a higher layer specification.
2381    ApplicationError0x9D = 0x9D,
2382    /// Application error code defined by a higher layer specification.
2383    ApplicationError0x9E = 0x9E,
2384    /// Application error code defined by a higher layer specification.
2385    ApplicationError0x9F = 0x9F,
2386    /// The requested write operation cannot be fulfilled for reasons other than permissions.
2387    WriteRequestRejected = 0xFC,
2388    /// A Client Characteristic Configuration descriptor is not configured according to the
2389    /// requirements of the profile or service.
2390    ClientCharacteristicConfigurationDescriptorImproperlyConfigured = 0xFD,
2391    /// A profile or service request cannot be serviced because an operation that has been
2392    /// previously triggered is still in progress.
2393    ProcedureAlreadyInProgress = 0xFE,
2394    /// An attribute value is out of range as defined by a profile or service specification.
2395    OutOfRange = 0xFF,
2396}
2397
2398impl TryFrom<u8> for AttError {
2399    type Error = u8;
2400
2401    fn try_from(value: u8) -> Result<Self, Self::Error> {
2402        match value {
2403            0x01 => Ok(AttError::InvalidHandle),
2404            0x02 => Ok(AttError::ReadNotPermitted),
2405            0x03 => Ok(AttError::WriteNotPermitted),
2406            0x04 => Ok(AttError::InvalidPdu),
2407            0x05 => Ok(AttError::InsufficientAuthentication),
2408            0x06 => Ok(AttError::RequestNotSupported),
2409            0x07 => Ok(AttError::InvalidOffset),
2410            0x08 => Ok(AttError::InsufficientAuthorization),
2411            0x09 => Ok(AttError::PrepareQueueFull),
2412            0x0A => Ok(AttError::AttributeNotFound),
2413            0x0B => Ok(AttError::AttributeNotLong),
2414            0x0C => Ok(AttError::InsufficientEncryptionKeySize),
2415            0x0D => Ok(AttError::InvalidAttributeValueLength),
2416            0x0E => Ok(AttError::UnlikelyError),
2417            0x0F => Ok(AttError::InsufficientEncryption),
2418            0x10 => Ok(AttError::UnsupportedGroupType),
2419            0x11 => Ok(AttError::InsufficientResources),
2420            0x80 => Ok(AttError::ApplicationError0x80),
2421            0x81 => Ok(AttError::ApplicationError0x81),
2422            0x82 => Ok(AttError::ApplicationError0x82),
2423            0x83 => Ok(AttError::ApplicationError0x83),
2424            0x84 => Ok(AttError::ApplicationError0x84),
2425            0x85 => Ok(AttError::ApplicationError0x85),
2426            0x86 => Ok(AttError::ApplicationError0x86),
2427            0x87 => Ok(AttError::ApplicationError0x87),
2428            0x88 => Ok(AttError::ApplicationError0x88),
2429            0x89 => Ok(AttError::ApplicationError0x89),
2430            0x8A => Ok(AttError::ApplicationError0x8A),
2431            0x8B => Ok(AttError::ApplicationError0x8B),
2432            0x8C => Ok(AttError::ApplicationError0x8C),
2433            0x8D => Ok(AttError::ApplicationError0x8D),
2434            0x8E => Ok(AttError::ApplicationError0x8E),
2435            0x8F => Ok(AttError::ApplicationError0x8F),
2436            0x90 => Ok(AttError::ApplicationError0x90),
2437            0x91 => Ok(AttError::ApplicationError0x91),
2438            0x92 => Ok(AttError::ApplicationError0x92),
2439            0x93 => Ok(AttError::ApplicationError0x93),
2440            0x94 => Ok(AttError::ApplicationError0x94),
2441            0x95 => Ok(AttError::ApplicationError0x95),
2442            0x96 => Ok(AttError::ApplicationError0x96),
2443            0x97 => Ok(AttError::ApplicationError0x97),
2444            0x98 => Ok(AttError::ApplicationError0x98),
2445            0x99 => Ok(AttError::ApplicationError0x99),
2446            0x9A => Ok(AttError::ApplicationError0x9A),
2447            0x9B => Ok(AttError::ApplicationError0x9B),
2448            0x9C => Ok(AttError::ApplicationError0x9C),
2449            0x9D => Ok(AttError::ApplicationError0x9D),
2450            0x9E => Ok(AttError::ApplicationError0x9E),
2451            0x9F => Ok(AttError::ApplicationError0x9F),
2452            0xFC => Ok(AttError::WriteRequestRejected),
2453            0xFD => Ok(AttError::ClientCharacteristicConfigurationDescriptorImproperlyConfigured),
2454            0xFE => Ok(AttError::ProcedureAlreadyInProgress),
2455            0xFF => Ok(AttError::OutOfRange),
2456            _ => Err(value),
2457        }
2458    }
2459}
2460
2461/// Possible ATT requests.  See Table 3.37 in the Bluetooth Core Spec v4.1, Vol 3, Part F, Section
2462/// 3.4.8.
2463#[repr(u8)]
2464#[derive(Copy, Clone, Debug, PartialEq)]
2465#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2466pub enum AttRequest {
2467    /// Section 3.4.1.1
2468    ErrorResponse = 0x01,
2469    /// Section 3.4.2.1
2470    ExchangeMtuRequest = 0x02,
2471    /// Section 3.4.2.2
2472    ExchangeMtuResponse = 0x03,
2473    /// Section 3.4.3.1
2474    FindInformationRequest = 0x04,
2475    /// Section 3.4.3.2
2476    FindInformationResponse = 0x05,
2477    /// Section 3.4.3.3
2478    FindByTypeValueRequest = 0x06,
2479    /// Section 3.4.3.4
2480    FindByTypeValueResponse = 0x07,
2481    /// Section 3.4.4.1
2482    ReadByTypeRequest = 0x08,
2483    /// Section 3.4.4.2
2484    ReadByTypeResponse = 0x09,
2485    /// Section 3.4.4.3
2486    ReadRequest = 0x0A,
2487    /// Section 3.4.4.4
2488    ReadResponse = 0x0B,
2489    /// Section 3.4.4.5
2490    ReadBlobRequest = 0x0C,
2491    /// Section 3.4.4.6
2492    ReadBlobResponse = 0x0D,
2493    /// Section 3.4.4.7
2494    ReadMultipleRequest = 0x0E,
2495    /// Section 3.4.4.8
2496    ReadMultipleResponse = 0x0F,
2497    /// Section 3.4.4.9
2498    ReadByGroupTypeRequest = 0x10,
2499    /// Section 3.4.4.10
2500    ReadByGroupTypeResponse = 0x11,
2501    /// Section 3.4.5.1
2502    WriteRequest = 0x12,
2503    /// Section 3.4.5.2
2504    WriteResponse = 0x13,
2505    /// Section 3.4.5.3
2506    WriteCommand = 0x52,
2507    /// Section 3.4.5.4
2508    SignedWriteCommand = 0xD2,
2509    /// Section 3.4.6.1
2510    PrepareWriteRequest = 0x16,
2511    /// Section 3.4.6.2
2512    PrepareWriteResponse = 0x17,
2513    /// Section 3.4.6.3
2514    ExecuteWriteRequest = 0x18,
2515    /// Section 3.4.6.4
2516    ExecuteWriteResponse = 0x19,
2517    /// Section 3.4.7.1
2518    HandleValueNotification = 0x1B,
2519    /// Section 3.4.7.2
2520    HandleValueIndication = 0x1D,
2521    /// Section 3.4.7.3
2522    HandleValueConfirmation = 0x1E,
2523}
2524
2525impl TryFrom<u8> for AttRequest {
2526    type Error = VendorError;
2527
2528    fn try_from(value: u8) -> Result<Self, Self::Error> {
2529        match value {
2530            0x01 => Ok(AttRequest::ErrorResponse),
2531            0x02 => Ok(AttRequest::ExchangeMtuRequest),
2532            0x03 => Ok(AttRequest::ExchangeMtuResponse),
2533            0x04 => Ok(AttRequest::FindInformationRequest),
2534            0x05 => Ok(AttRequest::FindInformationResponse),
2535            0x06 => Ok(AttRequest::FindByTypeValueRequest),
2536            0x07 => Ok(AttRequest::FindByTypeValueResponse),
2537            0x08 => Ok(AttRequest::ReadByTypeRequest),
2538            0x09 => Ok(AttRequest::ReadByTypeResponse),
2539            0x0A => Ok(AttRequest::ReadRequest),
2540            0x0B => Ok(AttRequest::ReadResponse),
2541            0x0C => Ok(AttRequest::ReadBlobRequest),
2542            0x0D => Ok(AttRequest::ReadBlobResponse),
2543            0x0E => Ok(AttRequest::ReadMultipleRequest),
2544            0x0F => Ok(AttRequest::ReadMultipleResponse),
2545            0x10 => Ok(AttRequest::ReadByGroupTypeRequest),
2546            0x11 => Ok(AttRequest::ReadByGroupTypeResponse),
2547            0x12 => Ok(AttRequest::WriteRequest),
2548            0x13 => Ok(AttRequest::WriteResponse),
2549            0x52 => Ok(AttRequest::WriteCommand),
2550            0xD2 => Ok(AttRequest::SignedWriteCommand),
2551            0x16 => Ok(AttRequest::PrepareWriteRequest),
2552            0x17 => Ok(AttRequest::PrepareWriteResponse),
2553            0x18 => Ok(AttRequest::ExecuteWriteRequest),
2554            0x19 => Ok(AttRequest::ExecuteWriteResponse),
2555            0x1B => Ok(AttRequest::HandleValueNotification),
2556            0x1D => Ok(AttRequest::HandleValueIndication),
2557            0x1E => Ok(AttRequest::HandleValueConfirmation),
2558            _ => Err(VendorError::BadAttRequestOpcode(value)),
2559        }
2560    }
2561}
2562
2563fn to_att_error_response(buffer: &[u8]) -> Result<AttErrorResponse, crate::event::Error> {
2564    require_len!(buffer, 8);
2565    Ok(AttErrorResponse {
2566        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2567        request: buffer[4].try_into().map_err(crate::event::Error::Vendor)?,
2568        attribute_handle: AttributeHandle(LittleEndian::read_u16(&buffer[5..])),
2569        error: buffer[7]
2570            .try_into()
2571            .map_err(VendorError::BadAttError)
2572            .map_err(crate::event::Error::Vendor)?,
2573    })
2574}
2575
2576/// This event is given to the application when a read request or read blob request is received by
2577/// the server from the client. This event will be given to the application only if the event bit
2578/// for this event generation is set when the characteristic was added. On receiving this event, the
2579/// application can update the value of the handle if it desires and when done it has to use the
2580/// [`allow_read`](crate::vendor::command::gatt::GattCommands::allow_read) command to indicate to the stack that it can
2581/// send the response to the client.
2582///
2583/// See the Bluetooth Core v4.1 spec, Vol 3, Part F, section 3.4.4.
2584/// See STM AN5270, section 3.4.19
2585#[derive(Copy, Clone, Debug)]
2586#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2587pub struct AttReadPermitRequest {
2588    /// Handle of the connection on which there was the request to read the attribute
2589    pub conn_handle: ConnectionHandle,
2590
2591    /// The handle of the attribute that has been requested by the client to be read.
2592    pub attribute_handle: AttributeHandle,
2593
2594    /// Contains the offset from which the read has been requested.
2595    pub offset: usize,
2596}
2597
2598fn to_att_read_permit_request(buffer: &[u8]) -> Result<AttReadPermitRequest, crate::event::Error> {
2599    require_len!(buffer, 8);
2600    Ok(AttReadPermitRequest {
2601        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2602        attribute_handle: AttributeHandle(LittleEndian::read_u16(&buffer[4..])),
2603        offset: LittleEndian::read_u16(&buffer[6..]) as usize,
2604    })
2605}
2606
2607/// This event is given to the application when a read multiple request or read by type request is
2608/// received by the server from the client. This event will be given to the application only if the
2609/// event bit for this event generation is set when the characteristic was added.  On receiving this
2610/// event, the application can update the values of the handles if it desires and when done it has
2611/// to send the `gatt_allow_read` command to indicate to the stack that it can send the response to
2612/// the client.
2613///
2614/// See the Bluetooth Core v4.1 spec, Vol 3, Part F, section 3.4.4.
2615#[derive(Copy, Clone)]
2616#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2617pub struct AttReadMultiplePermitRequest {
2618    /// Handle of the connection which requested to read the attribute.
2619    pub conn_handle: ConnectionHandle,
2620
2621    /// Number of valid handles in handles_buf
2622    handles_len: usize,
2623    /// Attribute handles returned by the ATT Read Multiple Permit Request. Only the first
2624    /// `handles_len` handles are valid.
2625    handles_buf: [AttributeHandle; MAX_ATTRIBUTE_HANDLE_BUFFER_LEN],
2626}
2627
2628// The maximum number of handles in the buffer is the max HCI packet size (255) less the other data in
2629// the packet divided by the length of an attribute handle (2).
2630const MAX_ATTRIBUTE_HANDLE_BUFFER_LEN: usize = 125;
2631
2632impl Debug for AttReadMultiplePermitRequest {
2633    fn fmt(&self, f: &mut Formatter) -> FmtResult {
2634        write!(
2635            f,
2636            "{{.conn_handle = {:?}, .handles = {:?}",
2637            self.conn_handle,
2638            first_16(self.handles())
2639        )
2640    }
2641}
2642
2643impl AttReadMultiplePermitRequest {
2644    /// Returns the valid attribute handles returned by the ATT Read Multiple Permit Request event.
2645    pub fn handles(&self) -> &[AttributeHandle] {
2646        &self.handles_buf[..self.handles_len]
2647    }
2648}
2649
2650fn to_att_read_multiple_permit_request(
2651    buffer: &[u8],
2652) -> Result<AttReadMultiplePermitRequest, crate::event::Error> {
2653    require_len_at_least!(buffer, 5);
2654
2655    let data_len = buffer[4] as usize;
2656    if data_len % 2 != 0 {
2657        return Err(crate::event::Error::Vendor(
2658            VendorError::AttReadMultiplePermitRequestPartial,
2659        ));
2660    }
2661
2662    let handle_len = data_len / 2;
2663    let mut handles = [AttributeHandle(0); MAX_ATTRIBUTE_HANDLE_BUFFER_LEN];
2664    for (i, handle) in handles.iter_mut().enumerate().take(handle_len) {
2665        let index = 5 + 2 * i;
2666        *handle = AttributeHandle(LittleEndian::read_u16(&buffer[index..]));
2667    }
2668
2669    Ok(AttReadMultiplePermitRequest {
2670        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2671        handles_len: handle_len,
2672        handles_buf: handles,
2673    })
2674}
2675
2676/// This event is raised when the number of available TX buffers is above a threshold TH (TH = 2).
2677/// The event will be given only if a previous ACI command returned with
2678/// [`InsufficientResources`](AttError::InsufficientResources).
2679#[derive(Copy, Clone, Debug)]
2680#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2681pub struct GattTxPoolAvailable {
2682    /// Connection handle on which the GATT procedure is running.
2683    pub conn_handle: ConnectionHandle,
2684    /// Indicates the number of elements available in the attrTxPool List.
2685    pub available_buffers: usize,
2686}
2687
2688fn to_gatt_tx_pool_available(buffer: &[u8]) -> Result<GattTxPoolAvailable, crate::event::Error> {
2689    require_len!(buffer, 6);
2690    Ok(GattTxPoolAvailable {
2691        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2692        available_buffers: LittleEndian::read_u16(&buffer[4..]) as usize,
2693    })
2694}
2695
2696/// This event is given to the application when a prepare write request is received by the server
2697/// from the client.
2698///
2699/// This event will be given to the application only if the event bit for this event generation is
2700/// set when the characteristic was added.  When this event is received, the application has to
2701/// check whether the value being requested for write is allowed to be written and respond with the
2702/// command `gatt_write_response`.  Based on the response from the application, the attribute value
2703/// will be modified by the stack.  If the write is rejected by the application, then the value of
2704/// the attribute will not be modified and an error response will be sent to the client, with the
2705/// error code as specified by the application.
2706#[derive(Copy, Clone)]
2707#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2708pub struct AttPrepareWritePermitRequest {
2709    /// Connection handle on which the GATT procedure is running.
2710    pub conn_handle: ConnectionHandle,
2711    /// The handle of the attribute to be written.
2712    pub attribute_handle: AttributeHandle,
2713    /// The offset of the first octet to be written.
2714    pub offset: usize,
2715
2716    // Number of valid bytes in `value_buf`
2717    value_len: usize,
2718    // The data to be written. Only the first `value_len` bytes are valid.
2719    value_buf: [u8; MAX_PREPARE_WRITE_PERMIT_REQ_VALUE_LEN],
2720}
2721
2722// The maximum number of bytes in the buffer is the max HCI packet size (255) less the other data in
2723// the packet.
2724const MAX_PREPARE_WRITE_PERMIT_REQ_VALUE_LEN: usize = 246;
2725
2726impl Debug for AttPrepareWritePermitRequest {
2727    fn fmt(&self, f: &mut Formatter) -> FmtResult {
2728        write!(
2729            f,
2730            "{{.conn_handle = {:?}, .attribute_handle = {:?}, .offset = {:?}, .value = {:?}",
2731            self.conn_handle,
2732            self.attribute_handle,
2733            self.offset,
2734            first_16(self.value())
2735        )
2736    }
2737}
2738
2739impl AttPrepareWritePermitRequest {
2740    /// Returns the data to be written.
2741    pub fn value(&self) -> &[u8] {
2742        &self.value_buf[..self.value_len]
2743    }
2744}
2745
2746fn to_att_prepare_write_permit_request(
2747    buffer: &[u8],
2748) -> Result<AttPrepareWritePermitRequest, crate::event::Error> {
2749    require_len_at_least!(buffer, 9);
2750
2751    let data_len = buffer[8] as usize;
2752    require_len!(buffer, 9 + data_len);
2753
2754    let mut value_buf = [0; MAX_PREPARE_WRITE_PERMIT_REQ_VALUE_LEN];
2755    value_buf[..data_len].copy_from_slice(&buffer[9..]);
2756    Ok(AttPrepareWritePermitRequest {
2757        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2758        attribute_handle: AttributeHandle(LittleEndian::read_u16(&buffer[4..])),
2759        offset: LittleEndian::read_u16(&buffer[6..]) as usize,
2760        value_len: data_len,
2761        value_buf,
2762    })
2763}
2764
2765/// This event is sent only during SC Pairing, when Numeric Comparison
2766/// Association model is selected, in order to show the Numeric Value generated,
2767/// and to ask for Confirmation to the User. When this event is received, the
2768/// application has to respond with the
2769/// [numeric_comparison_value_confirm_yes_no](super::command::gap::GapCommands::numeric_comparison_value_confirm_yes_no)
2770/// command.
2771#[derive(Debug, Copy, Clone)]
2772#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2773pub struct GapNumericComparisonValue {
2774    /// Handle of the connection where this event occured
2775    pub connection_handle: ConnectionHandle,
2776    /// Generated numeric value
2777    pub numeric_value: u32,
2778}
2779
2780fn to_numeric_comparison_value(
2781    buffer: &[u8],
2782) -> Result<GapNumericComparisonValue, crate::event::Error> {
2783    require_len!(buffer, 8);
2784
2785    Ok(GapNumericComparisonValue {
2786        connection_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[2..])),
2787        numeric_value: LittleEndian::read_u32(&buffer[4..]),
2788    })
2789}
2790
2791#[derive(Debug, Copy, Clone)]
2792#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2793/// This event is sent only during SC Pairing, when Keypress Notifications are
2794/// supported, in order to show the input type signaled by the peer device,
2795/// having Keyboard only I/O capabilities. When this event is received, no
2796/// action is required to the User.
2797pub struct GapKeypressNotification {
2798    /// Handle of the connection where this event occured
2799    pub connection_handle: ConnectionHandle,
2800    /// Type of Keypress input notified/signaled by peer device
2801    /// (having Keyboard only I/O capabilities.
2802    pub notification_type: KeypressNotificationType,
2803}
2804
2805#[derive(Debug, Copy, Clone)]
2806#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2807/// Type of Keypress input notified/signaled by peer device
2808/// (having Keyboard only I/O capabilities.
2809pub enum KeypressNotificationType {
2810    EntryStarted = 0x00,
2811    DigitEntered = 0x01,
2812    DigitErased = 0x02,
2813    PasskeyCleared = 0x03,
2814    EntryCompleted = 0x04,
2815    Reserved,
2816}
2817
2818impl From<u8> for KeypressNotificationType {
2819    fn from(value: u8) -> Self {
2820        match value {
2821            0x00 => KeypressNotificationType::EntryStarted,
2822            0x01 => KeypressNotificationType::DigitEntered,
2823            0x02 => KeypressNotificationType::DigitErased,
2824            0x03 => KeypressNotificationType::PasskeyCleared,
2825            0x04 => KeypressNotificationType::EntryCompleted,
2826            _ => KeypressNotificationType::Reserved,
2827        }
2828    }
2829}
2830
2831fn to_keypress_notification(buffer: &[u8]) -> Result<GapKeypressNotification, crate::event::Error> {
2832    require_len!(buffer, 3);
2833
2834    Ok(GapKeypressNotification {
2835        connection_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
2836        notification_type: KeypressNotificationType::from(buffer[2]),
2837    })
2838}
2839
2840#[derive(Debug, Clone, Copy)]
2841#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2842/// This event is generated upon receipt of a valid Command Reject packet (e.g.
2843/// when the Central responds to the Connection Update Request packet with a
2844/// Command Reject packet).
2845pub struct L2CapCommandReject {
2846    /// Handle of the connection where this event occurred
2847    pub conn_handle: ConnectionHandle,
2848    /// This is the identifier which associate the request to the response.
2849    pub identifier: u8,
2850    /// Reason
2851    pub reason: u16,
2852    /// Data field associated with Reason
2853    pub data: [u8; 247],
2854}
2855
2856fn to_l2cap_command_reject(buffer: &[u8]) -> Result<L2CapCommandReject, crate::event::Error> {
2857    require_len_at_least!(buffer, 6);
2858
2859    let mut data = [0; 247];
2860    let len = buffer[5] as usize;
2861    data[..len].copy_from_slice(&buffer[6..(6 + len)]);
2862
2863    Ok(L2CapCommandReject {
2864        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
2865        identifier: buffer[2],
2866        reason: LittleEndian::read_u16(&buffer[3..]),
2867        data,
2868    })
2869}
2870
2871fn to_l2cap_coc_connect(buffer: &[u8]) -> Result<L2CapCocConnect, crate::event::Error> {
2872    require_len!(buffer, 10);
2873
2874    Ok(L2CapCocConnect {
2875        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
2876        spsm: LittleEndian::read_u16(&buffer[2..]),
2877        mtu: LittleEndian::read_u16(&buffer[4..]),
2878        mps: LittleEndian::read_u16(&buffer[6..]),
2879        initial_credits: LittleEndian::read_u16(&buffer[8..]),
2880        channel_number: buffer[10],
2881    })
2882}
2883
2884fn to_l2cap_coc_connect_confirm(
2885    buffer: &[u8],
2886) -> Result<L2CapCocConnectConfirm, crate::event::Error> {
2887    require_len!(buffer, 12);
2888
2889    let mut channel_index_list = [0; 246];
2890    let tmp = &buffer[7..];
2891    channel_index_list[..tmp.len()].copy_from_slice(tmp);
2892
2893    Ok(L2CapCocConnectConfirm {
2894        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
2895        mtu: LittleEndian::read_u16(&buffer[4..]),
2896        mps: LittleEndian::read_u16(&buffer[6..]),
2897        initial_credits: LittleEndian::read_u16(&buffer[8..]),
2898        result: LittleEndian::read_u16(&buffer[10..]),
2899        channel_number: buffer[12],
2900        channel_index_list,
2901    })
2902}
2903
2904fn to_l2cap_coc_reconfig(buffer: &[u8]) -> Result<L2CapCocReconfig, crate::event::Error> {
2905    require_len_at_least!(buffer, 8);
2906
2907    let mut channel_index_list = [0; 246];
2908    let tmp = &buffer[7..];
2909    channel_index_list[..tmp.len()].copy_from_slice(tmp);
2910
2911    Ok(L2CapCocReconfig {
2912        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
2913        mtu: LittleEndian::read_u16(&buffer[2..]),
2914        mps: LittleEndian::read_u16(&buffer[4..]),
2915        channel_number: buffer[6],
2916        channel_index_list,
2917    })
2918}
2919
2920fn to_l2cap_coc_reconfig_confirm(
2921    buffer: &[u8],
2922) -> Result<L2CapCocReconfigConfirm, crate::event::Error> {
2923    require_len_at_least!(buffer, 4);
2924
2925    Ok(L2CapCocReconfigConfirm {
2926        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
2927        result: LittleEndian::read_u16(&buffer[2..]),
2928    })
2929}
2930
2931fn to_l2cap_coc_flow_control(buffer: &[u8]) -> Result<L2CapCocFlowControl, crate::event::Error> {
2932    require_len!(buffer, 3);
2933
2934    Ok(L2CapCocFlowControl {
2935        channel_index: buffer[0],
2936        credits: LittleEndian::read_u16(&buffer[1..]),
2937    })
2938}
2939
2940#[derive(Debug, Clone, Copy)]
2941#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2942/// This event is generated when receiving a valid K-frame packet on a connection-oriented channel
2943///
2944/// See Bluetooth spec. v.5.4 [Vol 3, Part A].
2945///
2946/// # Note:
2947/// For the first K-frame of the SDU, the information data contains the L2CAP SDU length coded in
2948/// two octets followed by the K-frame information payload. For the next K-frames of the SDU, the
2949/// information data only contains the K-frame information payload.
2950pub struct L2CapCocRxData {
2951    /// Index of the connection-oriented channel for which the primitive applie.
2952    pub channel_index: u8,
2953    /// Length of the data (in octets)
2954    pub length: u16,
2955    /// Information data
2956    pub data: [u8; 250],
2957}
2958
2959fn to_l2cap_coc_rx_data(buffer: &[u8]) -> Result<L2CapCocRxData, crate::event::Error> {
2960    require_len_at_least!(buffer, 3);
2961
2962    let length = LittleEndian::read_u16(&buffer[1..]);
2963    let mut data = [0; 250];
2964    data[..length as usize].copy_from_slice(&buffer[3..]);
2965
2966    Ok(L2CapCocRxData {
2967        channel_index: buffer[0],
2968        length,
2969        data,
2970    })
2971}
2972#[derive(Debug, Clone, Copy)]
2973#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2974/// This event informs the application of a change in status of the Enhanced ATT
2975/// bearer handled by the specified L2CAP channel
2976pub struct GattEattBrearer {
2977    /// Index of the connection-oriented channel for which the primitive applies.
2978    pub channel_index: u8,
2979    /// Enhanced ATT bearer state.
2980    pub eab_state: EabState,
2981    /// Status error code
2982    pub status: GattProcedureStatus,
2983}
2984
2985#[derive(Debug, Clone, Copy)]
2986#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2987/// Enhanced ATT bearer state.
2988pub enum EabState {
2989    AttBearerCreated = 0x00,
2990    AttBearerTerminated = 0x01,
2991}
2992
2993impl TryFrom<u8> for EabState {
2994    type Error = crate::event::Error;
2995
2996    fn try_from(value: u8) -> Result<Self, Self::Error> {
2997        match value {
2998            0x00 => Ok(EabState::AttBearerCreated),
2999            0x01 => Ok(EabState::AttBearerTerminated),
3000            err => Err(crate::event::Error::Vendor(VendorError::BadEabState(err))),
3001        }
3002    }
3003}
3004
3005fn to_gatt_eatt_bearer(buffer: &[u8]) -> Result<GattEattBrearer, crate::event::Error> {
3006    require_len!(buffer, 3);
3007
3008    Ok(GattEattBrearer {
3009        channel_index: buffer[0],
3010        eab_state: EabState::try_from(buffer[1])?,
3011        status: GattProcedureStatus::try_from(buffer[2])?,
3012    })
3013}
3014
3015#[derive(Debug, Clone, Copy)]
3016#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3017/// This event is generated when a Multiple Handle Value Notification is received from the server.
3018pub struct GattMultiNotification {
3019    /// Specifies the ATT bearer for which the event
3020    pub conn_handle: ConnectionHandle,
3021    /// - Bits 14-0: offset in octets from which Attribute_Value data starts.
3022    /// - Bit 15 is used as flag: when set to 1 it indicates what more data are to come
3023    /// (fragmented event in case of long attribute data)
3024    pub offset: u16,
3025    /// Length of the data in bytes
3026    pub data_len: u16,
3027    /// List of "Handle Length Value" tuples as define in Bluetooth Core Specification
3028    pub data: [u8; 247],
3029}
3030
3031fn to_gatt_multi_notification(buffer: &[u8]) -> Result<GattMultiNotification, crate::event::Error> {
3032    require_len_at_least!(buffer, 6);
3033
3034    let data_len = LittleEndian::read_u16(&buffer[4..]);
3035    let mut data = [0; 247];
3036    data[..data_len as usize].copy_from_slice(&buffer[4..]);
3037
3038    Ok(GattMultiNotification {
3039        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
3040        offset: LittleEndian::read_u16(&buffer[2..]),
3041        data_len,
3042        data,
3043    })
3044}
3045
3046#[derive(Debug, Clone, Copy)]
3047#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3048/// Defines data returned by [GATT Read Ext](VendorEvent::GattReadExt) event
3049pub struct GattReadExt {
3050    /// The connection handle related to the event.
3051    pub conn_handle: ConnectionHandle,
3052    /// - Bits 14-0: offset in octets from which Attribute_Value data
3053    /// starts.
3054    /// - Bit 15 is used as flag: when set to 1 it indicates that more
3055    /// data are to come (fragmented event in case of long attribute data).
3056    pub offset: u16,
3057
3058    // Number of valid bytes in value_buf
3059    value_len: usize,
3060    // Current value of the attribute. Only the first value_len bytes are valid.
3061    value_buf: [u8; MAX_ATTRIBUTE_VALUE_LEN],
3062}
3063
3064fn to_gatt_read_ext(buffer: &[u8]) -> Result<GattReadExt, crate::event::Error> {
3065    require_len_at_least!(buffer, 6);
3066
3067    let value_len = LittleEndian::read_u16(&buffer[4..]) as usize;
3068    require_len!(buffer, 6 + value_len);
3069
3070    let mut value_buf = [0; MAX_ATTRIBUTE_VALUE_LEN];
3071    value_buf[..value_len].copy_from_slice(&buffer[6..]);
3072
3073    Ok(GattReadExt {
3074        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
3075        offset: LittleEndian::read_u16(&buffer[2..]),
3076        value_len,
3077        value_buf,
3078    })
3079}
3080
3081impl GattReadExt {
3082    pub fn value(&self) -> &[u8] {
3083        &self.value_buf[..self.value_len]
3084    }
3085}
3086
3087#[derive(Debug, Clone, Copy)]
3088#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3089/// Defines data returned by [GATT Indication Ext](VendorEvent::GattIndicationExt) or
3090/// [GATT Notification Ext](VendorEvent::GattNotificationExt) event
3091pub struct AttributeValueExt {
3092    /// The connection handle related to the event.
3093    pub conn_handle: ConnectionHandle,
3094    /// The handle of the attribute
3095    pub attribute_handle: AttributeHandle,
3096    /// - Bits 14-0: offset in octets from which Attribute_Value data
3097    /// starts.
3098    /// - Bit 15 is used as flag: when set to 1 it indicates that more
3099    /// data are to come (fragmented event in case of long attribute data).
3100    pub offset: u16,
3101
3102    // Number of valid bytes in value_buf
3103    value_len: usize,
3104    // Current value of the attribute. Only the first value_len bytes are valid.
3105    value_buf: [u8; MAX_ATTRIBUTE_VALUE_LEN],
3106}
3107
3108fn to_attribute_value_ext(buffer: &[u8]) -> Result<AttributeValueExt, crate::event::Error> {
3109    require_len_at_least!(buffer, 6);
3110
3111    let value_len = LittleEndian::read_u16(&buffer[6..]) as usize;
3112    require_len!(buffer, 8 + value_len);
3113
3114    let mut value_buf = [0; MAX_ATTRIBUTE_VALUE_LEN];
3115    value_buf[..value_len].copy_from_slice(&buffer[8..]);
3116
3117    Ok(AttributeValueExt {
3118        conn_handle: ConnectionHandle(LittleEndian::read_u16(&buffer[0..])),
3119        attribute_handle: AttributeHandle(LittleEndian::read_u16(&buffer[2..])),
3120        offset: LittleEndian::read_u16(&buffer[4..]),
3121        value_len,
3122        value_buf,
3123    })
3124}
3125
3126impl AttributeValueExt {
3127    pub fn value(&self) -> &[u8] {
3128        &self.value_buf[..self.value_len]
3129    }
3130}
3131
3132#[derive(Debug, Clone, Copy)]
3133#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3134/// Defines data returned by [HAL End Of Radio Activity](VendorEvent::HalEndOfRadioActivity) event
3135pub struct HalEndOfRadioActivity {
3136    /// Completed radio event
3137    pub last_state: RadioEvent,
3138    /// Incoming radio event
3139    pub next_state: RadioEvent,
3140    /// 32-bit absolute current time expressed in internal time units
3141    pub next_state_sys_time: u32,
3142    /// Slot number of completed radio events
3143    ///
3144    /// Values:
3145    /// - 0xFF: Idle
3146    /// - 0x00 .. 0x07
3147    pub last_state_slot: u8,
3148    /// Slot number of incoming radio events
3149    ///
3150    /// Values:
3151    /// - 0xFF: Idle
3152    /// - 0x00 .. 0x07
3153    pub next_state_slot: u8,
3154}
3155
3156#[derive(Debug, Clone, Copy)]
3157#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3158pub enum RadioEvent {
3159    Idle = 0x00,
3160    Advertising = 0x01,
3161    PeripheralConnection = 0x02,
3162    Scanning = 0x03,
3163    CentralConnection = 0x05,
3164    TxTestMode = 0x06,
3165    RxTestMode = 0x07,
3166}
3167
3168impl TryFrom<u8> for RadioEvent {
3169    type Error = crate::event::Error;
3170
3171    fn try_from(value: u8) -> Result<Self, Self::Error> {
3172        match value {
3173            0x00 => Ok(RadioEvent::Idle),
3174            0x01 => Ok(RadioEvent::Advertising),
3175            0x02 => Ok(RadioEvent::PeripheralConnection),
3176            0x03 => Ok(RadioEvent::Scanning),
3177            0x05 => Ok(RadioEvent::CentralConnection),
3178            0x06 => Ok(RadioEvent::TxTestMode),
3179            0x07 => Ok(RadioEvent::RxTestMode),
3180            x => Err(crate::event::Error::Vendor(VendorError::BadRadioEvent(x))),
3181        }
3182    }
3183}
3184
3185fn to_hal_end_of_radio_activity(
3186    buffer: &[u8],
3187) -> Result<HalEndOfRadioActivity, crate::event::Error> {
3188    require_len!(buffer, 7);
3189
3190    Ok(HalEndOfRadioActivity {
3191        last_state: RadioEvent::try_from(buffer[0])?,
3192        next_state: RadioEvent::try_from(buffer[1])?,
3193        next_state_sys_time: LittleEndian::read_u32(&buffer[2..]),
3194        last_state_slot: buffer[6],
3195        next_state_slot: buffer[7],
3196    })
3197}
3198
3199#[derive(Debug, Clone, Copy)]
3200#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3201/// Defines data returned by [HAL End Of Radio Activity](VendorEvent::HalEndOfRadioActivity) event
3202pub struct HalScanReqReport {
3203    /// RSSI (signed integer).
3204    ///
3205    /// Units: dBm
3206    ///
3207    /// Values:
3208    /// - 127: RSSI not available
3209    /// - -127 .. 20
3210    pub rssi: u8,
3211    /// Address of the peer device
3212    pub peer_addr: PeerAddrType,
3213}
3214
3215fn to_hal_scan_req_report(buffer: &[u8]) -> Result<HalScanReqReport, crate::event::Error> {
3216    require_len!(buffer, 8);
3217
3218    let mut addr = crate::BdAddr([0; 6]);
3219    addr.0.copy_from_slice(&buffer[2..]);
3220
3221    Ok(HalScanReqReport {
3222        rssi: buffer[0],
3223        peer_addr: match buffer[1] {
3224            0x00 => PeerAddrType::PublicDeviceAddress(addr),
3225            0x01 => PeerAddrType::RandomDeviceAddress(addr),
3226            0x02 => PeerAddrType::PublicDeviceAddress(addr),
3227            0x03 => PeerAddrType::RandomIdentityAddress(addr),
3228            x => return Err(crate::event::Error::Vendor(VendorError::BadBdAddrType(x))),
3229        },
3230    })
3231}
3232
3233#[derive(Debug, Clone, Copy)]
3234#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3235/// Defines data returned by [HAL Firmware Error](VendorEvent::HalFirmwareError) event
3236pub struct HalFirmwareError {
3237    /// Firmware error type
3238    pub fw_error_type: FirmwareError,
3239    /// Length of  data in octets
3240    data_len: u8,
3241    /// the error event info
3242    data: [u8; 251],
3243}
3244
3245#[derive(Debug, Clone, Copy)]
3246#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3247/// Defines error types returned by [HAL Firmware Error](VendorEvent::HalFirmwareError) event
3248pub enum FirmwareError {
3249    /// L2CAP recombination failure
3250    L2capRecombination = 0x01,
3251    /// GATT unexpected peer message
3252    GattUnexpectedPeerMsg = 0x02,
3253    /// NVM level warning
3254    NvmLevelWarning = 0x03,
3255    /// COC Rx data length too large
3256    CocRxDataTooLarge = 0x04,
3257}
3258
3259impl TryFrom<u8> for FirmwareError {
3260    type Error = crate::event::Error;
3261
3262    fn try_from(value: u8) -> Result<Self, Self::Error> {
3263        match value {
3264            0x01 => Ok(FirmwareError::L2capRecombination),
3265            0x02 => Ok(FirmwareError::GattUnexpectedPeerMsg),
3266            0x03 => Ok(FirmwareError::NvmLevelWarning),
3267            0x04 => Ok(FirmwareError::CocRxDataTooLarge),
3268            x => Err(crate::event::Error::Vendor(VendorError::BadFirmwareError(
3269                x,
3270            ))),
3271        }
3272    }
3273}
3274
3275impl HalFirmwareError {
3276    pub fn data(&self) -> &[u8] {
3277        &self.data[..self.data_len as usize]
3278    }
3279}
3280
3281fn to_hal_firmware_error(buffer: &[u8]) -> Result<HalFirmwareError, crate::event::Error> {
3282    require_len_at_least!(buffer, 2);
3283
3284    let data_len = buffer[1] as usize;
3285    let mut data = [0; 251];
3286    data[..data_len].copy_from_slice(&buffer[2..(2 + data_len)]);
3287
3288    Ok(HalFirmwareError {
3289        fw_error_type: FirmwareError::try_from(buffer[0])?,
3290        data_len: buffer[1],
3291        data,
3292    })
3293}