stm32wb_hci/vendor/command/
gatt.rs

1//! GATT commands and types needed for those commands.
2
3extern crate byteorder;
4
5use core::ops::Range;
6
7use byteorder::{ByteOrder, LittleEndian};
8
9use crate::{vendor::event::AttributeHandle, ConnectionHandle, Controller};
10
11/// GATT-specific.
12pub trait GattCommands {
13    /// Initialize the GATT server on the slave device. Initialize all the pools and active
14    /// nodes. Also it adds GATT service with service changed characteristic. Until this command is
15    /// issued the GATT channel will not process any commands even if the connection is opened. This
16    /// command has to be given before using any of the GAP features.
17    ///
18    /// # Errors
19    ///
20    /// Only underlying communication errors are reported.
21    ///
22    /// # Generated events
23    ///
24    /// A [Command Complete](crate::event::command::CommandComplete) event is generated.
25    async fn init(&mut self);
26
27    /// Initialize the GATT server on a slave device.
28    ///
29    /// This function exists to prevent name conflicts with other Commands traits' init methods.
30    async fn init_gatt(&mut self) {
31        self.init().await
32    }
33
34    /// Add a service to GATT Server.
35    ///
36    /// When a service is created in the server, the host needs to reserve the handle ranges for
37    /// this service using [`max_attribute_records`](AddServiceParameters::max_attribute_records).
38    /// This parameter specifies the maximum number of attribute records that can be added to this
39    /// service (including the service attribute, include attribute, characteristic attribute,
40    /// characteristic value attribute and characteristic descriptor attribute). Handle of the
41    /// created service is returned in command complete event.
42    ///
43    /// # Errors
44    ///
45    /// Only underlying communication errors are reported.
46    ///
47    /// # Generated events
48    ///
49    /// A [Command complete](crate::event::command::CommandComplete) event is
50    /// generated.
51    async fn add_service(&mut self, params: &AddServiceParameters);
52
53    /// Include a service to another service.
54    ///
55    /// Attribute server creates an INCLUDE definition attribute.
56    ///
57    /// # Errors
58    ///
59    /// Only underlying communication errors are reported.
60    ///
61    /// # Generated events
62    ///
63    /// A [Command complete](crate::event::command::CommandComplete) event is
64    /// generated.
65    async fn include_service(&mut self, params: &IncludeServiceParameters);
66
67    /// Add a characteristic to a service.
68    ///
69    /// # Errors
70    ///
71    /// Only underlying communication errors are reported.
72    ///
73    /// # Generated events
74    ///
75    /// When the command is completed, a
76    /// [command complete](crate::event::command::CommandComplete) event will be
77    /// generated by the controller which carries the status of the command and the handle of the
78    /// characteristic as parameters.
79    async fn add_characteristic(&mut self, params: &AddCharacteristicParameters);
80
81    /// Add a characteristic descriptor to a service.
82    ///
83    /// # Errors
84    ///
85    /// - [DescriptorTooLong](Error::DescriptorTooLong) if the
86    ///   [descriptor value](AddDescriptorParameters::descriptor_value) is longer than the
87    ///   [maximum descriptor value length](AddDescriptorParameters::descriptor_value_max_len).
88    /// - [DescriptorBufferTooLong](Error::DescriptorBufferTooLong) if the
89    ///   [descriptor value maximum length](AddDescriptorParameters::descriptor_value_max_len) is so large that
90    ///   the serialized structure may be more than 255 bytes. The maximum size is 227.
91    /// - Underlying communication errors.
92    ///
93    /// # Generated events
94    ///
95    /// When this command is completed, a [command complete](crate::event::command::CommandComplete) event
96    /// will be generated by the controller which carries the status of the command and the handle
97    /// of the characteristic descriptor.
98    async fn add_characteristic_descriptor(
99        &mut self,
100        params: &AddDescriptorParameters<'_>,
101    ) -> Result<(), Error>;
102
103    /// Update a characteristic value in a service.
104    ///
105    /// # Errors
106    ///
107    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the
108    ///   [characteristic value](UpdateCharacteristicValueParameters::value] is so long that the command packet
109    ///   would exceed 255 bytes. The maximum allowed length is 249 bytes.
110    /// - Underlying communication errors.
111    ///
112    /// # Generated events
113    ///
114    /// When the command has completed, the controller will generate a
115    /// [command complete](crate::event::command::CommandComplete) event.
116    async fn update_characteristic_value(
117        &mut self,
118        params: &UpdateCharacteristicValueParameters<'_>,
119    ) -> Result<(), Error>;
120
121    /// Delete the characteristic specified from the service.
122    ///
123    /// # Errors
124    ///
125    /// Only underlying communication errors are reported.
126    ///
127    /// # Generated events
128    ///
129    /// When the command has completed, the controller will generate a
130    /// [command complete](crate::event::command::CommandComplete) event.
131    async fn delete_characteristic(
132        &mut self,
133        service: AttributeHandle,
134        characteristic: AttributeHandle,
135    );
136
137    /// Delete the service specified from the GATT server database.
138    ///
139    /// # Errors
140    ///
141    /// Only underlying communication errors are reported.
142    ///
143    /// # Generated events
144    ///
145    /// When the command has completed, the controller will generate a
146    /// [command complete](crate::event::command::CommandComplete) event.
147    async fn delete_service(&mut self, service: AttributeHandle);
148
149    /// Delete the Include definition from the service.
150    ///
151    /// # Errors
152    ///
153    /// Only underlying communication errors are reported.
154    ///
155    /// # Generated events
156    ///
157    /// When the command has completed, the controller will generate a
158    /// [command complete](crate::event::command::CommandComplete) event.
159    async fn delete_included_service(&mut self, params: &DeleteIncludedServiceParameters);
160
161    /// Allows masking events from the GATT.
162    ///
163    /// The default configuration is all the events masked.
164    ///
165    /// # Errors
166    ///
167    /// Only underlying communication errors are reported.
168    ///
169    /// # Generated events
170    ///
171    /// A [command complete](crate::event::command::CommandComplete) event is
172    /// generated on the completion of the command.
173    async fn set_event_mask(&mut self, mask: Event);
174
175    /// Allows masking events from the GATT.
176    ///
177    /// This function exists to prevent name conflicts with other Commands traits' set_event_mask
178    /// methods.
179    async fn set_gatt_event_mask(&mut self, mask: Event) {
180        self.set_event_mask(mask).await
181    }
182
183    /// Perform an ATT MTU exchange.
184    ///
185    /// # Errors
186    ///
187    /// Only underlying communication errors are reported.
188    ///
189    /// # Generated events
190    ///
191    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
192    /// the command. When the ATT MTU exchange procedure is completed, an
193    /// [Exchange MTU Response](crate::vendor::event::VendorEvent::AttExchangeMtuResponse) event is generated. Also, a
194    /// [procedure complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event is generated
195    /// to indicate end of procedure.
196    async fn exchange_configuration(&mut self, conn_handle: crate::ConnectionHandle);
197
198    /// Post the Find information request.
199    ///
200    /// # Errors
201    ///
202    /// Only underlying communication errors are reported.
203    ///
204    /// # Generated events
205    ///
206    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
207    /// the command. The responses of the procedure are given through the
208    /// [Find Information Response](crate::vendor::event::VendorEvent::AttFindInformationResponse) event. The end of the
209    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
210    async fn find_information_request(
211        &mut self,
212        conn_handle: crate::ConnectionHandle,
213        attribute_range: Range<AttributeHandle>,
214    );
215
216    /// Post the Find by type value request.
217    ///
218    /// # Errors
219    ///
220    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the
221    ///   [attribute value](FindByTypeValueParameters::value) to find is too long to fit in one command packet
222    ///   (255 bytes). The maximum length is 246 bytes.
223    /// - Underlying communication errors.
224    ///
225    /// # Generated events
226    ///
227    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
228    /// the command. The responses of the procedure are given through the
229    /// [Find by Type Value Response](crate::vendor::event::VendorEvent::AttFindByTypeValueResponse) event. The end of the
230    /// procedure is indicated by a [Gatt Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
231    async fn find_by_type_value_request(
232        &mut self,
233        params: &FindByTypeValueParameters,
234    ) -> Result<(), Error>;
235
236    /// Send a Read By Type Request.
237    ///
238    /// # Errors
239    ///
240    /// Only underlying communication errors are reported.
241    ///
242    /// # Generated events
243    ///
244    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
245    /// the command. The responses of the procedure are given through the
246    /// [Read by Type Response](crate::vendor::event::VendorEvent::AttReadByTypeResponse) event. The end of the procedure
247    /// is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
248    async fn read_by_type_request(&mut self, params: &ReadByTypeParameters);
249
250    /// Sends a Read By Group Type request.
251    ///
252    /// The Read By Group Type Request is used to obtain the values of grouping attributes where the
253    /// attribute type is known but the handle is not known. Grouping attributes are defined at GATT
254    /// layer. The grouping attribute types are: Primary Service, Secondary Service and
255    /// Characteristic.
256    ///
257    /// # Errors
258    ///
259    /// Only underlying communication errors are reported.
260    ///
261    /// # Generated events
262    ///
263    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
264    /// the command. The responses of the procedure are given through the
265    /// [Read by Group Type Response](crate::vendor::event::VendorEvent::AttReadByGroupTypeResponse) event. The end of the
266    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
267    async fn read_by_group_type_request(&mut self, params: &ReadByTypeParameters);
268
269    /// Sends a Prepare Write request.
270    ///
271    /// # Errors
272    ///
273    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the attribute value is so long that the
274    ///   serialized command would be longer than 255 bytes. The maximum length is 248 bytes.
275    /// - Underlying comminication errors
276    ///
277    /// # Generated events
278    ///
279    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
280    /// the command. The responses of the procedure are given through the
281    /// [Prepare Write Response](crate::vendor::event::VendorEvent::AttPrepareWriteResponse) event. The end of the
282    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
283    async fn prepare_write_request(&mut self, params: &WriteRequest<'_>) -> Result<(), Error>;
284
285    /// Sends an Execute Write Request to write all pending prepared writes.
286    ///
287    /// # Errors
288    ///
289    /// Only underlying communication errors are reported.
290    ///
291    /// # Generated events
292    ///
293    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
294    /// the command. The result of the procedure is given through the
295    /// [Execute Write Response](crate::vendor::event::VendorEvent::AttExecuteWriteResponse) event. The end of the
296    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
297    async fn execute_write_request(&mut self, conn_handle: crate::ConnectionHandle);
298
299    /// Sends an Execute Write Request to discard prepared writes.
300    ///
301    /// # Errors
302    ///
303    /// Only underlying communication errors are reported.
304    ///
305    /// # Generated events
306    ///
307    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
308    /// the command. The result of the procedure is given through the
309    /// [Execute Write Response](crate::vendor::event::VendorEvent::AttExecuteWriteResponse) event. The end of the
310    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
311    async fn cancel_write_request(&mut self, conn_handle: crate::ConnectionHandle);
312
313    /// This command will start the GATT client procedure to discover all primary services on the
314    /// server.
315    ///
316    /// # Errors
317    ///
318    /// Only underlying communication errors are reported.
319    ///
320    /// # Generated events
321    ///
322    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
323    /// the command. The responses of the procedure are given through the
324    /// [Read By Group Response](crate::vendor::event::VendorEvent::AttReadByGroupTypeResponse) event. The end of the
325    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
326    async fn discover_all_primary_services(&mut self, conn_handle: crate::ConnectionHandle);
327
328    /// This command will start the procedure to discover the primary services of the specified
329    /// UUID on the server.
330    ///
331    /// # Errors
332    ///
333    /// Only underlying communication errors are reported.
334    ///
335    /// # Generated events
336    ///
337    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
338    /// the command. The responses of the procedure are given through the
339    /// [Find By Type Value Response](crate::vendor::event::VendorEvent::AttFindByTypeValueResponse) event. The end of the
340    /// procedure is indicated by a [Gatt Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
341    async fn discover_primary_services_by_uuid(
342        &mut self,
343        conn_handle: crate::ConnectionHandle,
344        uuid: Uuid,
345    );
346
347    /// Start the procedure to find all included services.
348    ///
349    /// # Errors
350    ///
351    /// Only underlying communication errors are reported.
352    ///
353    /// # Generated events
354    ///
355    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
356    /// the command. The responses of the procedure are given through the
357    /// [Read By Type Response](crate::vendor::event::VendorEvent::AttReadByTypeResponse) event. The end of the procedure
358    /// is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
359    async fn find_included_services(
360        &mut self,
361        conn_handle: crate::ConnectionHandle,
362        service_handle_range: Range<AttributeHandle>,
363    );
364
365    /// Start the procedure to discover all the characteristics of a given service.
366    ///
367    /// # Errors
368    ///
369    /// Only underlying communication errors are reported.
370    ///
371    /// # Generated events
372    ///
373    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
374    /// the command. The responses of the procedure are given through the
375    /// [Read By Type Response](crate::vendor::event::VendorEvent::AttReadByTypeResponse) event. The end of the procedure
376    /// is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
377    async fn discover_all_characteristics_of_service(
378        &mut self,
379        conn_handle: crate::ConnectionHandle,
380        attribute_handle_range: Range<AttributeHandle>,
381    );
382
383    /// Start the procedure to discover all the characteristics specified by the UUID.
384    ///
385    /// # Errors
386    ///
387    /// Only underlying communication errors are reported.
388    ///
389    /// # Generated events
390    ///
391    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
392    /// the command. The responses of the procedure are given through the
393    /// [Discover or Read Characteristic By UUID](crate::vendor::event::VendorEvent::GattDiscoverOrReadCharacteristicByUuidResponse)
394    /// event. The end of the procedure is indicated by a
395    /// [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
396    async fn discover_characteristics_by_uuid(
397        &mut self,
398        conn_handle: crate::ConnectionHandle,
399        attribute_handle_range: Range<AttributeHandle>,
400        uuid: Uuid,
401    );
402
403    /// Start the procedure to discover all characteristic descriptors on the server.
404    ///
405    /// # Errors
406    ///
407    /// Only underlying communication errors are reported.
408    ///
409    /// # Generated events
410    ///
411    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
412    /// the command. The responses of the procedure are given through the
413    /// [Find Information Response](crate::vendor::event::VendorEvent::AttFindInformationResponse) event. The end of the
414    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
415    async fn discover_all_characteristic_descriptors(
416        &mut self,
417        conn_handle: crate::ConnectionHandle,
418        characteristic_handle_range: Range<AttributeHandle>,
419    );
420
421    /// Start the procedure to read the attribute value.
422    ///
423    /// # Errors
424    ///
425    /// Only underlying communication errors are reported.
426    ///
427    /// # Generated events
428    ///
429    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
430    /// the command. The responses of the procedure are given through the
431    /// [Read Response](crate::vendor::event::VendorEvent::AttReadResponse) event. The end of the procedure is
432    /// indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete)
433    /// event.
434    async fn read_characteristic_value(
435        &mut self,
436        conn_handle: crate::ConnectionHandle,
437        characteristic_handle: AttributeHandle,
438    );
439
440    /// Start the procedure to read all the characteristics specified by the UUID.
441    ///
442    /// # Errors
443    ///
444    /// Only underlying communication errors are reported.
445    ///
446    /// # Generated events
447    ///
448    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
449    /// the command. The responses of the procedure are given through the
450    /// [Discover or Read Characteristic by UUID](crate::vendor::event::VendorEvent::GattDiscoverOrReadCharacteristicByUuidResponse)
451    /// event. The end of the procedure is indicated by a
452    /// [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
453    async fn read_characteristic_using_uuid(
454        &mut self,
455        conn_handle: crate::ConnectionHandle,
456        characteristic_handle_range: Range<AttributeHandle>,
457        uuid: Uuid,
458    );
459
460    /// Start the procedure to read a long characteristic value.
461    ///
462    /// # Errors
463    ///
464    /// Only underlying communication errors are reported.
465    ///
466    /// # Generated events
467    ///
468    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
469    /// the command. The responses of the procedure are given through the
470    /// [Read Blob Response](crate::vendor::event::VendorEvent::AttReadBlobResponse) event. The end of the procedure
471    /// is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
472    async fn read_long_characteristic_value(&mut self, params: &LongCharacteristicReadParameters);
473
474    /// Start a procedure to read multiple characteristic values from a server.
475    ///
476    /// This sub-procedure is used to read multiple Characteristic Values from a server when the
477    /// client knows the Characteristic Value Handles.
478    ///
479    /// # Errors
480    ///
481    /// - [TooManyHandlesToRead](Error::TooManyHandlesToRead) if the number of handles to read would
482    ///   cause the length of the serialized command to exceed 255 bytes. The maximum number of
483    ///   handles is 126.
484    /// - Underlying communication errors are reported.
485    ///
486    /// # Generated events
487    ///
488    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
489    /// the command. The responses of the procedure are given through the
490    /// [Read Multiple Response](crate::vendor::event::VendorEvent::AttReadMultipleResponse) event. The end of the
491    /// procedure is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
492    async fn read_multiple_characteristic_values(
493        &mut self,
494        params: &MultipleCharacteristicReadParameters<'_>,
495    ) -> Result<(), Error>;
496
497    /// Start the procedure to write a characteristic value.
498    ///
499    /// # Errors
500    ///
501    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the [value](CharacteristicValue::value)
502    ///   is too long to fit in one command packet. The maximum length is 250 bytes.
503    /// - Underlying communication errors are reported.
504    ///
505    /// # Generated events
506    ///
507    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
508    /// the command. When the procedure is completed, a
509    /// [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event is generated.
510    async fn write_characteristic_value(
511        &mut self,
512        params: &CharacteristicValue<'_>,
513    ) -> Result<(), Error>;
514
515    /// Start the procedure to write a long characteristic value.
516    ///
517    /// # Errors
518    ///
519    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the
520    ///   [value](LongCharacteristicValue::value) is too long to fit in one command packet. The
521    ///   maximum length is 248 bytes.
522    /// - Underlying communication errors are reported.
523    ///
524    /// # Generated events
525    ///
526    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
527    /// the command. The responses of the procedure are given through the
528    /// [Prepare Write Response](crate::vendor::event::VendorEvent::AttPrepareWriteResponse) and
529    /// [Execute Write Response](crate::vendor::event::VendorEvent::AttExecuteWriteResponse) events. When the procedure is
530    /// completed, a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete)
531    /// event is generated.
532    async fn write_long_characteristic_value(
533        &mut self,
534        params: &LongCharacteristicValue<'_>,
535    ) -> Result<(), Error>;
536
537    /// Start the procedure to write a characteristic reliably.
538    ///
539    /// # Errors
540    ///
541    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the
542    ///   [value](LongCharacteristicValue::value) is too long to fit in one command packet. The
543    ///   maximum length is 248 bytes.
544    /// - Underlying communication errors are reported.
545    ///
546    /// # Generated events
547    ///
548    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
549    /// the command. The responses of the procedure are given through the
550    /// [Prepare Write Response](crate::vendor::event::VendorEvent::AttPrepareWriteResponse) and
551    /// [Execute Write Response](crate::vendor::event::VendorEvent::AttExecuteWriteResponse) events. When the procedure is
552    /// completed, a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete)
553    /// event is generated.
554    async fn write_characteristic_value_reliably(
555        &mut self,
556        params: &LongCharacteristicValue<'_>,
557    ) -> Result<(), Error>;
558
559    /// Start the procedure to write a long characteristic descriptor.
560    ///
561    /// # Errors
562    ///
563    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the
564    ///   [value](LongCharacteristicValue::value) is too long to fit in one command packet. The
565    ///   maximum length is 248 bytes.
566    /// - Underlying communication errors are reported.
567    ///
568    /// # Generated events
569    ///
570    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
571    /// the command. The responses of the procedure are given through the
572    /// [Prepare Write Response](crate::vendor::event::VendorEvent::AttPrepareWriteResponse) and
573    /// [Execute Write Response](crate::vendor::event::VendorEvent::AttExecuteWriteResponse) events. When the procedure is
574    /// completed, a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete)
575    /// event is generated.
576    async fn write_long_characteristic_descriptor(
577        &mut self,
578        params: &LongCharacteristicValue<'_>,
579    ) -> Result<(), Error>;
580
581    /// Start the procedure to read a long characteristic descriptor.
582    ///
583    /// # Errors
584    ///
585    /// Only underlying communication errors are reported.
586    ///
587    /// # Generated events
588    ///
589    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
590    /// the command. The responses of the procedure are given through the
591    /// [Read Blob Response](crate::vendor::event::VendorEvent::AttReadBlobResponse) event. The end of the procedure
592    /// is indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event.
593    async fn read_long_characteristic_descriptor(
594        &mut self,
595        params: &LongCharacteristicReadParameters,
596    );
597
598    /// Start the procedure to write a characteristic descriptor value.
599    ///
600    /// # Errors
601    ///
602    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the [value](CharacteristicValue::value)
603    ///   is too long to fit in one command packet. The maximum length is 250 bytes.
604    /// - Underlying communication errors are reported.
605    ///
606    /// # Generated events
607    ///
608    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
609    /// the command. When the procedure is completed, a
610    /// [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete) event is generated.
611    async fn write_characteristic_descriptor(
612        &mut self,
613        params: &CharacteristicValue<'_>,
614    ) -> Result<(), Error>;
615
616    /// Start the procedure to read a characteristic descriptor.
617    ///
618    /// # Errors
619    ///
620    /// Only underlying communication errors are reported.
621    ///
622    /// # Generated events
623    ///
624    /// A [command status](crate::event::Event::CommandStatus) event is generated on the receipt of
625    /// the command. The responses of the procedure are given through the
626    /// [Read Response](crate::vendor::event::VendorEvent::AttReadResponse) event. The end of the procedure is
627    /// indicated by a [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete)
628    /// event.
629    async fn read_characteristic_descriptor(
630        &mut self,
631        conn_handle: crate::ConnectionHandle,
632        characteristic_handle: AttributeHandle,
633    );
634
635    /// Start the procedure to write a characteristic value without waiting for any response from
636    /// the server.
637    ///
638    /// # Errors
639    ///
640    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the [value](CharacteristicValue::value)
641    ///   is too long to fit in one command packet. The maximum length is 250 bytes.
642    /// - Underlying communication errors are reported.
643    ///
644    /// # Generated events
645    ///
646    /// A [command complete](crate::event::command::CommandComplete)
647    /// event is generated when this command is processed.
648    async fn write_without_response(
649        &mut self,
650        params: &CharacteristicValue<'_>,
651    ) -> Result<(), Error>;
652
653    /// Start the procedure to write a characteristic value with an authentication signature without
654    /// waiting for any response from the server. It cannot be used when the link is encrypted.
655    ///
656    /// # Errors
657    ///
658    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the [value](CharacteristicValue::value)
659    ///   is too long to fit in one command packet. The maximum length is 250 bytes.
660    /// - Underlying communication errors are reported.
661    ///
662    /// # Generated events
663    ///
664    /// A [command complete](crate::event::command::CommandComplete) event is
665    /// generated when this command is processed.
666    async fn signed_write_without_response(
667        &mut self,
668        params: &CharacteristicValue<'_>,
669    ) -> Result<(), Error>;
670
671    /// Allow application to confirm indication. This command has to be sent when the application
672    /// receives the [GATT Indication](crate::vendor::event::VendorEvent::GattIndication) event.
673    ///
674    /// # Errors
675    ///
676    /// Only underlying communication errors are reported.
677    ///
678    /// # Generated events
679    ///
680    /// A [command complete](crate::event::command::CommandComplete) event
681    /// is generated when this command is processed.
682    async fn confirm_indication(&mut self, conn_handle: crate::ConnectionHandle);
683
684    /// Allows or rejects a write request from a client.
685    ///
686    /// This command has to be sent by the application when it receives the
687    /// [GATT Write Permit Request](crate::vendor::event::VendorEvent::AttWritePermitRequest) event.
688    ///
689    /// # Errors
690    ///
691    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the
692    ///   [attribute value](WriteResponseParameters::value) is so long that the serialized command cannot fit
693    ///   in one packet. The maximum length is 250 bytes.
694    /// - Underlying communication errors are reported.
695    ///
696    /// # Generated events
697    ///
698    /// A [command complete](crate::event::command::CommandComplete) event is
699    /// generated when this command is processed.
700    async fn write_response(&mut self, params: &WriteResponseParameters<'_>) -> Result<(), Error>;
701
702    /// Allows the GATT server to send a response to a read request from a client.
703    ///
704    /// The application has to send this command when it receives the
705    /// [Read Permit Request](crate::vendor::event::VendorEvent::AttReadPermitRequest) or
706    /// [Read Multiple Permit Request](crate::vendor::event::VendorEvent::AttReadMultiplePermitRequest).
707    /// This command indicates to the stack that the response can be sent to the client. So if the application wishes to
708    /// update any of the attributes before they are read by the client, it has to update the
709    /// characteristic values using the
710    /// [`update_characteristic_value`](GattCommands::update_characteristic_value) and then give this
711    /// command. The application should perform the required operations within 30 seconds.
712    /// Otherwise the GATT procedure will timeout.
713    ///
714    /// # Errors
715    ///
716    /// Only underlying communication errors are reported.
717    ///
718    /// # Generated events
719    ///
720    /// A [command complete](crate::event::command::CommandComplete) event is
721    /// generated when this command is processed.
722    async fn allow_read(&mut self, conn_handle: crate::ConnectionHandle);
723
724    /// This command sets the security permission for the attribute handle specified. Currently the
725    /// setting of security permission is allowed only for client configuration descriptor.
726    ///
727    /// # Errors
728    ///
729    /// Only underlying communication errors are reported.
730    ///
731    /// # Generated events
732    ///
733    /// A [command complete](crate::event::command::CommandComplete)
734    /// event is generated when this command is processed.
735    async fn set_security_permission(&mut self, params: &SecurityPermissionParameters);
736
737    /// This command sets the value of a descriptor.
738    ///
739    /// # Errors
740    ///
741    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the length of the descriptor value is
742    ///   so long that the serialized command would not fit in one packet. The maximum length is 246
743    ///   bytes.
744    /// - Underlying communication errors are reported.
745    ///
746    /// # Generated events
747    ///
748    /// A [command complete](crate::event::command::CommandComplete) event
749    /// is generated when this command is processed.
750    async fn set_descriptor_value(
751        &mut self,
752        params: &DescriptorValueParameters<'_>,
753    ) -> Result<(), Error>;
754
755    /// The command returns the value of the attribute handle from the specified offset.
756    ///
757    /// If the length to be returned is greater than 128, then only 128 bytes are
758    /// [returned](crate::event::command::ReturnParameters::GattReadHandleValueOffset). The
759    /// application should send this command with incremented offsets until it gets an error with
760    /// the offset it specified or the number of byes of attribute value returned is less than 128.
761    ///
762    /// # Errors
763    ///
764    /// Only underlying communication errors are reported.
765    ///
766    /// # Generated events
767    ///
768    /// A [command complete](crate::event::command::CommandComplete)
769    /// event is generated when this command is processed.
770    async fn read_handle_value_offset(&mut self, handle: AttributeHandle, offset: usize);
771
772    /// This is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE tp support update of Long
773    /// attribute up to 512 bytes and indicate selectively the generation of Indication/Notification
774    ///
775    /// This command is an extension of the
776    /// [`update_characteristic_value`](GattCommands::update_characteristic_value) command and supports
777    /// updating of long attribute values (up to 512 bytes).
778    ///
779    /// # Errors
780    ///
781    /// - [ValueBufferTooLong](Error::ValueBufferTooLong) if the characteristic value is so long
782    ///   that the command would not fit in one packet. The maximum length is 245 bytes.
783    /// - Underlying communication errors are reported.
784    ///
785    /// # Generated events
786    ///
787    /// When the command has completed, the controller will generate a
788    /// [command complete](crate::event::command::CommandComplete) event.
789    async fn update_characteristic_value_ext(
790        &mut self,
791        params: &UpdateCharacteristicValueExt<'_>,
792    ) -> Result<(), Error>;
793
794    /// This command is used to deny the GATT server to send a response to a read request from a client.
795    ///
796    /// The application may send this command when it receives the
797    /// [ATT Read Permit Request](crate::vendor::event::VendorEvent::AttReadPermitRequest) or
798    /// [ATT Read Multiple Permit Request](crate::vendor::event::VendorEvent::AttReadMultiplePermitRequest).
799    ///
800    /// This command indicates to the stack that the client is not allowed to read the requested
801    /// characteristic due to e.g. application restrictions.
802    ///
803    /// The error code shall be either `0x08` (Insufficient Authorization) or a value in the range
804    /// `0x80 .. 0x9F` (Application Error).
805    ///
806    /// The application should issue the [GATT Allow Read](GattCommands::allow_read) or
807    /// [Gatt Deny Read](GattCommands::deny_read) command within 30 seconds from the receipt
808    /// of the [ATT Read Permit Request](crate::vendor::event::VendorEvent::AttReadPermitRequest) or the
809    /// [ATT Read Multiple Permit Request](crate::vendor::event::VendorEvent::AttReadMultiplePermitRequest)
810    /// events; otherwise the GATT procedure issues a timeout
811    async fn deny_read(&mut self, handle: ConnectionHandle, err: u8);
812
813    /// This command sets the access permission for the attribute handle specified.
814    async fn set_access_permission(
815        &mut self,
816        service: AttributeHandle,
817        attribute: AttributeHandle,
818        permissions: AccessPermission,
819    );
820
821    /// This command forces the saving of the GATT database for all active connections. Note that,
822    /// by default, the GATT database is saved per active connection at the time of disconnecting.
823    async fn store_database(&mut self);
824
825    /// This commad sends a Multiple Handle Value Notification over the ATT bearer specified in
826    /// parameter. The handles provided as parameters must be the handles of the characteristic
827    /// declarations.
828    async fn send_multiple_notification(
829        &mut self,
830        conn_handle: ConnectionHandle,
831        handles: &[AttributeHandle],
832    );
833
834    /// Starts a procedure to read multiple variable length characteristic values from a server;
835    ///
836    /// This command must specify the handles of the characteristic values to be read.
837    ///
838    /// When the procedure is completed, a
839    /// [GATT ProcedureComplete](crate::vendor::event::VendorEvent::GattProcedureComplete) event
840    /// is generated, Before procedure completion, the response packets are given through
841    /// [ATT Read Multiple Response](crate::vendor::event::VendorEvent::AttReadMultipleResponse)
842    /// event.
843    async fn read_multiple_variable_characteristic_value(
844        &mut self,
845        conn_handle: ConnectionHandle,
846        handles: &[AttributeHandle],
847    );
848}
849
850impl<T: Controller> GattCommands for T {
851    async fn init(&mut self) {
852        self.controller_write(crate::vendor::opcode::GATT_INIT, &[])
853            .await
854    }
855
856    impl_variable_length_params!(
857        add_service,
858        AddServiceParameters,
859        crate::vendor::opcode::GATT_ADD_SERVICE
860    );
861
862    impl_variable_length_params!(
863        include_service,
864        IncludeServiceParameters,
865        crate::vendor::opcode::GATT_INCLUDE_SERVICE
866    );
867
868    impl_variable_length_params!(
869        add_characteristic,
870        AddCharacteristicParameters,
871        crate::vendor::opcode::GATT_ADD_CHARACTERISTIC
872    );
873
874    impl_validate_variable_length_params!(
875        add_characteristic_descriptor<'a>,
876        AddDescriptorParameters<'a>,
877        crate::vendor::opcode::GATT_ADD_CHARACTERISTIC_DESCRIPTOR
878    );
879
880    impl_validate_variable_length_params!(
881        update_characteristic_value<'a>,
882        UpdateCharacteristicValueParameters<'a>,
883        crate::vendor::opcode::GATT_UPDATE_CHARACTERISTIC_VALUE
884    );
885
886    async fn delete_characteristic(
887        &mut self,
888        service: AttributeHandle,
889        characteristic: AttributeHandle,
890    ) {
891        let mut bytes = [0; 4];
892        LittleEndian::write_u16(&mut bytes[0..2], service.0);
893        LittleEndian::write_u16(&mut bytes[2..4], characteristic.0);
894
895        self.controller_write(crate::vendor::opcode::GATT_DELETE_CHARACTERISTIC, &bytes)
896            .await
897    }
898
899    async fn delete_service(&mut self, service: AttributeHandle) {
900        let mut bytes = [0; 2];
901        LittleEndian::write_u16(&mut bytes[0..2], service.0);
902
903        self.controller_write(crate::vendor::opcode::GATT_DELETE_SERVICE, &bytes)
904            .await
905    }
906
907    impl_params!(
908        delete_included_service,
909        DeleteIncludedServiceParameters,
910        crate::vendor::opcode::GATT_DELETE_INCLUDED_SERVICE
911    );
912
913    impl_value_params!(
914        set_event_mask,
915        Event,
916        crate::vendor::opcode::GATT_SET_EVENT_MASK
917    );
918
919    async fn exchange_configuration(&mut self, conn_handle: crate::ConnectionHandle) {
920        let mut bytes = [0; 2];
921        LittleEndian::write_u16(&mut bytes, conn_handle.0);
922
923        self.controller_write(crate::vendor::opcode::GATT_EXCHANGE_CONFIGURATION, &bytes)
924            .await
925    }
926
927    async fn find_information_request(
928        &mut self,
929        conn_handle: crate::ConnectionHandle,
930        attribute_range: Range<AttributeHandle>,
931    ) {
932        let mut bytes = [0; 6];
933        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
934        LittleEndian::write_u16(&mut bytes[2..4], attribute_range.start.0);
935        LittleEndian::write_u16(&mut bytes[4..6], attribute_range.end.0);
936
937        self.controller_write(crate::vendor::opcode::GATT_FIND_INFORMATION_REQUEST, &bytes)
938            .await
939    }
940
941    impl_validate_variable_length_params!(
942        find_by_type_value_request<'a>,
943        FindByTypeValueParameters<'a>,
944        crate::vendor::opcode::GATT_FIND_BY_TYPE_VALUE_REQUEST
945    );
946
947    impl_variable_length_params!(
948        read_by_type_request,
949        ReadByTypeParameters,
950        crate::vendor::opcode::GATT_READ_BY_TYPE_REQUEST
951    );
952
953    impl_variable_length_params!(
954        read_by_group_type_request,
955        ReadByTypeParameters,
956        crate::vendor::opcode::GATT_READ_BY_GROUP_TYPE_REQUEST
957    );
958
959    impl_validate_variable_length_params!(
960        prepare_write_request<'a>,
961        WriteRequest<'a>,
962        crate::vendor::opcode::GATT_PREPARE_WRITE_REQUEST
963    );
964
965    async fn execute_write_request(&mut self, conn_handle: crate::ConnectionHandle) {
966        let mut bytes = [0; 3];
967        LittleEndian::write_u16(&mut bytes, conn_handle.0);
968        bytes[2] = true as u8;
969
970        self.controller_write(crate::vendor::opcode::GATT_EXECUTE_WRITE_REQUEST, &bytes)
971            .await
972    }
973
974    async fn cancel_write_request(&mut self, conn_handle: crate::ConnectionHandle) {
975        let mut bytes = [0; 3];
976        LittleEndian::write_u16(&mut bytes, conn_handle.0);
977        bytes[2] = false as u8;
978
979        self.controller_write(crate::vendor::opcode::GATT_EXECUTE_WRITE_REQUEST, &bytes)
980            .await
981    }
982
983    async fn discover_all_primary_services(&mut self, conn_handle: crate::ConnectionHandle) {
984        let mut bytes = [0; 2];
985        LittleEndian::write_u16(&mut bytes, conn_handle.0);
986
987        self.controller_write(
988            crate::vendor::opcode::GATT_DISCOVER_ALL_PRIMARY_SERVICES,
989            &bytes,
990        )
991        .await
992    }
993
994    async fn discover_primary_services_by_uuid(
995        &mut self,
996        conn_handle: crate::ConnectionHandle,
997        uuid: Uuid,
998    ) {
999        let mut bytes = [0; 19];
1000        LittleEndian::write_u16(&mut bytes, conn_handle.0);
1001        let end = 2 + uuid.copy_into_slice(&mut bytes[2..]);
1002
1003        self.controller_write(
1004            crate::vendor::opcode::GATT_DISCOVER_PRIMARY_SERVICES_BY_UUID,
1005            &bytes[..end],
1006        )
1007        .await
1008    }
1009
1010    async fn find_included_services(
1011        &mut self,
1012        conn_handle: crate::ConnectionHandle,
1013        service_handle_range: Range<AttributeHandle>,
1014    ) {
1015        let mut bytes = [0; 6];
1016        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
1017        LittleEndian::write_u16(&mut bytes[2..4], service_handle_range.start.0);
1018        LittleEndian::write_u16(&mut bytes[4..6], service_handle_range.end.0);
1019
1020        self.controller_write(crate::vendor::opcode::GATT_FIND_INCLUDED_SERVICES, &bytes)
1021            .await
1022    }
1023
1024    async fn discover_all_characteristics_of_service(
1025        &mut self,
1026        conn_handle: crate::ConnectionHandle,
1027        attribute_handle_range: Range<AttributeHandle>,
1028    ) {
1029        let mut bytes = [0; 6];
1030        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
1031        LittleEndian::write_u16(&mut bytes[2..4], attribute_handle_range.start.0);
1032        LittleEndian::write_u16(&mut bytes[4..6], attribute_handle_range.end.0);
1033
1034        self.controller_write(
1035            crate::vendor::opcode::GATT_DISCOVER_ALL_CHARACTERISTICS_OF_SERVICE,
1036            &bytes,
1037        )
1038        .await
1039    }
1040
1041    async fn discover_characteristics_by_uuid(
1042        &mut self,
1043        conn_handle: crate::ConnectionHandle,
1044        attribute_handle_range: Range<AttributeHandle>,
1045        uuid: Uuid,
1046    ) {
1047        let mut bytes = [0; 23];
1048        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
1049        LittleEndian::write_u16(&mut bytes[2..4], attribute_handle_range.start.0);
1050        LittleEndian::write_u16(&mut bytes[4..6], attribute_handle_range.end.0);
1051        let uuid_len = uuid.copy_into_slice(&mut bytes[6..]);
1052
1053        self.controller_write(
1054            crate::vendor::opcode::GATT_DISCOVER_CHARACTERISTICS_BY_UUID,
1055            &bytes[..6 + uuid_len],
1056        )
1057        .await
1058    }
1059
1060    async fn discover_all_characteristic_descriptors(
1061        &mut self,
1062        conn_handle: crate::ConnectionHandle,
1063        characteristic_handle_range: Range<AttributeHandle>,
1064    ) {
1065        let mut bytes = [0; 6];
1066        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
1067        LittleEndian::write_u16(&mut bytes[2..4], characteristic_handle_range.start.0);
1068        LittleEndian::write_u16(&mut bytes[4..6], characteristic_handle_range.end.0);
1069
1070        self.controller_write(
1071            crate::vendor::opcode::GATT_DISCOVER_ALL_CHARACTERISTIC_DESCRIPTORS,
1072            &bytes,
1073        )
1074        .await
1075    }
1076
1077    async fn read_characteristic_value(
1078        &mut self,
1079        conn_handle: crate::ConnectionHandle,
1080        characteristic_handle: AttributeHandle,
1081    ) {
1082        let mut bytes = [0; 4];
1083        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
1084        LittleEndian::write_u16(&mut bytes[2..4], characteristic_handle.0);
1085
1086        self.controller_write(
1087            crate::vendor::opcode::GATT_READ_CHARACTERISTIC_VALUE,
1088            &bytes,
1089        )
1090        .await
1091    }
1092
1093    async fn read_characteristic_using_uuid(
1094        &mut self,
1095        conn_handle: crate::ConnectionHandle,
1096        characteristic_handle_range: Range<AttributeHandle>,
1097        uuid: Uuid,
1098    ) {
1099        let mut bytes = [0; 23];
1100        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
1101        LittleEndian::write_u16(&mut bytes[2..4], characteristic_handle_range.start.0);
1102        LittleEndian::write_u16(&mut bytes[4..6], characteristic_handle_range.end.0);
1103        let uuid_len = uuid.copy_into_slice(&mut bytes[6..]);
1104
1105        self.controller_write(
1106            crate::vendor::opcode::GATT_READ_CHARACTERISTIC_BY_UUID,
1107            &bytes[..6 + uuid_len],
1108        )
1109        .await
1110    }
1111
1112    impl_params!(
1113        read_long_characteristic_value,
1114        LongCharacteristicReadParameters,
1115        crate::vendor::opcode::GATT_READ_LONG_CHARACTERISTIC_VALUE
1116    );
1117
1118    impl_validate_variable_length_params!(
1119        read_multiple_characteristic_values<'a>,
1120        MultipleCharacteristicReadParameters<'a>,
1121        crate::vendor::opcode::GATT_READ_MULTIPLE_CHARACTERISTIC_VALUES
1122    );
1123
1124    impl_validate_variable_length_params!(
1125        write_characteristic_value<'a>,
1126        CharacteristicValue<'a>,
1127        crate::vendor::opcode::GATT_WRITE_CHARACTERISTIC_VALUE
1128    );
1129
1130    impl_validate_variable_length_params!(
1131        write_long_characteristic_value<'a>,
1132        LongCharacteristicValue<'a>,
1133        crate::vendor::opcode::GATT_WRITE_LONG_CHARACTERISTIC_VALUE
1134    );
1135
1136    impl_validate_variable_length_params!(
1137        write_characteristic_value_reliably<'a>,
1138        LongCharacteristicValue<'a>,
1139        crate::vendor::opcode::GATT_WRITE_CHARACTERISTIC_VALUE_RELIABLY
1140    );
1141
1142    impl_validate_variable_length_params!(
1143        write_long_characteristic_descriptor<'a>,
1144        LongCharacteristicValue<'a>,
1145        crate::vendor::opcode::GATT_WRITE_LONG_CHARACTERISTIC_DESCRIPTOR
1146    );
1147
1148    impl_params!(
1149        read_long_characteristic_descriptor,
1150        LongCharacteristicReadParameters,
1151        crate::vendor::opcode::GATT_READ_LONG_CHARACTERISTIC_DESCRIPTOR
1152    );
1153
1154    impl_validate_variable_length_params!(
1155        write_characteristic_descriptor<'a>,
1156        CharacteristicValue<'a>,
1157        crate::vendor::opcode::GATT_WRITE_CHARACTERISTIC_DESCRIPTOR
1158    );
1159
1160    async fn read_characteristic_descriptor(
1161        &mut self,
1162        conn_handle: crate::ConnectionHandle,
1163        characteristic_handle: AttributeHandle,
1164    ) {
1165        let mut bytes = [0; 4];
1166        LittleEndian::write_u16(&mut bytes[0..2], conn_handle.0);
1167        LittleEndian::write_u16(&mut bytes[2..4], characteristic_handle.0);
1168
1169        self.controller_write(
1170            crate::vendor::opcode::GATT_READ_CHARACTERISTIC_DESCRIPTOR,
1171            &bytes,
1172        )
1173        .await
1174    }
1175
1176    impl_validate_variable_length_params!(
1177        write_without_response<'a>,
1178        CharacteristicValue<'a>,
1179        crate::vendor::opcode::GATT_WRITE_WITHOUT_RESPONSE
1180    );
1181
1182    impl_validate_variable_length_params!(
1183        signed_write_without_response<'a>,
1184        CharacteristicValue<'a>,
1185        crate::vendor::opcode::GATT_SIGNED_WRITE_WITHOUT_RESPONSE
1186    );
1187
1188    async fn confirm_indication(&mut self, conn_handle: crate::ConnectionHandle) {
1189        let mut bytes = [0; 2];
1190        LittleEndian::write_u16(&mut bytes, conn_handle.0);
1191
1192        self.controller_write(crate::vendor::opcode::GATT_CONFIRM_INDICATION, &bytes)
1193            .await
1194    }
1195
1196    impl_validate_variable_length_params!(
1197        write_response<'a>,
1198        WriteResponseParameters<'a>,
1199        crate::vendor::opcode::GATT_WRITE_RESPONSE
1200    );
1201
1202    async fn allow_read(&mut self, conn_handle: crate::ConnectionHandle) {
1203        let mut bytes = [0; 2];
1204        LittleEndian::write_u16(&mut bytes, conn_handle.0);
1205
1206        self.controller_write(crate::vendor::opcode::GATT_ALLOW_READ, &bytes)
1207            .await
1208    }
1209
1210    impl_params!(
1211        set_security_permission,
1212        SecurityPermissionParameters,
1213        crate::vendor::opcode::GATT_SET_SECURITY_PERMISSION
1214    );
1215
1216    impl_validate_variable_length_params!(
1217        set_descriptor_value<'a>,
1218        DescriptorValueParameters<'a>,
1219        crate::vendor::opcode::GATT_SET_DESCRIPTOR_VALUE
1220    );
1221
1222    async fn read_handle_value_offset(&mut self, handle: AttributeHandle, offset: usize) {
1223        let mut bytes = [0; 3];
1224        LittleEndian::write_u16(&mut bytes, handle.0);
1225        bytes[2] = offset as u8;
1226
1227        self.controller_write(crate::vendor::opcode::GATT_READ_HANDLE_VALUE_OFFSET, &bytes)
1228            .await
1229    }
1230
1231    impl_validate_variable_length_params!(
1232        update_characteristic_value_ext<'a>,
1233        UpdateCharacteristicValueExt<'a>,
1234        crate::vendor::opcode::GATT_UPDATE_LONG_CHARACTERISTIC_VALUE
1235    );
1236
1237    async fn deny_read(&mut self, handle: ConnectionHandle, err: u8) {
1238        let mut payload = [0; 3];
1239        LittleEndian::write_u16(&mut payload[0..], handle.0);
1240        payload[2] = err;
1241        self.controller_write(crate::vendor::opcode::GATT_DENY_READ, &payload)
1242            .await;
1243    }
1244
1245    async fn set_access_permission(
1246        &mut self,
1247        service: AttributeHandle,
1248        attribute: AttributeHandle,
1249        permissions: AccessPermission,
1250    ) {
1251        let mut payload = [0; 5];
1252        LittleEndian::write_u16(&mut payload[0..], service.0);
1253        LittleEndian::write_u16(&mut payload[2..], attribute.0);
1254        payload[4] = permissions.bits();
1255        self.controller_write(crate::vendor::opcode::GATT_SET_ACCESS_PERMISSION, &payload)
1256            .await;
1257    }
1258
1259    async fn store_database(&mut self) {
1260        self.controller_write(crate::vendor::opcode::GATT_STORE_DB, &[])
1261            .await;
1262    }
1263
1264    async fn send_multiple_notification(
1265        &mut self,
1266        conn_handle: ConnectionHandle,
1267        handles: &[AttributeHandle],
1268    ) {
1269        let mut payload = [0; 255];
1270        LittleEndian::write_u16(&mut payload[0..], conn_handle.0);
1271        payload[1] = handles.len() as u8;
1272        for (idx, handle) in handles.iter().enumerate() {
1273            LittleEndian::write_u16(&mut payload[2 + (idx * 2)..], handle.0);
1274        }
1275        self.controller_write(
1276            crate::vendor::opcode::GATT_SEND_MULT_NOTIFICATION,
1277            &payload[..2 + (handles.len() * 2)],
1278        )
1279        .await;
1280    }
1281
1282    async fn read_multiple_variable_characteristic_value(
1283        &mut self,
1284        conn_handle: ConnectionHandle,
1285        handles: &[AttributeHandle],
1286    ) {
1287        let mut payload = [0; 255];
1288        LittleEndian::write_u16(&mut payload[0..], conn_handle.0);
1289        payload[1] = handles.len() as u8;
1290        for (idx, handle) in handles.iter().enumerate() {
1291            LittleEndian::write_u16(&mut payload[2 + (idx * 2)..], handle.0);
1292        }
1293
1294        self.controller_write(
1295            crate::vendor::opcode::GATT_READ_MULTIPLE_VAR_CHAR_VALUE,
1296            &payload[..2 + (handles.len() * 2)],
1297        )
1298        .await;
1299    }
1300}
1301
1302/// Potential errors from parameter validation.
1303///
1304/// Before some commands are sent to the controller, the parameters are validated. This type
1305/// enumerates the potential validation errors. Must be specialized on the types of communication
1306/// errors.
1307#[derive(Copy, Clone, Debug, PartialEq)]
1308#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1309pub enum Error {
1310    /// For the [Add Characteristic Descriptor](GattCommands::add_characteristic_descriptor) command:
1311    /// the [descriptor value](AddDescriptorParameters::descriptor_value) is longer than the
1312    /// [maximum descriptor value length](AddDescriptorParameters::descriptor_value_max_len).
1313    DescriptorTooLong,
1314
1315    /// For the [Add Characteristic Descriptor](GattCommands::add_characteristic_descriptor) command:
1316    /// the [descriptor value maximum length](AddDescriptorParameters::descriptor_value_max_len) is
1317    /// so large that the serialized structure may be more than 255 bytes. The maximum size is 227.
1318    DescriptorBufferTooLong,
1319
1320    /// For the [Update Characteristir Value](GattCommands::update_characteristic_value) command: the
1321    /// length of the [characteristic value](UpdateCharacteristicValueParameters::value) is so large
1322    /// that the serialized structure would be more than 255 bytes. The maximum size is 249.
1323    ValueBufferTooLong,
1324
1325    /// For the [Read Multiple Characteristic Values](GattCommands::read_multiple_characteristic_values)
1326    /// command: the number of [handles](MultipleCharacteristicReadParameters::handles) would cause
1327    /// the serialized command to be more than 255 bytes. The maximum length is 126 handles.
1328    TooManyHandlesToRead,
1329}
1330
1331/// Parameters for the [GATT Add Service](GattCommands::add_service) command.
1332pub struct AddServiceParameters {
1333    /// UUID of the service
1334    pub uuid: Uuid,
1335
1336    /// Type of service
1337    pub service_type: ServiceType,
1338
1339    /// The maximum number of attribute records that can be added to this service (including the
1340    /// service attribute, include attribute, characteristic attribute, characteristic value
1341    /// attribute and characteristic descriptor attribute).
1342    pub max_attribute_records: u8,
1343}
1344
1345impl AddServiceParameters {
1346    const MAX_LENGTH: usize = 19;
1347
1348    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
1349        assert!(bytes.len() >= Self::MAX_LENGTH);
1350
1351        let next = self.uuid.copy_into_slice(bytes);
1352        bytes[next] = self.service_type as u8;
1353        bytes[next + 1] = self.max_attribute_records;
1354
1355        next + 2
1356    }
1357}
1358
1359/// Types of UUID
1360#[derive(Copy, Clone, Debug, PartialEq)]
1361#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1362pub enum Uuid {
1363    /// 16-bit UUID
1364    Uuid16(u16),
1365
1366    /// 128-bit UUID
1367    Uuid128([u8; 16]),
1368}
1369
1370impl Uuid {
1371    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
1372        match *self {
1373            Uuid::Uuid16(uuid) => {
1374                assert!(bytes.len() >= 3);
1375
1376                bytes[0] = 0x01;
1377                LittleEndian::write_u16(&mut bytes[1..3], uuid);
1378
1379                3
1380            }
1381            Uuid::Uuid128(uuid) => {
1382                assert!(bytes.len() >= 17);
1383
1384                bytes[0] = 0x02;
1385                bytes[1..17].copy_from_slice(&uuid);
1386
1387                17
1388            }
1389        }
1390    }
1391}
1392
1393/// Types of GATT services
1394#[derive(Copy, Clone, Debug, PartialEq)]
1395#[repr(u8)]
1396#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1397pub enum ServiceType {
1398    /// Primary service
1399    Primary = 0x01,
1400    /// Secondary service
1401    Secondary = 0x02,
1402}
1403
1404/// Parameters for the [GATT Include Service](GattCommands::include_service) command.
1405pub struct IncludeServiceParameters {
1406    /// Handle of the service to which another service has to be included
1407    pub service_handle: AttributeHandle,
1408
1409    /// Range of handles of the service which has to be included in the service.
1410    pub include_handle_range: Range<AttributeHandle>,
1411
1412    /// UUID of the included service
1413    pub include_uuid: Uuid,
1414}
1415
1416impl IncludeServiceParameters {
1417    const MAX_LENGTH: usize = 23;
1418
1419    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
1420        assert!(bytes.len() >= Self::MAX_LENGTH);
1421
1422        LittleEndian::write_u16(&mut bytes[0..2], self.service_handle.0);
1423        LittleEndian::write_u16(&mut bytes[2..4], self.include_handle_range.start.0);
1424        LittleEndian::write_u16(&mut bytes[4..6], self.include_handle_range.end.0);
1425        let uuid_len = self.include_uuid.copy_into_slice(&mut bytes[6..]);
1426
1427        6 + uuid_len
1428    }
1429}
1430
1431/// Parameters for the [GATT Add Characteristic](GattCommands::add_characteristic) command.
1432pub struct AddCharacteristicParameters {
1433    /// Handle of the service to which the characteristic has to be added
1434    pub service_handle: AttributeHandle,
1435
1436    /// UUID of the characteristic
1437    pub characteristic_uuid: Uuid,
1438
1439    /// Maximum length of the characteristic value
1440    pub characteristic_value_len: u16,
1441
1442    /// Properties of the characteristic (defined in Volume 3, Part G, Section 3.3.3.1 of Bluetooth
1443    /// Specification 4.1)
1444    pub characteristic_properties: CharacteristicProperty,
1445
1446    /// Security requirements of the characteristic
1447    pub security_permissions: CharacteristicPermission,
1448
1449    /// Which types of events will be generated when the attribute is accessed.
1450    pub gatt_event_mask: CharacteristicEvent,
1451
1452    /// The minimum encryption key size requirement for this attribute.
1453    pub encryption_key_size: EncryptionKeySize,
1454
1455    /// If true, the attribute has a variable length value field. Otherwise, the value field length
1456    /// is fixed.
1457    pub is_variable: bool,
1458}
1459
1460impl AddCharacteristicParameters {
1461    const MAX_LENGTH: usize = 26;
1462
1463    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
1464        assert!(bytes.len() >= Self::MAX_LENGTH);
1465
1466        LittleEndian::write_u16(&mut bytes[0..2], self.service_handle.0);
1467        let uuid_len = self.characteristic_uuid.copy_into_slice(&mut bytes[2..19]);
1468        let next = 2 + uuid_len;
1469        LittleEndian::write_u16(&mut bytes[next..next + 2], self.characteristic_value_len);
1470        bytes[next + 2] = self.characteristic_properties.bits();
1471        bytes[next + 3] = self.security_permissions.bits();
1472        bytes[next + 4] = self.gatt_event_mask.bits();
1473        bytes[next + 5] = self.encryption_key_size.0;
1474        bytes[next + 6] = self.is_variable as u8;
1475
1476        next + 6
1477    }
1478}
1479
1480#[cfg(not(feature = "defmt"))]
1481bitflags::bitflags! {
1482    /// Available [properties](AddCharacteristicParameters::characteristic_properties) for
1483    /// characteristics. Defined in Volume 3, Part G, Section 3.3.3.1 of Bluetooth Specification
1484    /// 4.1.
1485    pub struct CharacteristicProperty: u8 {
1486        /// If set, permits broadcasts of the Characteristic Value using Server Characteristic
1487        /// Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor
1488        /// shall exist.
1489        const BROADCAST = 0x01;
1490
1491        /// If set, permits reads of the Characteristic Value using procedures defined in Volume 3,
1492        /// Part G, Section 4.8 of the Bluetooth specification 4.1.
1493        const READ = 0x02;
1494
1495        /// If set, permit writes of the Characteristic Value without response using procedures
1496        /// defined in Volume 3, Part G, Section 4.9.1 of the Bluetooth specification 4.1.
1497        const WRITE_WITHOUT_RESPONSE = 0x04;
1498
1499        /// If set, permits writes of the Characteristic Value with response using procedures
1500        /// defined in Volume 3, Part Section 4.9.3 or Section 4.9.4 of the Bluetooth
1501        /// specification 4.1.
1502        const WRITE = 0x08;
1503
1504        /// If set, permits notifications of a Characteristic Value without acknowledgement using
1505        /// the procedure defined in Volume 3, Part G, Section 4.10 of the Bluetooth specification
1506        /// 4.1. If set, the Client Characteristic Configuration Descriptor shall exist.
1507        const NOTIFY = 0x10;
1508
1509        /// If set, permits indications of a Characteristic Value with acknowledgement using the
1510        /// procedure defined in Volume 3, Part G, Section 4.11 of the Bluetooth specification
1511        /// 4.1. If set, the Client Characteristic Configuration Descriptor shall exist.
1512        const INDICATE = 0x20;
1513
1514        /// If set, permits signed writes to the Characteristic Value using the Signed Writes
1515        /// procedure defined in Volume 3, Part G, Section 4.9.2 of the Bluetooth specification
1516        /// 4.1.
1517        const AUTHENTICATED = 0x40;
1518
1519        /// If set, additional characteristic properties are defined in the Characteristic Extended
1520        /// Properties Descriptor defined in Volume 3, Part G, Section 3.3.3.1 of the Bluetooth
1521        /// specification 4.1. If set, the Characteristic Extended Properties Descriptor shall
1522        /// exist.
1523        const EXTENDED_PROPERTIES = 0x80;
1524    }
1525}
1526
1527#[cfg(feature = "defmt")]
1528defmt::bitflags! {
1529    /// Available [properties](AddCharacteristicParameters::characteristic_properties) for
1530    /// characteristics. Defined in Volume 3, Part G, Section 3.3.3.1 of Bluetooth Specification
1531    /// 4.1.
1532    pub struct CharacteristicProperty: u8 {
1533        /// If set, permits broadcasts of the Characteristic Value using Server Characteristic
1534        /// Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor
1535        /// shall exist.
1536        const BROADCAST = 0x01;
1537
1538        /// If set, permits reads of the Characteristic Value using procedures defined in Volume 3,
1539        /// Part G, Section 4.8 of the Bluetooth specification 4.1.
1540        const READ = 0x02;
1541
1542        /// If set, permit writes of the Characteristic Value without response using procedures
1543        /// defined in Volume 3, Part G, Section 4.9.1 of the Bluetooth specification 4.1.
1544        const WRITE_WITHOUT_RESPONSE = 0x04;
1545
1546        /// If set, permits writes of the Characteristic Value with response using procedures
1547        /// defined in Volume 3, Part Section 4.9.3 or Section 4.9.4 of the Bluetooth
1548        /// specification 4.1.
1549        const WRITE = 0x08;
1550
1551        /// If set, permits notifications of a Characteristic Value without acknowledgement using
1552        /// the procedure defined in Volume 3, Part G, Section 4.10 of the Bluetooth specification
1553        /// 4.1. If set, the Client Characteristic Configuration Descriptor shall exist.
1554        const NOTIFY = 0x10;
1555
1556        /// If set, permits indications of a Characteristic Value with acknowledgement using the
1557        /// procedure defined in Volume 3, Part G, Section 4.11 of the Bluetooth specification
1558        /// 4.1. If set, the Client Characteristic Configuration Descriptor shall exist.
1559        const INDICATE = 0x20;
1560
1561        /// If set, permits signed writes to the Characteristic Value using the Signed Writes
1562        /// procedure defined in Volume 3, Part G, Section 4.9.2 of the Bluetooth specification
1563        /// 4.1.
1564        const AUTHENTICATED = 0x40;
1565
1566        /// If set, additional characteristic properties are defined in the Characteristic Extended
1567        /// Properties Descriptor defined in Volume 3, Part G, Section 3.3.3.1 of the Bluetooth
1568        /// specification 4.1. If set, the Characteristic Extended Properties Descriptor shall
1569        /// exist.
1570        const EXTENDED_PROPERTIES = 0x80;
1571    }
1572}
1573
1574#[cfg(not(feature = "defmt"))]
1575bitflags::bitflags! {
1576    /// [Permissions](AddCharacteristicParameter::security_permissions) available for
1577    /// characteristics.
1578    pub struct CharacteristicPermission: u8 {
1579        /// Need authentication to read.
1580        const AUTHENTICATED_READ = 0x01;
1581
1582        /// Need authorization to read.
1583        const AUTHORIZED_READ = 0x02;
1584
1585        /// Link should be encrypted to read.
1586        const ENCRYPTED_READ = 0x04;
1587
1588        /// Need authentication to write.
1589        const AUTHENTICATED_WRITE = 0x08;
1590
1591        /// Need authorization to write.
1592        const AUTHORIZED_WRITE = 0x10;
1593
1594        /// Link should be encrypted for write.
1595        const ENCRYPTED_WRITE = 0x20;
1596    }
1597}
1598
1599#[cfg(feature = "defmt")]
1600defmt::bitflags! {
1601    /// [Permissions](AddCharacteristicParameter::security_permissions) available for
1602    /// characteristics.
1603    pub struct CharacteristicPermission: u8 {
1604        /// Need authentication to read.
1605        const AUTHENTICATED_READ = 0x01;
1606
1607        /// Need authorization to read.
1608        const AUTHORIZED_READ = 0x02;
1609
1610        /// Link should be encrypted to read.
1611        const ENCRYPTED_READ = 0x04;
1612
1613        /// Need authentication to write.
1614        const AUTHENTICATED_WRITE = 0x08;
1615
1616        /// Need authorization to write.
1617        const AUTHORIZED_WRITE = 0x10;
1618
1619        /// Link should be encrypted for write.
1620        const ENCRYPTED_WRITE = 0x20;
1621    }
1622}
1623
1624#[cfg(not(feature = "defmt"))]
1625bitflags::bitflags! {
1626    /// Which events may be generated when a characteristic is accessed.
1627    pub struct CharacteristicEvent: u8 {
1628        /// The application will be notified when a client writes to this attribute.
1629        const ATTRIBUTE_WRITE = 0x01;
1630
1631        /// The application will be notified when a write request/write command/signed write command
1632        /// is received by the server for this attribute.
1633        const CONFIRM_WRITE = 0x02;
1634
1635        /// The application will be notified when a read request of any type is got for this
1636        /// attribute.
1637        const CONFIRM_READ = 0x04;
1638
1639        /// The application will be notified when a notification is complete
1640        const NOTIFY_NOTIFICATION_COMPLETE = 0x08;
1641    }
1642}
1643
1644#[cfg(feature = "defmt")]
1645defmt::bitflags! {
1646    /// Which events may be generated when a characteristic is accessed.
1647    pub struct CharacteristicEvent: u8 {
1648        /// The application will be notified when a client writes to this attribute.
1649        const ATTRIBUTE_WRITE = 0x01;
1650
1651        /// The application will be notified when a write request/write command/signed write command
1652        /// is received by the server for this attribute.
1653        const CONFIRM_WRITE = 0x02;
1654
1655        /// The application will be notified when a read request of any type is got for this
1656        /// attribute.
1657        const CONFIRM_READ = 0x04;
1658
1659        /// The application will be notified when a notification is complete
1660        const NOTIFY_NOTIFICATION_COMPLETE = 0x08;
1661    }
1662}
1663
1664/// Encryption key size, in bytes.
1665#[derive(Copy, Clone, Debug, PartialEq)]
1666pub struct EncryptionKeySize(u8);
1667
1668impl EncryptionKeySize {
1669    /// Validate the size as a valid encryption key size. Valid range is 7 to 16, inclusive.
1670    ///
1671    /// # Errors
1672    ///
1673    /// - [TooShort](EncryptionKeySizeError::TooShort) if the provided size is less than 7.
1674    /// - [TooLong](EncryptionKeySizeError::TooLong) if the provided size is greater than 16.
1675    pub fn with_value(sz: usize) -> Result<Self, EncryptionKeySizeError> {
1676        const MIN: usize = 7;
1677        const MAX: usize = 16;
1678
1679        if sz < MIN {
1680            return Err(EncryptionKeySizeError::TooShort);
1681        }
1682
1683        if sz > MAX {
1684            return Err(EncryptionKeySizeError::TooLong);
1685        }
1686
1687        Ok(Self(sz as u8))
1688    }
1689
1690    /// Retrieve the key size.
1691    pub fn value(&self) -> usize {
1692        self.0 as usize
1693    }
1694}
1695
1696/// Errors that can occur when creating an [`EncryptionKeySize`].
1697#[derive(Copy, Clone, Debug, PartialEq)]
1698#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1699pub enum EncryptionKeySizeError {
1700    /// The provided size was less than the minimum allowed size.
1701    TooShort,
1702    /// The provided size was greater than the maximum allowed size.
1703    TooLong,
1704}
1705
1706/// Parameters for the [GATT Add Characteristic Descriptor](GattCommands::add_characteristic_descriptor)
1707/// command.
1708pub struct AddDescriptorParameters<'a> {
1709    /// Handle of the service to which characteristic belongs.
1710    pub service_handle: AttributeHandle,
1711
1712    /// Handle of the characteristic to which description is to be added.
1713    pub characteristic_handle: AttributeHandle,
1714
1715    /// UUID of the characteristic descriptor.
1716    ///
1717    /// See [KnownDescriptor] for some useful descriptors. This value is not restricted to the known
1718    /// descriptors, however.
1719    pub descriptor_uuid: Uuid,
1720
1721    /// The maximum length of the descriptor value.
1722    pub descriptor_value_max_len: usize,
1723
1724    /// Current Length of the characteristic descriptor value.
1725    pub descriptor_value: &'a [u8],
1726
1727    /// What security requirements must be met before the descriptor can be accessed.
1728    pub security_permissions: DescriptorPermission,
1729
1730    /// What types of access are allowed for the descriptor.
1731    pub access_permissions: AccessPermission,
1732
1733    /// Which types of events will be generated when the attribute is accessed.
1734    pub gatt_event_mask: CharacteristicEvent,
1735
1736    /// The minimum encryption key size requirement for this attribute.
1737    pub encryption_key_size: EncryptionKeySize,
1738
1739    /// If true, the attribute has a variable length value field. Otherwise, the value field length
1740    /// is fixed.
1741    pub is_variable: bool,
1742}
1743
1744impl<'a> AddDescriptorParameters<'a> {
1745    const MAX_LENGTH: usize = 255;
1746
1747    fn validate(&self) -> Result<(), Error> {
1748        if self.descriptor_value.len() > self.descriptor_value_max_len {
1749            return Err(Error::DescriptorTooLong);
1750        }
1751
1752        if 28 + self.descriptor_value_max_len > Self::MAX_LENGTH {
1753            return Err(Error::DescriptorBufferTooLong);
1754        }
1755
1756        Ok(())
1757    }
1758
1759    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
1760        // The buffer should be big enough to hold this descriptor, assuming a 128-bit UUID.
1761        assert!(bytes.len() >= 28 + self.descriptor_value.len());
1762
1763        LittleEndian::write_u16(&mut bytes[0..2], self.service_handle.0);
1764        LittleEndian::write_u16(&mut bytes[2..4], self.characteristic_handle.0);
1765        let uuid_len = self.descriptor_uuid.copy_into_slice(&mut bytes[4..]);
1766        bytes[4 + uuid_len] = self.descriptor_value_max_len as u8;
1767        bytes[5 + uuid_len] = self.descriptor_value.len() as u8;
1768        bytes[6 + uuid_len..6 + uuid_len + self.descriptor_value.len()]
1769            .copy_from_slice(self.descriptor_value);
1770        let next = 6 + uuid_len + self.descriptor_value.len();
1771        bytes[next] = self.security_permissions.bits();
1772        bytes[1 + next] = self.access_permissions.bits();
1773        bytes[2 + next] = self.gatt_event_mask.bits();
1774        bytes[3 + next] = self.encryption_key_size.0;
1775        bytes[4 + next] = self.is_variable as u8;
1776
1777        5 + next
1778    }
1779}
1780
1781/// Common characteristic descriptor UUIDs.
1782#[repr(u16)]
1783#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1784pub enum KnownDescriptor {
1785    /// Characteristic Extended Properties Descriptor
1786    CharacteristicExtendedProperties = 0x2900,
1787    /// Characteristic User Descriptor
1788    CharacteristicUser = 0x2901,
1789    /// Client configuration descriptor
1790    ClientConfiguration = 0x2902,
1791    /// Server configuration descriptor
1792    ServerConfiguration = 0x2903,
1793    /// Characteristic presentation format
1794    CharacteristicPresentationFormat = 0x2904,
1795    /// Characteristic aggregated format
1796    CharacteristicAggregatedFormat = 0x2905,
1797}
1798
1799impl From<KnownDescriptor> for Uuid {
1800    fn from(value: KnownDescriptor) -> Self {
1801        Uuid::Uuid16(value as u16)
1802    }
1803}
1804
1805#[cfg(not(feature = "defmt"))]
1806bitflags::bitflags! {
1807    /// Permissions available for characteristic descriptors.
1808    pub struct DescriptorPermission: u8 {
1809        /// Authentication required.
1810        const AUTHENTICATED = 0x01;
1811
1812        /// Authorization required.
1813        const AUTHORIZED = 0x02;
1814
1815        /// Encryption required.
1816        const ENCRYPTED = 0x04;
1817    }
1818}
1819
1820#[cfg(feature = "defmt")]
1821defmt::bitflags! {
1822    /// Permissions available for characteristic descriptors.
1823    pub struct DescriptorPermission: u8 {
1824        /// Authentication required.
1825        const AUTHENTICATED = 0x01;
1826
1827        /// Authorization required.
1828        const AUTHORIZED = 0x02;
1829
1830        /// Encryption required.
1831        const ENCRYPTED = 0x04;
1832    }
1833}
1834
1835#[cfg(not(feature = "defmt"))]
1836bitflags::bitflags! {
1837    /// Types of access for characteristic descriptors
1838    pub struct AccessPermission: u8 {
1839        /// Readable
1840        const READ = 0x01;
1841        /// Writable
1842        const WRITE = 0x02;
1843        /// Readable and writeable
1844        const READ_WRITE = Self::READ.bits() | Self::WRITE.bits();
1845        /// Writeable without response
1846        const WRITE_NO_RESP = 0x04;
1847        /// Signed writeable
1848        const SIGNED_WRITE = 0x08;
1849    }
1850}
1851
1852#[cfg(feature = "defmt")]
1853defmt::bitflags! {
1854    /// Types of access for characteristic descriptors
1855    pub struct AccessPermission: u8 {
1856        /// Readable
1857        const READ = 0x01;
1858        /// Writable
1859        const WRITE = 0x02;
1860        /// Readable and writeable
1861        const READ_WRITE = Self::READ.bits() | Self::WRITE.bits();
1862        /// Writeable without responseconst
1863        const WRITE_NO_RESP = 0x04;
1864        /// Signed writeable
1865        const SIGNED_WRITE = 0x08;
1866    }
1867}
1868
1869/// Parameters for the [Update Characteristic Value](GattCommands::update_characteristic_value)
1870/// command.
1871pub struct UpdateCharacteristicValueParameters<'a> {
1872    /// Handle of the service to which characteristic belongs.
1873    pub service_handle: AttributeHandle,
1874
1875    /// Handle of the characteristic.
1876    pub characteristic_handle: AttributeHandle,
1877
1878    /// The offset from which the attribute value has to be updated. If this is set to 0, and the
1879    /// attribute value is of [variable length](AddCharacteristicParameters::is_variable), then the
1880    /// length of the attribute will be set to the length of
1881    /// [value](UpdateCharacteristicValueParameters::value). If the offset is set to a value greater
1882    /// than 0, then the length of the attribute will be set to the
1883    /// [maximum length](AddCharacteristicParameters::characteristic_value_len) as specified for the
1884    /// attribute while adding the characteristic.
1885    pub offset: usize,
1886
1887    /// The new characteristic value.
1888    pub value: &'a [u8],
1889}
1890
1891impl<'a> UpdateCharacteristicValueParameters<'a> {
1892    const MAX_LENGTH: usize = 255;
1893
1894    fn validate(&self) -> Result<(), Error> {
1895        const MAX_VALUE_LEN: usize = 249;
1896        if self.value.len() > MAX_VALUE_LEN {
1897            return Err(Error::ValueBufferTooLong);
1898        }
1899
1900        Ok(())
1901    }
1902
1903    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
1904        assert!(bytes.len() >= 6 + self.value.len());
1905
1906        LittleEndian::write_u16(&mut bytes[0..2], self.service_handle.0);
1907        LittleEndian::write_u16(&mut bytes[2..4], self.characteristic_handle.0);
1908        bytes[4] = self.offset as u8;
1909        bytes[5] = self.value.len() as u8;
1910        bytes[6..6 + self.value.len()].copy_from_slice(self.value);
1911
1912        6 + self.value.len()
1913    }
1914}
1915
1916/// Parameters for the [GATT Delete Included Service](GattCommands::delete_included_service) command.
1917pub struct DeleteIncludedServiceParameters {
1918    /// Handle of the service to which Include definition belongs
1919    pub service: AttributeHandle,
1920
1921    /// Handle of the Included definition to be deleted.
1922    pub included_service: AttributeHandle,
1923}
1924
1925impl DeleteIncludedServiceParameters {
1926    const LENGTH: usize = 4;
1927
1928    fn copy_into_slice(&self, bytes: &mut [u8]) {
1929        assert!(bytes.len() >= Self::LENGTH);
1930
1931        LittleEndian::write_u16(&mut bytes[0..2], self.service.0);
1932        LittleEndian::write_u16(&mut bytes[2..4], self.included_service.0);
1933    }
1934}
1935
1936#[cfg(not(feature = "defmt"))]
1937bitflags::bitflags! {
1938    /// Flags for individual events that can be masked by the
1939    /// [GATT Set Event Mask](GattCommands::set_event_mask) command.
1940    pub struct Event: u32 {
1941        /// [GATT Attribute Modified](crate::vendor::event::VendorEvent::GattAttributeModified).
1942        const ATTRIBUTE_MODIFIED = 0x0000_0001;
1943        /// [GATT Procedure Timeout](crate::vendor::event::VendorEvent::GattProcedureTimeout).
1944        const PROCEDURE_TIMEOUT = 0x0000_0002;
1945        /// [ATT Exchange MTU Response](crate::vendor::event::VendorEvent::AttExchangeMtuResponse).
1946        const EXCHANGE_MTU_RESPONSE = 0x0000_0004;
1947        /// [ATT Find Information Response](crate::vendor::event::VendorEvent::AttFindInformationResponse).
1948        const FIND_INFORMATION_RESPONSE = 0x0000_0008;
1949        /// [ATT Find By Type Value Response](crate::vendor::event::VendorEvent::AttFindByTypeValueResponse).
1950        const FIND_BY_TYPE_VALUE_RESPONSE = 0x0000_0010;
1951        /// [ATT Find By Type Response](crate::vendor::event::VendorEvent::AttFindByTypeResponse).
1952        const READ_BY_TYPE_RESPONSE = 0x0000_0020;
1953        /// [ATT Read Response](crate::vendor::event::VendorEvent::AttReadResponse).
1954        const READ_RESPONSE = 0x0000_0040;
1955        /// [ATT Read Blob Response](crate::vendor::event::VendorEvent::AttReadBlobResponse).
1956        const READ_BLOB_RESPONSE = 0x0000_0080;
1957        /// [ATT Read Multiple Response](crate::vendor::event::VendorEvent::AttReadMultipleResponse).
1958        const READ_MULTIPLE_RESPONSE = 0x0000_0100;
1959        /// [ATT Read By Group](crate::vendor::event::VendorEvent::AttReadByGroupTypeResponse).
1960        const READ_BY_GROUP_RESPONSE = 0x0000_0200;
1961        /// [ATT Prepare Write Response](crate::vendor::event::VendorEvent::AttPrepareWriteResponse).
1962        const PREPARE_WRITE_RESPONSE = 0x0000_0800;
1963        /// [ATT Execute Write Response](crate::vendor::event::VendorEvent::AttExecuteWriteResponse).
1964        const EXECUTE_WRITE_RESPONSE = 0x0000_1000;
1965        /// [GATT Indication](crate::vendor::event::VendorEvent::GattIndication).
1966        const INDICATION = 0x0000_2000;
1967        /// [GATT Notification](crate::vendor::event::VendorEvent::GattNotification).
1968        const NOTIFICATION = 0x0000_4000;
1969        /// [GATT Error Response](crate::vendor::event::VendorEvent::AttErrorResponse).
1970        const ERROR_RESPONSE = 0x0000_8000;
1971        /// [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete).
1972        const PROCEDURE_COMPLETE = 0x0001_0000;
1973        /// [GATT Discover Characteristic by UUID or Read Using Characteristic UUID](crate::vendor::event::VendorEvent::GattDiscoverOrReadCharacteristicByUuidResponse).
1974        const DISCOVER_OR_READ_CHARACTERISTIC_BY_UUID_RESPONSE = 0x0002_0000;
1975        /// [GATT Tx Pool Available](crate::vendor::event::VendorEvent::GattTxPoolAvailable)
1976        const TX_POOL_AVAILABLE = 0x0004_0000;
1977    }
1978}
1979
1980#[cfg(feature = "defmt")]
1981defmt::bitflags! {
1982    /// Flags for individual events that can be masked by the [GATT Set Event Mask](GattCommands::set_event_mask) command.
1983    pub struct Event: u32 {
1984        /// [GATT Attribute Modified](crate::vendor::event::VendorEvent::GattAttributeModified).
1985        const ATTRIBUTE_MODIFIED = 0x0000_0001;
1986        /// [GATT Procedure Timeout](crate::vendor::event::VendorEvent::GattProcedureTimeout).
1987        const PROCEDURE_TIMEOUT = 0x0000_0002;
1988        /// [ATT Exchange MTU Response](crate::vendor::event::VendorEvent::AttExchangeMtuResponse).
1989        const EXCHANGE_MTU_RESPONSE = 0x0000_0004;
1990        /// [ATT Find Information Response](crate::vendor::event::VendorEvent::AttFindInformationResponse).
1991        const FIND_INFORMATION_RESPONSE = 0x0000_0008;
1992        /// [ATT Find By Type Value Response](crate::vendor::event::VendorEvent::AttFindByTypeValueResponse).
1993        const FIND_BY_TYPE_VALUE_RESPONSE = 0x0000_0010;
1994        /// [ATT Find By Type Response](crate::vendor::event::VendorEvent::AttFindByTypeResponse).
1995        const READ_BY_TYPE_RESPONSE = 0x0000_0020;
1996        /// [ATT Read Response](crate::vendor::event::VendorEvent::AttReadResponse).
1997        const READ_RESPONSE = 0x0000_0040;
1998        /// [ATT Read Blob Response](crate::vendor::event::VendorEvent::AttReadBlobResponse).
1999        const READ_BLOB_RESPONSE = 0x0000_0080;
2000        /// [ATT Read Multiple Response](crate::vendor::event::VendorEvent::AttReadMultipleResponse).
2001        const READ_MULTIPLE_RESPONSE = 0x0000_0100;
2002        /// [ATT Read By Group](crate::vendor::event::VendorEvent::AttReadByGroupTypeResponse).
2003        const READ_BY_GROUP_RESPONSE = 0x0000_0200;
2004        /// [ATT Prepare Write Response](crate::vendor::event::VendorEvent::AttPrepareWriteResponse).
2005        const PREPARE_WRITE_RESPONSE = 0x0000_0800;
2006        /// [ATT Execute Write Response](crate::vendor::event::VendorEvent::AttExecuteWriteResponse).
2007        const EXECUTE_WRITE_RESPONSE = 0x0000_1000;
2008        /// [GATT Indication](crate::vendor::event::VendorEvent::GattIndication).
2009        const INDICATION = 0x0000_2000;
2010        /// [GATT Notification](crate::vendor::event::VendorEvent::GattNotification).
2011        const NOTIFICATION = 0x0000_4000;
2012        /// [GATT Error Response](crate::vendor::event::VendorEvent::AttErrorResponse).
2013        const ERROR_RESPONSE = 0x0000_8000;
2014        /// [GATT Procedure Complete](crate::vendor::event::VendorEvent::GattProcedureComplete).
2015        const PROCEDURE_COMPLETE = 0x0001_0000;
2016        /// [GATT Discover Characteristic by UUID or Read Using Characteristic UUID](crate::vendor::event::VendorEvent::GattDiscoverOrReadCharacteristicByUuidResponse).
2017        const DISCOVER_OR_READ_CHARACTERISTIC_BY_UUID_RESPONSE = 0x0002_0000;
2018        /// [GATT Tx Pool Available](crate::vendor::event::VendorEvent::GattTxPoolAvailable)
2019        const TX_POOL_AVAILABLE = 0x0004_0000;
2020    }
2021}
2022
2023impl Event {
2024    const LENGTH: usize = 4;
2025
2026    fn copy_into_slice(&self, bytes: &mut [u8]) {
2027        assert!(bytes.len() >= Self::LENGTH);
2028
2029        LittleEndian::write_u32(bytes, self.bits());
2030    }
2031}
2032
2033/// Parameters for the [GATT Find by Type Value Request](GattCommands::find_by_type_value_request)
2034/// command.
2035pub struct FindByTypeValueParameters<'a> {
2036    /// Connection handle for which the command is given.
2037    pub conn_handle: crate::ConnectionHandle,
2038
2039    /// Range of attributes to be discovered on the server.
2040    pub attribute_handle_range: Range<AttributeHandle>,
2041
2042    /// UUID to find.
2043    pub uuid: Uuid16,
2044
2045    /// Attribute value to find.
2046    ///
2047    /// Note: Though the max attribute value that is allowed according to the spec is 512 octets,
2048    /// due to the limitation of the transport layer (command packet max length is 255 bytes) the
2049    /// value is limited to 246 bytes.
2050    pub value: &'a [u8],
2051}
2052
2053impl<'a> FindByTypeValueParameters<'a> {
2054    const MAX_LENGTH: usize = 255;
2055
2056    fn validate(&self) -> Result<(), Error> {
2057        if 9 + self.value.len() > Self::MAX_LENGTH {
2058            return Err(Error::ValueBufferTooLong);
2059        }
2060
2061        Ok(())
2062    }
2063
2064    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2065        assert!(bytes.len() >= 9 + self.value.len());
2066
2067        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2068        LittleEndian::write_u16(&mut bytes[2..4], self.attribute_handle_range.start.0);
2069        LittleEndian::write_u16(&mut bytes[4..6], self.attribute_handle_range.end.0);
2070        LittleEndian::write_u16(&mut bytes[6..8], self.uuid.0);
2071        bytes[8] = self.value.len() as u8;
2072        bytes[9..9 + self.value.len()].copy_from_slice(self.value);
2073
2074        9 + self.value.len()
2075    }
2076}
2077
2078/// 16-bit UUID
2079pub struct Uuid16(pub u16);
2080
2081/// Parameters for the [Read by Group Type Request](GattCommands::read_by_group_type_request) command.
2082pub struct ReadByTypeParameters {
2083    /// Connection handle for which the command is given.
2084    pub conn_handle: crate::ConnectionHandle,
2085
2086    /// Range of values to be read on the server.
2087    pub attribute_handle_range: Range<AttributeHandle>,
2088
2089    /// UUID of the attribute.
2090    pub uuid: Uuid,
2091}
2092
2093impl ReadByTypeParameters {
2094    const MAX_LENGTH: usize = 23;
2095
2096    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2097        assert!(bytes.len() >= Self::MAX_LENGTH);
2098
2099        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2100        LittleEndian::write_u16(&mut bytes[2..4], self.attribute_handle_range.start.0);
2101        LittleEndian::write_u16(&mut bytes[4..6], self.attribute_handle_range.end.0);
2102        6 + self.uuid.copy_into_slice(&mut bytes[6..])
2103    }
2104}
2105
2106/// Parameters for the [Prepare Write Request](GattCommands::prepare_write_request) command.
2107pub struct WriteRequest<'a> {
2108    /// Connection handle for which the command is given.
2109    pub conn_handle: crate::ConnectionHandle,
2110
2111    /// Handle of the attribute whose value has to be written
2112    pub attribute_handle: AttributeHandle,
2113
2114    /// The offset at which value has to be written
2115    pub offset: usize,
2116
2117    /// Value of the attribute to be written
2118    pub value: &'a [u8],
2119}
2120
2121impl<'a> WriteRequest<'a> {
2122    const MAX_LENGTH: usize = 255;
2123
2124    fn validate(&self) -> Result<(), Error> {
2125        if 9 + self.value.len() > 255 {
2126            return Err(Error::ValueBufferTooLong);
2127        }
2128
2129        Ok(())
2130    }
2131
2132    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2133        assert!(bytes.len() >= 9 + self.value.len());
2134
2135        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2136        LittleEndian::write_u16(&mut bytes[2..4], self.attribute_handle.0);
2137        LittleEndian::write_u16(&mut bytes[4..6], self.offset as u16);
2138        bytes[6] = self.value.len() as u8;
2139        bytes[7..7 + self.value.len()].copy_from_slice(self.value);
2140
2141        7 + self.value.len()
2142    }
2143}
2144
2145/// Parameters for the [Read long characteristic value](GattCommands::read_long_characteristic_value)
2146/// command.
2147pub struct LongCharacteristicReadParameters {
2148    /// Connection handle for which the command is given.
2149    pub conn_handle: crate::ConnectionHandle,
2150
2151    /// Handle of the characteristic to be read
2152    pub attribute: AttributeHandle,
2153
2154    /// Offset from which the value needs to be read.
2155    pub offset: usize,
2156}
2157
2158impl LongCharacteristicReadParameters {
2159    const LENGTH: usize = 6;
2160
2161    fn copy_into_slice(&self, bytes: &mut [u8]) {
2162        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2163        LittleEndian::write_u16(&mut bytes[2..4], self.attribute.0);
2164        LittleEndian::write_u16(&mut bytes[4..6], self.offset as u16);
2165    }
2166}
2167
2168/// Parameters for the [Read Multiple Characteristic Values](GattCommands::read_multiple_characteristic_values)
2169/// command.
2170pub struct MultipleCharacteristicReadParameters<'a> {
2171    /// Connection handle for which the command is given.
2172    pub conn_handle: crate::ConnectionHandle,
2173
2174    /// The handles for which the attribute value has to be read.
2175    ///
2176    /// The maximum length is 126 handles.
2177    pub handles: &'a [AttributeHandle],
2178}
2179
2180impl<'a> MultipleCharacteristicReadParameters<'a> {
2181    const MAX_LENGTH: usize = 255;
2182
2183    fn validate(&self) -> Result<(), Error> {
2184        const MAX_HANDLE_COUNT: usize = 126;
2185        if self.handles.len() > MAX_HANDLE_COUNT {
2186            return Err(Error::TooManyHandlesToRead);
2187        }
2188
2189        Ok(())
2190    }
2191
2192    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2193        assert!(bytes.len() >= 3 + 2 * self.handles.len());
2194
2195        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2196        bytes[2] = self.handles.len() as u8;
2197        let mut next = 3;
2198        for handle in self.handles.iter() {
2199            LittleEndian::write_u16(&mut bytes[next..next + 2], handle.0);
2200            next += 2
2201        }
2202
2203        next
2204    }
2205}
2206
2207/// Parameters for the [Write Characteristic Value](GattCommands::write_characteristic_value) command.
2208pub struct CharacteristicValue<'a> {
2209    /// Connection handle for which the command is given.
2210    pub conn_handle: crate::ConnectionHandle,
2211
2212    /// Handle of the characteristic to be written.
2213    pub characteristic_handle: AttributeHandle,
2214
2215    /// Value to be written. The maximum length is 250 bytes.
2216    pub value: &'a [u8],
2217}
2218
2219impl<'a> CharacteristicValue<'a> {
2220    const MAX_LENGTH: usize = 255;
2221
2222    fn validate(&self) -> Result<(), Error> {
2223        if self.len() > Self::MAX_LENGTH {
2224            return Err(Error::ValueBufferTooLong);
2225        }
2226
2227        Ok(())
2228    }
2229
2230    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2231        assert!(bytes.len() >= self.len());
2232
2233        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2234        LittleEndian::write_u16(&mut bytes[2..4], self.characteristic_handle.0);
2235        bytes[4] = self.value.len() as u8;
2236        bytes[5..self.len()].copy_from_slice(self.value);
2237
2238        self.len()
2239    }
2240
2241    fn len(&self) -> usize {
2242        5 + self.value.len()
2243    }
2244}
2245
2246/// Parameters for the [Write Long Characteristic Value](GattCommands::write_long_characteristic_value)
2247/// command.
2248pub struct LongCharacteristicValue<'a> {
2249    /// Connection handle for which the command is given.
2250    pub conn_handle: crate::ConnectionHandle,
2251
2252    /// Handle of the characteristic to be written.
2253    pub characteristic_handle: AttributeHandle,
2254
2255    /// Offset at which the attribute has to be written.
2256    pub offset: usize,
2257
2258    /// Value to be written. The maximum length is 248 bytes.
2259    pub value: &'a [u8],
2260}
2261
2262impl<'a> LongCharacteristicValue<'a> {
2263    const MAX_LENGTH: usize = 255;
2264
2265    fn validate(&self) -> Result<(), Error> {
2266        if self.len() > Self::MAX_LENGTH {
2267            return Err(Error::ValueBufferTooLong);
2268        }
2269
2270        Ok(())
2271    }
2272
2273    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2274        assert!(bytes.len() >= self.len());
2275
2276        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2277        LittleEndian::write_u16(&mut bytes[2..4], self.characteristic_handle.0);
2278        LittleEndian::write_u16(&mut bytes[4..6], self.offset as u16);
2279        bytes[6] = self.value.len() as u8;
2280        bytes[7..self.len()].copy_from_slice(self.value);
2281
2282        self.len()
2283    }
2284
2285    fn len(&self) -> usize {
2286        7 + self.value.len()
2287    }
2288}
2289
2290/// Parameters for the [Write Response](GattCommands::write_response) command.
2291pub struct WriteResponseParameters<'a> {
2292    /// Connection handle for which the command is given
2293    pub conn_handle: crate::ConnectionHandle,
2294
2295    /// Handle of the attribute that was passed in the
2296    /// [Write Permit Request](crate::vendor::event::VendorEvent::AttWritePermitRequest) event.
2297    pub attribute_handle: AttributeHandle,
2298
2299    /// Is the command rejected, and if so, why?
2300    pub status: Result<(), crate::Status>,
2301
2302    /// Value as passed in the
2303    /// [Write Permit Request](crate::vendor::event::VendorEvent::AttWritePermitRequest) event.
2304    pub value: &'a [u8],
2305}
2306
2307impl<'a> WriteResponseParameters<'a> {
2308    const MAX_LENGTH: usize = 255;
2309
2310    fn validate(&self) -> Result<(), Error> {
2311        if self.len() > Self::MAX_LENGTH {
2312            return Err(Error::ValueBufferTooLong);
2313        }
2314
2315        Ok(())
2316    }
2317
2318    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2319        assert!(bytes.len() >= self.len());
2320        LittleEndian::write_u16(&mut bytes[0..2], self.conn_handle.0);
2321        LittleEndian::write_u16(&mut bytes[2..4], self.attribute_handle.0);
2322        match self.status {
2323            Ok(_) => {
2324                bytes[4] = 0;
2325                bytes[5] = 0;
2326            }
2327            Err(code) => {
2328                bytes[4] = 1;
2329                bytes[5] = code.into();
2330            }
2331        }
2332        bytes[6] = self.value.len() as u8;
2333        bytes[7..self.len()].copy_from_slice(self.value);
2334
2335        self.len()
2336    }
2337
2338    fn len(&self) -> usize {
2339        7 + self.value.len()
2340    }
2341}
2342
2343/// Parameters for the [Set Security Permission](GattCommands::set_security_permission) command.
2344pub struct SecurityPermissionParameters {
2345    /// Handle of the service which contains the attribute whose security permission has to be
2346    /// modified.
2347    pub service_handle: AttributeHandle,
2348
2349    /// Handle of the attribute whose security permission has to be modified.
2350    pub attribute_handle: AttributeHandle,
2351
2352    /// Security requirements for the attribute.
2353    pub permission: CharacteristicPermission,
2354}
2355
2356impl SecurityPermissionParameters {
2357    const LENGTH: usize = 5;
2358
2359    fn copy_into_slice(&self, bytes: &mut [u8]) {
2360        assert!(bytes.len() >= Self::LENGTH);
2361
2362        LittleEndian::write_u16(&mut bytes[0..2], self.service_handle.0);
2363        LittleEndian::write_u16(&mut bytes[2..4], self.attribute_handle.0);
2364        bytes[4] = self.permission.bits();
2365    }
2366}
2367
2368/// Parameters for the [Set Descriptor Value](GattCommands::set_descriptor_value) command.
2369pub struct DescriptorValueParameters<'a> {
2370    /// Handle of the service which contains the descriptor.
2371    pub service_handle: AttributeHandle,
2372
2373    /// Handle of the characteristic which contains the descriptor.
2374    pub characteristic_handle: AttributeHandle,
2375
2376    /// Handle of the descriptor whose value has to be set.
2377    pub descriptor_handle: AttributeHandle,
2378
2379    /// Offset from which the descriptor value has to be updated.
2380    pub offset: usize,
2381
2382    /// Descriptor value
2383    pub value: &'a [u8],
2384}
2385
2386impl<'a> DescriptorValueParameters<'a> {
2387    const MAX_LENGTH: usize = 255;
2388
2389    fn validate(&self) -> Result<(), Error> {
2390        if self.len() > Self::MAX_LENGTH {
2391            return Err(Error::ValueBufferTooLong);
2392        }
2393
2394        Ok(())
2395    }
2396
2397    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2398        assert!(bytes.len() >= self.len());
2399        LittleEndian::write_u16(&mut bytes[0..2], self.service_handle.0);
2400        LittleEndian::write_u16(&mut bytes[2..4], self.characteristic_handle.0);
2401        LittleEndian::write_u16(&mut bytes[4..6], self.descriptor_handle.0);
2402        LittleEndian::write_u16(&mut bytes[6..8], self.offset as u16);
2403        bytes[8] = self.value.len() as u8;
2404        bytes[9..self.len()].copy_from_slice(self.value);
2405
2406        self.len()
2407    }
2408
2409    fn len(&self) -> usize {
2410        9 + self.value.len()
2411    }
2412}
2413
2414/// Parameters for the
2415/// [Update Long Characteristic Value](GattCommands::update_characteristic_value_ext) command.
2416pub struct UpdateCharacteristicValueExt<'a> {
2417    /// Specifies the client(s) to be notified
2418    pub conn_handle_to_notify: ConnectionHandleToNotify,
2419
2420    /// Handle of the service to which characteristic belongs.
2421    pub service_handle: AttributeHandle,
2422
2423    /// Handle of the characteristic.
2424    pub characteristic_handle: AttributeHandle,
2425
2426    /// Controls whether an indication, notification, both, or neither is generated by the attribute
2427    /// update.
2428    pub update_type: UpdateType,
2429
2430    /// Total length of the Attribute value after the update. In case of a
2431    /// [variable size](AddCharacteristicParameters::is_variable) characteristic, this field specifies the new
2432    /// length of the characteristic value after the update; in case of fixed length characteristic
2433    /// this field is ignored.
2434    pub total_len: usize,
2435
2436    /// The offset from which the Attribute value has to be updated.
2437    pub offset: usize,
2438
2439    /// Updated value of the characteristic.
2440    pub value: &'a [u8],
2441}
2442
2443impl<'a> UpdateCharacteristicValueExt<'a> {
2444    const MAX_LENGTH: usize = 255;
2445
2446    fn validate(&self) -> Result<(), Error> {
2447        if self.len() > Self::MAX_LENGTH {
2448            return Err(Error::ValueBufferTooLong);
2449        }
2450
2451        Ok(())
2452    }
2453
2454    fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
2455        assert!(bytes.len() >= self.len());
2456
2457        LittleEndian::write_u16(
2458            &mut bytes[0..2],
2459            match self.conn_handle_to_notify {
2460                ConnectionHandleToNotify::NotifyAll => 0x0000,
2461                ConnectionHandleToNotify::NotifyOneUnenhanced(handle) => handle.0,
2462                ConnectionHandleToNotify::NotifyOneEnhanced(handle) => handle.0,
2463            },
2464        );
2465        LittleEndian::write_u16(&mut bytes[2..4], self.service_handle.0);
2466        LittleEndian::write_u16(&mut bytes[4..6], self.characteristic_handle.0);
2467        bytes[6] = self.update_type.bits();
2468        LittleEndian::write_u16(&mut bytes[7..9], self.total_len as u16);
2469        LittleEndian::write_u16(&mut bytes[9..11], self.offset as u16);
2470        bytes[11] = self.value.len() as u8;
2471        bytes[12..self.len()].copy_from_slice(self.value);
2472
2473        self.len()
2474    }
2475
2476    fn len(&self) -> usize {
2477        12 + self.value.len()
2478    }
2479}
2480
2481#[derive(Clone, Copy)]
2482pub enum ConnectionHandleToNotify {
2483    /// Notify all subscribed clients on their unenhanced ATT bearer
2484    NotifyAll,
2485    /// Notify one client on the specified unenhanced ATT bearer (the parameter us the
2486    /// connection handle) (0x0001 .. 0x0EFF)
2487    NotifyOneUnenhanced(ConnectionHandle),
2488    /// Notfiy one client on the specified enhanced ATT bearer (the LST-byte of the
2489    /// parameter is the connection-oriented channel index) (0xEA00 .. 0xEA1F)
2490    NotifyOneEnhanced(ConnectionHandle),
2491}
2492
2493#[cfg(not(feature = "defmt"))]
2494bitflags::bitflags! {
2495    /// Flags for types of updates that the controller should signal when a characteristic value is
2496    /// [updated](GattCommands::update_long_characteristic_value).
2497    pub struct UpdateType: u8 {
2498        /// A notification can be sent if enabled in the client characteristic configuration
2499        /// descriptor.
2500        const NOTIFICATION = 0x01;
2501        /// An indication can be sent if enabled in the client characteristic configuration
2502        /// descriptor.
2503        const INDICATION = 0x02;
2504    }
2505}
2506
2507#[cfg(feature = "defmt")]
2508defmt::bitflags! {
2509    /// Flags for types of updates that the controller should signal when a characteristic value is
2510    /// [updated](GattCommands::update_long_characteristic_value).
2511    pub struct UpdateType: u8 {
2512        /// A notification can be sent if enabled in the client characteristic configuration
2513        /// descriptor.
2514        const NOTIFICATION = 0x01;
2515        /// An indication can be sent if enabled in the client characteristic configuration
2516        /// descriptor.
2517        const INDICATION = 0x02;
2518    }
2519}