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}