1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
use bytes::{Buf, BufMut, Bytes, BytesMut};
use enumflags2::BitFlags;

use crate::interface::controller::{Controller, ControllerSettings};
use crate::interface::Command;
use crate::Address;
use crate::Result;

use super::*;
use crate::util::BufExt2;

// use some consts for common callback patterns
fn settings_callback(_: Controller, param: Option<Bytes>) -> Result<ControllerSettings> {
    Ok(param.unwrap().get_flags_u32_le())
}

impl<'a> BlueZClient<'a> {
    /// This command is used to set the local name of a controller. The
    ///	command parameters also include a short name which will be used
    ///	in case the full name doesn't fit within EIR/AD data.
    ///
    /// Name can be at most 248 bytes. Short name can be at most 10 bytes.
    /// This function returns a pair of OsStrings in the order (name, short_name).
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	The values of name and short name will be remembered when
    ///	switching the controller off and back on again. So the name
    ///	and short name only have to be set once when a new controller
    ///	is found and will stay until removed.
    pub async fn set_local_name(
        &mut self,
        controller: Controller,
        name: &str,
        short_name: Option<&str>,
    ) -> Result<(CString, CString)> {
        if name.len() > 248 {
            return Err(Error::NameTooLong {
                name: name.to_owned(),
                max_len: 248,
            });
        }

        if let Some(short_name) = short_name {
            if short_name.len() > 10 {
                return Err(Error::NameTooLong {
                    name: short_name.to_owned(),
                    max_len: 10,
                });
            }
        }
        let short_name = short_name.unwrap_or("");

        let mut param = BytesMut::with_capacity(260);
        param.resize(260, 0); // initialize w/ zeros

        CString::new(name)?
            .as_bytes_with_nul()
            .copy_to_slice(&mut param[..=name.len()]);
        CString::new(short_name)?
            .as_bytes_with_nul()
            .copy_to_slice(&mut param[249..][..=short_name.len()]);

        self.exec_command(
            Command::SetLocalName,
            controller,
            Some(param.to_bytes()),
            |_, param| {
                let mut param = param.unwrap();

                Ok((param.split_to(249).get_c_string(), param.get_c_string()))
            },
        )
        .await
    }

    /// This command is used to power on or off a controller.
    ///
    ///	If discoverable setting is activated with a timeout, then
    ///	switching the controller off will expire this timeout and
    ///	disable discoverable.
    ///
    ///	Settings programmed via Set Advertising and Add/Remove
    ///	Advertising while the controller was powered off will be activated
    ///	when powering the controller on.
    ///
    ///	Switching the controller off will permanently cancel and remove
    ///	all advertising instances with a timeout set, i.e. time limited
    ///	advertising instances are not being remembered across power cycles.
    ///	Advertising Removed events will be issued accordingly.
    pub async fn set_powered(
        &mut self,
        controller: Controller,
        powered: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(powered as u8);

        self.exec_command(
            Command::SetPowered,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to set the discoverable property of a
    ///	controller.
    ///
    ///	Timeout is the time in seconds and is only meaningful when
    ///	Discoverable is set to General or Limited. Providing a timeout
    ///	with None returns Invalid Parameters. For Limited, the timeout
    ///	is required.
    ///
    ///	This command is only available for BR/EDR capable controllers
    ///	(e.g. not for single-mode LE ones). It will return Not Supported
    ///	otherwise.
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered, however using a timeout
    /// when the controller is not powered will	return Not Powered error.
    ///
    ///	When switching discoverable on and the connectable setting is
    ///	off it will return Rejected error.
    pub async fn set_discoverable(
        &mut self,
        controller: Controller,
        discoverability: DiscoverableMode,
        timeout: Option<u16>,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(3);
        param.put_u8(discoverability as u8);
        if let Some(timeout) = timeout {
            param.put_u16_le(timeout);
        }

        self.exec_command(
            Command::SetDiscoverable,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to set the connectable property of a
    ///	controller.
    ///
    ///	This command is available for BR/EDR, LE-only and also dual
    ///	mode controllers. For BR/EDR is changes the page scan setting
    ///	and for LE controllers it changes the advertising type. For
    ///	dual mode controllers it affects both settings.
    ///
    ///	For LE capable controllers the connectable setting takes effect
    ///	when advertising is enabled (peripheral) or when directed
    ///	advertising events are received (central).
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	When switching connectable off, it will also switch off the
    ///	discoverable setting. Switching connectable back on will not
    ///	restore a previous discoverable. It will stay off and needs
    ///	to be manually switched back on.
    ///
    ///	When switching connectable off, it will expire a discoverable
    ///	setting with a timeout.
    ///
    ///	This setting does not affect known devices from Add Device
    ///	command. These devices are always allowed to connect.
    pub async fn set_connectable(
        &mut self,
        controller: Controller,
        connectable: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(connectable as u8);

        self.exec_command(
            Command::SetConnectable,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to set the controller into a connectable
    ///	state where the page scan parameters have been set in a way to
    ///	favor faster connect times with the expense of higher power
    ///	consumption.
    ///
    ///	This command is only available for BR/EDR capable controllers
    ///	(e.g. not for single-mode LE ones). It will return Not Supported
    ///	otherwise.
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	The setting will be remembered during power down/up toggles.
    pub async fn set_fast_connectable(
        &mut self,
        controller: Controller,
        fast_connectable: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(fast_connectable as u8);

        self.exec_command(
            Command::SetFastConnectable,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to set the bondable (pairable) property of an
    ///	controller.
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	Turning bondable on will not automatically switch the controller
    ///	into connectable mode. That needs to be done separately.
    ///
    ///	The setting will be remembered during power down/up toggles.
    pub async fn set_bondable(
        &mut self,
        controller: Controller,
        bondable: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(bondable as u8);

        self.exec_command(
            Command::SetPairable,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command is used to either enable or disable link level
    ///	security for an controller (also known as Security Mode 3).
    ///
    ///	This command is only available for BR/EDR capable controllers
    ///	(e.g. not for single-mode LE ones). It will return Not Supported
    ///	otherwise.
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    pub async fn set_link_security(
        &mut self,
        controller: Controller,
        link_security: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(link_security as u8);

        self.exec_command(
            Command::SetLinkSecurity,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command is used to enable/disable Secure Simple Pairing
    ///	support for a controller.
    ///
    ///	This command is only available for BR/EDR capable controllers
    ///	supporting the core specification version 2.1 or greater
    ///	(e.g. not for single-mode LE controllers or pre-2.1 ones).
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	In case the controller does not support Secure Simple Pairing,
    ///	the command will fail regardless with Not Supported error.
    pub async fn set_ssp(
        &mut self,
        controller: Controller,
        ssp: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(ssp as u8);

        self.exec_command(
            Command::SetSecureSimplePairing,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command is used to enable/disable Bluetooth High Speed
    ///	support for a controller.
    ///
    ///	This command is only available for BR/EDR capable controllers
    ///	(e.g. not for single-mode LE ones).
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	To enable High Speed support, it is required that Secure Simple
    ///	Pairing support is enabled first. High Speed support is not
    ///	possible for connections without Secure Simple Pairing.
    ///
    ///	When switching Secure Simple Pairing off, the support for High
    ///	Speed will be switched off as well. Switching Secure Simple
    ///	Pairing back on, will not re-enable High Speed support. That
    ///	needs to be done manually.
    pub async fn set_high_speed(
        &mut self,
        controller: Controller,
        high_speed: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(high_speed as u8);

        self.exec_command(
            Command::SetHighSpeed,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to enable/disable Low Energy support for a
    ///	controller.
    ///
    ///	This command is only available for LE capable controllers and
    ///	will yield in a Not Supported error otherwise.
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	In case the kernel subsystem does not support Low Energy or the
    ///	controller does not either, the command will fail regardless.
    ///
    ///	Disabling LE support will permanently disable and remove all
    ///	advertising instances configured with the Add Advertising
    ///	command. Advertising Removed events will be issued accordingly.
    pub async fn set_le(&mut self, controller: Controller, le: bool) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(le as u8);

        self.exec_command(
            Command::SetLowEnergy,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to enable LE advertising on a controller
    ///	that supports it.
    ///
    ///	The value `Disabled` disables advertising, the value `WithConnectable` enables
    ///	advertising with considering of connectable setting and the
    ///	value `Enabled` enables advertising in connectable mode.
    ///
    ///	Using value `WithConnectable` means that when connectable setting is disabled,
    ///	the advertising happens with undirected non-connectable advertising
    ///	packets and a non-resolvable random address is used. If connectable
    ///	setting is enabled, then undirected connectable advertising packets
    ///	and the identity address or resolvable private address are used.
    ///
    ///	LE Devices configured via Add Device command with Action `0x01`
    ///	have no effect when using Advertising value `0x01` since only the
    ///	connectable setting is taken into account.
    ///
    ///	To utilize undirected connectable advertising without changing the
    ///	connectable setting, the value `Enabled` can be utilized. It makes the
    ///	device connectable via LE without the requirement for being
    ///	connectable on BR/EDR (and/or LE).
    ///
    ///	The value `Enabled` should be the preferred mode of operation when
    ///	implementing peripheral mode.
    ///
    ///	Using this command will temporarily deactivate any configuration
    ///	made by the Add Advertising command. This command takes precedence.
    ///	Once a Set Advertising command with value `Disabled` is issued any
    ///	previously made configurations via Add/Remove Advertising, including
    ///	such changes made while Set Advertising was active, will be re-
    ///	enabled.
    ///
    ///	A pre-requisite is that LE is already enabled, otherwise this
    ///	command will return a "rejected" response.
    pub async fn set_advertising(
        &mut self,
        controller: Controller,
        mode: LeAdvertisingMode,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(mode as u8);

        self.exec_command(
            Command::SetAdvertising,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to enable or disable BR/EDR support
    ///	on a dual-mode controller.
    ///
    ///	A pre-requisite is that LE is already enabled, otherwise
    ///	this command will return a "rejected" response. Enabling BR/EDR
    ///	can be done both when powered on and powered off, however
    ///	disabling it can only be done when powered off (otherwise the
    ///	command will again return "rejected"). Disabling BR/EDR will
    ///	automatically disable all other BR/EDR related settings.
    pub async fn set_bredr(
        &mut self,
        controller: Controller,
        enabled: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(enabled as u8);

        self.exec_command(
            Command::SetBREDR,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command is used to set the IO Capability used for pairing.
    ///	The command accepts both SSP and SMP values.
    ///
    ///	Passing KeyboardDisplay will cause the kernel to
    ///	convert it to DisplayYesNo)in the case of a BR/EDR
    ///	connection (as KeyboardDisplay is specific to SMP).
    ///
    ///	This command can be used when the controller is not powered.
    pub async fn set_io_capability(
        &mut self,
        controller: Controller,
        io_capability: IoCapability,
    ) -> Result<()> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(io_capability as u8);

        self.exec_command(
            Command::SetIOCapability,
            controller,
            Some(param.to_bytes()),
            |_, _| Ok(()),
        )
        .await
    }

    /// This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	The Source parameter selects the organization that assigned the
    ///	Vendor parameter:
    ///
    ///	 - `0x0000`	Disable Device ID
    ///	 - `0x0001`	Bluetooth SIG
    ///	 - `0x0002`	USB Implementer's Forum
    ///
    ///	The information is put into the EIR data. If the controller does
    ///	not support EIR or if SSP is disabled, this command will still
    ///	succeed. The information is stored for later use and will survive
    ///	toggling SSP on and off.
    pub async fn set_device_id(
        &mut self,
        controller: Controller,
        source: u16,
        vendor: u16,
        product: u16,
        version: u16,
    ) -> Result<()> {
        let mut param = BytesMut::with_capacity(8);
        param.put_u16_le(source);
        param.put_u16_le(vendor);
        param.put_u16_le(product);
        param.put_u16_le(version);

        self.exec_command(
            Command::SetDeviceID,
            controller,
            Some(param.to_bytes()),
            |_, _| Ok(()),
        )
        .await
    }

    /// This command allows for setting the Low Energy scan parameters
    ///	used for connection establishment and passive scanning. It is
    ///	only supported on controllers with LE support.
    pub async fn set_scan_parameters(
        &mut self,
        controller: Controller,
        interval: u16,
        window: u16,
    ) -> Result<()> {
        let mut param = BytesMut::with_capacity(4);
        param.put_u16_le(interval);
        param.put_u16_le(window);

        self.exec_command(
            Command::SetScanParameters,
            controller,
            Some(param.to_bytes()),
            |_, _| Ok(()),
        )
        .await
    }

    ///	This command allows for setting the static random address. It is
    ///	only supported on controllers with LE support. The static random
    ///	address is suppose to be valid for the lifetime of the
    ///	controller or at least until the next power cycle. To ensure
    ///	such behavior, setting of the address is limited to when the
    ///	controller is powered off.
    ///
    ///	The `Address::zero()` (`00:00:00:00:00:00`) can be used
    ///	to disable the static address.
    ///
    ///	When a controller has a public address (which is required for
    ///	all dual-mode controllers), this address is not used. If a dual-mode
    ///	controller is configured as Low Energy only devices (BR/EDR has
    ///	been switched off), then the static address is used. Only when
    ///	the controller information reports a zero address (`00:00:00:00:00:00`),
    ///	it is required to configure a static address first.
    ///
    ///	If privacy mode is enabled and the controller is single mode
    ///	LE only without a public address, the static random address is
    ///	used as identity address.
    ///
    ///	The Static Address flag from the current settings can also be used
    ///	to determine if the configured static address is in use or not.
    pub async fn set_static_address(
        &mut self,
        controller: Controller,
        address: Address,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::from(address.as_ref());

        self.exec_command(
            Command::SetStaticAddress,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command is used to enable/disable Secure Connections
    ///	support for a controller.
    ///
    ///	The value `Disabled` disables Secure Connections, the value `Enabled`
    ///	enables Secure Connections and the value `Only` enables Secure
    ///	Connections Only mode.
    ///
    ///	This command is only available for LE capable controllers as
    ///	well as controllers supporting the core specification version
    ///	4.1 or greater.
    ///
    ///	This command can be used when the controller is not powered and
    ///	all settings will be programmed once powered.
    ///
    ///	In case the controller does not support Secure Connections
    ///	the command will fail regardless with Not Supported error.
    pub async fn set_secure_connections_mode(
        &mut self,
        controller: Controller,
        mode: SecureConnectionsMode,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(mode as u8);

        self.exec_command(
            Command::SetSecureConnections,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    /// This command is used to tell the kernel whether to accept the
    ///	usage of debug keys or not.
    ///
    ///	With a value of `Discard` any generated debug key will be discarded
    ///	as soon as the connection terminates.
    ///
    ///	With a value of `Persist` generated debug keys will be kept and can
    ///	be used for future connections. However debug keys are always
    ///	marked as non persistent and should not be stored. This means
    ///	a reboot or changing the value back to `0x00` will delete them.
    ///
    ///	With a value of `PersistAndGenerate` generated debug keys will be kept and can
    ///	be used for future connections. This has the same affect as
    ///	with value `Persist`. However in addition this value will also
    ///	enter the controller mode to generate debug keys for each
    ///	new pairing. Changing the value back to `Persist` or `Discard` will
    ///	disable the controller mode for generating debug keys.
    pub async fn set_debug_mode(
        &mut self,
        controller: Controller,
        mode: DebugKeysMode,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(1);
        param.put_u8(mode as u8);

        self.exec_command(
            Command::SetDebugKeys,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command is used to enable Low Energy Privacy feature using
    ///	resolvable private addresses.
    ///
    ///	The value `Disabled` disables privacy mode, the values `Strict` and `Limited`
    ///	enable privacy mode.
    ///
    ///	With value `Strict` the kernel will always use the privacy mode. This
    ///	means resolvable private address is used when the controller is
    ///	discoverable and also when pairing is initiated.
    ///
    ///	With value `Limited` the kernel will use a limited privacy mode with a
    ///	resolvable private address except when the controller is bondable
    ///	and discoverable, in which case the identity address is used.
    ///
    ///	Exposing the identity address when bondable and discoverable or
    ///	during initiated pairing can be a privacy issue. For dual-mode
    ///	controllers this can be neglected since its public address will
    ///	be exposed over BR/EDR anyway. The benefit of exposing the
    ///	identity address for pairing purposes is that it makes matching
    ///	up devices with dual-mode topology during device discovery now
    ///	possible.
    ///
    ///	If the privacy value `Limited` is used, then also the GATT database
    ///	should expose the Privacy Characteristic so that remote devices
    ///	can determine if the privacy feature is in use or not.
    ///
    ///	When the controller has a public address (mandatory for dual-mode
    ///	controllers) it is used as identity address. In case the controller
    ///	is single mode LE only without a public address, it is required
    ///	to configure a static random address first. The privacy mode can
    ///	only be enabled when an identity address is available.
    ///
    ///	The identity_resolving_key is the local key assigned for the local
    ///	resolvable private address.
    pub async fn set_privacy_mode(
        &mut self,
        controller: Controller,
        mode: PrivacyMode,
        identity_resolving_key: [u8; 16],
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::with_capacity(17);
        param.put_u8(mode as u8);
        param.put_slice(&identity_resolving_key[..]);

        self.exec_command(
            Command::SetPrivacy,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command allows to change external configuration option to
    ///	indicate that a controller is now configured or unconfigured.
    ///
    ///	The value false sets unconfigured state and the value true sets
    ///	configured state of the controller.
    ///
    ///	It is not mandatory that this configuration option is provided
    ///	by a controller. If it is provided, the configuration has to
    ///	happen externally using user channel operation or via vendor
    ///	specific methods.
    ///
    ///	Setting this option and when Missing_Options returns zero, this
    ///	means that the controller will switch to configured state and it
    ///	can be expected that it will be announced via Index Added event.
    ///
    ///	Wrongly configured controllers might still cause an error when
    ///	trying to power them via Set Powered command.
    pub async fn set_external_config(
        &mut self,
        controller: Controller,
        config: bool,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::from([config as u8].as_ref() as &[u8]);

        self.exec_command(
            Command::SetExternalConfig,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command allows configuration of public address. Since a vendor
    ///	specific procedure is required, this command might not be supported
    ///	by all controllers. Actually most likely only a handful embedded
    ///	controllers will offer support for this command.
    ///
    ///	When the support for Bluetooth public address configuration is
    ///	indicated in the supported options mask, then this command
    ///	can be used to configure the public address.
    ///
    ///	It is only possible to configure the public address when the
    ///	controller is powered off.
    ///
    ///	For an unconfigured controller and when this function returns
    ///	an empty mask, this means that a Index Added event for the now
    ///	fully configured controller can be expected.
    ///
    ///	For a fully configured controller, the current controller index
    ///	will become invalid and an Unconfigured Index Removed event will
    ///	be sent. Once the address has been successfully changed an Index
    ///	Added event will be sent. There is no guarantee that the controller
    ///	index stays the same.
    ///
    ///	All previous configured parameters and settings are lost when
    ///	this command succeeds. The controller has to be treated as new
    ///	one. Use this command for a fully configured controller only when
    ///	you really know what you are doing.
    pub async fn set_public_address(
        &mut self,
        controller: Controller,
        address: Address,
    ) -> Result<ControllerSettings> {
        let mut param = BytesMut::from(address.as_ref());

        self.exec_command(
            Command::SetPublicAddress,
            controller,
            Some(param.to_bytes()),
            settings_callback,
        )
        .await
    }

    ///	This command is used to set the appearance value of a controller.
    ///
    ///	This command can be used when the controller is not
    ///	powered and all settings will be programmed once powered.
    ///
    ///	The value of appearance will be remembered when switching
    ///	the controller off and back on again. So the appearance only
    ///	have to be set once when a new controller is found and will
    ///	stay until removed.
    // todo: implement appearance as enum instead of u16
    pub async fn set_appearance(&mut self, controller: Controller, appearance: u16) -> Result<()> {
        let mut param = BytesMut::with_capacity(2);
        param.put_u16_le(appearance);

        self.exec_command(
            Command::SetAppearance,
            controller,
            Some(param.to_bytes()),
            |_, _| Ok(()),
        )
        .await
    }

    ///	on the PHY configuration. It is remembered over power cycles.
    pub async fn set_phy_config(
        &mut self,
        controller: Controller,
        selected_phys: BitFlags<PhyFlag>,
    ) -> Result<()> {
        let mut param = BytesMut::with_capacity(4);
        param.put_u32_le(selected_phys.bits());

        self.exec_command(
            Command::SetPhyConfig,
            controller,
            Some(param.to_bytes()),
            |_, _| Ok(()),
        )
        .await
    }
}