1#![allow(dead_code)]
10
11#[cfg(feature = "alloc")]
12#[allow(unused_imports)]
13use alloc::vec::Vec;
14use core::fmt;
15
16use crate::error::KernelError;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24#[repr(u8)]
25pub enum HciPacketType {
26 Command = 0x01,
28 AclData = 0x02,
30 ScoData = 0x03,
32 Event = 0x04,
34}
35
36impl HciPacketType {
37 pub(crate) fn from_u8(val: u8) -> Option<Self> {
39 match val {
40 0x01 => Some(Self::Command),
41 0x02 => Some(Self::AclData),
42 0x03 => Some(Self::ScoData),
43 0x04 => Some(Self::Event),
44 _ => None,
45 }
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55#[repr(u8)]
56pub enum Ogf {
57 LinkControl = 0x01,
59 LinkPolicy = 0x02,
61 ControllerBaseband = 0x03,
63 Informational = 0x04,
65 StatusParameters = 0x05,
67 LeController = 0x08,
69}
70
71impl Ogf {
72 pub(crate) fn from_u8(val: u8) -> Option<Self> {
73 match val {
74 0x01 => Some(Self::LinkControl),
75 0x02 => Some(Self::LinkPolicy),
76 0x03 => Some(Self::ControllerBaseband),
77 0x04 => Some(Self::Informational),
78 0x05 => Some(Self::StatusParameters),
79 0x08 => Some(Self::LeController),
80 _ => None,
81 }
82 }
83}
84
85pub const fn make_opcode(ogf: u8, ocf: u16) -> u16 {
88 ((ogf as u16) << 10) | (ocf & 0x03FF)
89}
90
91pub const fn opcode_ogf(opcode: u16) -> u8 {
93 (opcode >> 10) as u8
94}
95
96pub const fn opcode_ocf(opcode: u16) -> u16 {
98 opcode & 0x03FF
99}
100
101pub const HCI_INQUIRY: u16 = make_opcode(0x01, 0x0001);
104pub const HCI_CREATE_CONNECTION: u16 = make_opcode(0x01, 0x0005);
106pub const HCI_DISCONNECT: u16 = make_opcode(0x01, 0x0006);
108pub const HCI_RESET: u16 = make_opcode(0x03, 0x0003);
110pub const HCI_READ_LOCAL_NAME: u16 = make_opcode(0x03, 0x0014);
112pub const HCI_WRITE_SCAN_ENABLE: u16 = make_opcode(0x03, 0x001A);
114pub const HCI_READ_BD_ADDR: u16 = make_opcode(0x04, 0x0009);
116
117pub const HCI_MAX_COMMAND_PARAMS: usize = 255;
123
124#[derive(Clone)]
126pub struct HciCommand {
127 pub opcode: u16,
129 pub param_len: u8,
131 pub params: [u8; HCI_MAX_COMMAND_PARAMS],
133}
134
135impl fmt::Debug for HciCommand {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 f.debug_struct("HciCommand")
138 .field("opcode", &format_args!("0x{:04X}", self.opcode))
139 .field("ogf", &format_args!("0x{:02X}", opcode_ogf(self.opcode)))
140 .field("ocf", &format_args!("0x{:03X}", opcode_ocf(self.opcode)))
141 .field("param_len", &self.param_len)
142 .finish()
143 }
144}
145
146impl HciCommand {
147 pub fn new(opcode: u16) -> Self {
149 Self {
150 opcode,
151 param_len: 0,
152 params: [0u8; HCI_MAX_COMMAND_PARAMS],
153 }
154 }
155
156 pub(crate) fn with_params(opcode: u16, params: &[u8]) -> Result<Self, KernelError> {
158 if params.len() > HCI_MAX_COMMAND_PARAMS {
159 return Err(KernelError::InvalidArgument {
160 name: "params",
161 value: "exceeds 255 bytes",
162 });
163 }
164 let mut cmd = Self::new(opcode);
165 cmd.param_len = params.len() as u8;
166 cmd.params[..params.len()].copy_from_slice(params);
167 Ok(cmd)
168 }
169
170 pub(crate) fn serialize(&self, buf: &mut [u8]) -> Result<usize, KernelError> {
173 let total = 1 + 3 + self.param_len as usize; if buf.len() < total {
175 return Err(KernelError::InvalidArgument {
176 name: "buffer",
177 value: "too small for HCI command",
178 });
179 }
180 buf[0] = HciPacketType::Command as u8;
181 buf[1] = (self.opcode & 0xFF) as u8;
182 buf[2] = (self.opcode >> 8) as u8;
183 buf[3] = self.param_len;
184 if self.param_len > 0 {
185 buf[4..4 + self.param_len as usize]
186 .copy_from_slice(&self.params[..self.param_len as usize]);
187 }
188 Ok(total)
189 }
190}
191
192#[derive(Debug, Clone, Copy, PartialEq, Eq)]
198#[repr(u8)]
199pub enum HciEventCode {
200 InquiryComplete = 0x01,
202 InquiryResult = 0x02,
204 ConnectionComplete = 0x03,
206 ConnectionRequest = 0x04,
208 DisconnectionComplete = 0x05,
210 CommandComplete = 0x0E,
212 CommandStatus = 0x0F,
214 NumberOfCompletedPackets = 0x13,
216 ExtendedInquiryResult = 0x2F,
218}
219
220impl HciEventCode {
221 pub(crate) fn from_u8(val: u8) -> Option<Self> {
222 match val {
223 0x01 => Some(Self::InquiryComplete),
224 0x02 => Some(Self::InquiryResult),
225 0x03 => Some(Self::ConnectionComplete),
226 0x04 => Some(Self::ConnectionRequest),
227 0x05 => Some(Self::DisconnectionComplete),
228 0x0E => Some(Self::CommandComplete),
229 0x0F => Some(Self::CommandStatus),
230 0x13 => Some(Self::NumberOfCompletedPackets),
231 0x2F => Some(Self::ExtendedInquiryResult),
232 _ => None,
233 }
234 }
235}
236
237pub const HCI_MAX_EVENT_PARAMS: usize = 255;
239
240#[derive(Clone)]
242pub struct HciEvent {
243 pub event_code: u8,
245 pub param_len: u8,
247 pub params: [u8; HCI_MAX_EVENT_PARAMS],
249}
250
251impl fmt::Debug for HciEvent {
252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253 f.debug_struct("HciEvent")
254 .field("event_code", &format_args!("0x{:02X}", self.event_code))
255 .field("param_len", &self.param_len)
256 .finish()
257 }
258}
259
260impl HciEvent {
261 pub fn new(event_code: u8) -> Self {
263 Self {
264 event_code,
265 param_len: 0,
266 params: [0u8; HCI_MAX_EVENT_PARAMS],
267 }
268 }
269
270 pub(crate) fn parse(buf: &[u8]) -> Result<Self, KernelError> {
272 if buf.len() < 2 {
273 return Err(KernelError::InvalidArgument {
274 name: "event_buffer",
275 value: "too short for HCI event header",
276 });
277 }
278 let event_code = buf[0];
279 let param_len = buf[1];
280 if buf.len() < 2 + param_len as usize {
281 return Err(KernelError::InvalidArgument {
282 name: "event_buffer",
283 value: "truncated event parameters",
284 });
285 }
286 let mut evt = Self::new(event_code);
287 evt.param_len = param_len;
288 if param_len > 0 {
289 evt.params[..param_len as usize].copy_from_slice(&buf[2..2 + param_len as usize]);
290 }
291 Ok(evt)
292 }
293
294 pub(crate) fn is_command_complete(&self) -> bool {
296 self.event_code == HciEventCode::CommandComplete as u8
297 }
298
299 pub(crate) fn is_command_status(&self) -> bool {
301 self.event_code == HciEventCode::CommandStatus as u8
302 }
303
304 pub(crate) fn command_complete_opcode(&self) -> Option<u16> {
306 if !self.is_command_complete() || self.param_len < 3 {
307 return None;
308 }
309 Some(u16::from_le_bytes([self.params[1], self.params[2]]))
311 }
312
313 pub(crate) fn command_complete_status(&self) -> Option<u8> {
315 if !self.is_command_complete() || self.param_len < 4 {
316 return None;
317 }
318 Some(self.params[3])
319 }
320
321 pub(crate) fn command_status(&self) -> Option<u8> {
323 if !self.is_command_status() || self.param_len < 1 {
324 return None;
325 }
326 Some(self.params[0])
327 }
328}
329
330#[derive(Debug, Clone, Copy, PartialEq, Eq)]
336#[repr(u8)]
337pub enum AclBoundaryFlag {
338 FirstNonFlushable = 0x00,
340 Continuing = 0x01,
342 FirstFlushable = 0x02,
344}
345
346#[derive(Debug, Clone, Copy, PartialEq, Eq)]
348#[repr(u8)]
349pub enum AclBroadcastFlag {
350 PointToPoint = 0x00,
352 ActiveBroadcast = 0x01,
354}
355
356pub const ACL_MAX_DATA_LEN: usize = 1021;
358
359#[derive(Debug, Clone, Copy, PartialEq, Eq)]
361pub struct AclHeader {
362 pub handle: u16,
364 pub boundary: AclBoundaryFlag,
366 pub broadcast: AclBroadcastFlag,
368 pub data_len: u16,
370}
371
372impl AclHeader {
373 pub(crate) fn parse(buf: &[u8]) -> Result<Self, KernelError> {
375 if buf.len() < 4 {
376 return Err(KernelError::InvalidArgument {
377 name: "acl_buffer",
378 value: "too short for ACL header",
379 });
380 }
381 let hdr_word = u16::from_le_bytes([buf[0], buf[1]]);
382 let handle = hdr_word & 0x0FFF;
383 let pb = (hdr_word >> 12) & 0x03;
384 let bc = (hdr_word >> 14) & 0x03;
385 let data_len = u16::from_le_bytes([buf[2], buf[3]]);
386
387 let boundary = match pb {
388 0x00 => AclBoundaryFlag::FirstNonFlushable,
389 0x01 => AclBoundaryFlag::Continuing,
390 0x02 => AclBoundaryFlag::FirstFlushable,
391 _ => AclBoundaryFlag::FirstFlushable,
392 };
393 let broadcast = match bc {
394 0x00 => AclBroadcastFlag::PointToPoint,
395 0x01 => AclBroadcastFlag::ActiveBroadcast,
396 _ => AclBroadcastFlag::PointToPoint,
397 };
398
399 Ok(Self {
400 handle,
401 boundary,
402 broadcast,
403 data_len,
404 })
405 }
406
407 pub(crate) fn serialize(&self, buf: &mut [u8]) -> Result<(), KernelError> {
409 if buf.len() < 4 {
410 return Err(KernelError::InvalidArgument {
411 name: "buffer",
412 value: "too small for ACL header",
413 });
414 }
415 let hdr_word = (self.handle & 0x0FFF)
416 | ((self.boundary as u16) << 12)
417 | ((self.broadcast as u16) << 14);
418 buf[0..2].copy_from_slice(&hdr_word.to_le_bytes());
419 buf[2..4].copy_from_slice(&self.data_len.to_le_bytes());
420 Ok(())
421 }
422}
423
424pub type BdAddr = [u8; 6];
430
431pub const BD_ADDR_ZERO: BdAddr = [0u8; 6];
433
434pub(crate) fn format_bd_addr(addr: &BdAddr) -> [u8; 17] {
436 let hex = b"0123456789ABCDEF";
437 let mut out = [0u8; 17];
438 for i in 0..6 {
439 let offset = (5 - i) * 3; out[offset] = hex[(addr[i] >> 4) as usize];
441 out[offset + 1] = hex[(addr[i] & 0x0F) as usize];
442 if i > 0 {
443 out[offset + 2] = b':';
444 }
445 }
446 out
447}
448
449#[derive(Debug, Clone, Copy)]
455pub struct HciUsbTransport {
456 pub device_addr: u8,
458 pub cmd_endpoint: u8,
460 pub evt_endpoint: u8,
462 pub acl_tx_endpoint: u8,
464 pub acl_rx_endpoint: u8,
466 pub intr_endpoint: u8,
468 pub active: bool,
470}
471
472impl Default for HciUsbTransport {
473 fn default() -> Self {
474 Self::new()
475 }
476}
477
478impl HciUsbTransport {
479 pub fn new() -> Self {
481 Self {
482 device_addr: 0,
483 cmd_endpoint: 0x00,
484 evt_endpoint: 0x81,
485 acl_tx_endpoint: 0x02,
486 acl_rx_endpoint: 0x82,
487 intr_endpoint: 0x83,
488 active: false,
489 }
490 }
491
492 pub(crate) fn configure(&mut self, device_addr: u8) {
494 self.device_addr = device_addr;
495 self.active = true;
496 }
497
498 pub(crate) fn send_command(&self, _cmd: &HciCommand) -> Result<(), KernelError> {
500 if !self.active {
501 return Err(KernelError::InvalidState {
502 expected: "active",
503 actual: "inactive",
504 });
505 }
506 Ok(())
509 }
510
511 pub(crate) fn send_acl_data(
513 &self,
514 _header: &AclHeader,
515 _data: &[u8],
516 ) -> Result<(), KernelError> {
517 if !self.active {
518 return Err(KernelError::InvalidState {
519 expected: "active",
520 actual: "inactive",
521 });
522 }
523 Ok(())
524 }
525
526 pub(crate) fn poll_event(&self) -> Result<Option<HciEvent>, KernelError> {
528 if !self.active {
529 return Err(KernelError::InvalidState {
530 expected: "active",
531 actual: "inactive",
532 });
533 }
534 Ok(None)
536 }
537
538 pub(crate) fn poll_acl_data(
540 &self,
541 ) -> Result<Option<(AclHeader, [u8; ACL_MAX_DATA_LEN], usize)>, KernelError> {
542 if !self.active {
543 return Err(KernelError::InvalidState {
544 expected: "active",
545 actual: "inactive",
546 });
547 }
548 Ok(None)
549 }
550}
551
552pub const GIAC_LAP: u32 = 0x9E8B33;
558
559pub const LIAC_LAP: u32 = 0x9E8B00;
561
562#[derive(Debug, Clone, Copy, PartialEq, Eq)]
564#[repr(u8)]
565pub enum ScanEnable {
566 NoScans = 0x00,
568 InquiryScanOnly = 0x01,
570 PageScanOnly = 0x02,
572 InquiryAndPageScan = 0x03,
574}
575
576pub const MAX_DISCOVERED_DEVICES: usize = 16;
578
579#[derive(Debug, Clone, Copy)]
581pub struct DiscoveredDevice {
582 pub addr: BdAddr,
584 pub page_scan_rep_mode: u8,
586 pub class_of_device: u32,
588 pub clock_offset: u16,
590 pub rssi: i8,
592 pub name: [u8; 248],
594 pub name_len: usize,
596 pub valid: bool,
598}
599
600impl DiscoveredDevice {
601 pub const fn empty() -> Self {
602 Self {
603 addr: BD_ADDR_ZERO,
604 page_scan_rep_mode: 0,
605 class_of_device: 0,
606 clock_offset: 0,
607 rssi: 0,
608 name: [0u8; 248],
609 name_len: 0,
610 valid: false,
611 }
612 }
613}
614
615pub(crate) fn parse_eir_name(eir: &[u8]) -> Option<([u8; 248], usize)> {
618 let mut offset = 0;
619 while offset < eir.len() {
620 let length = eir[offset] as usize;
621 if length == 0 {
622 break;
623 }
624 if offset + 1 + length > eir.len() {
625 break;
626 }
627 let data_type = eir[offset + 1];
628 if data_type == 0x08 || data_type == 0x09 {
630 let name_data = &eir[offset + 2..offset + 1 + length];
631 let copy_len = name_data.len().min(248);
632 let mut name = [0u8; 248];
633 name[..copy_len].copy_from_slice(&name_data[..copy_len]);
634 return Some((name, copy_len));
635 }
636 offset += 1 + length;
637 }
638 None
639}
640
641pub const MAX_CONNECTIONS: usize = 8;
647
648#[derive(Debug, Clone, Copy, PartialEq, Eq)]
650pub enum ConnectionState {
651 Idle,
653 Connecting,
655 Connected,
657 Disconnecting,
659}
660
661#[derive(Debug, Clone, Copy)]
663pub struct HciConnection {
664 pub handle: u16,
666 pub remote_addr: BdAddr,
668 pub link_type: u8,
670 pub state: ConnectionState,
672 pub encrypted: bool,
674 pub link_key: [u8; 16],
676 pub has_link_key: bool,
678}
679
680impl HciConnection {
681 pub const fn empty() -> Self {
682 Self {
683 handle: 0,
684 remote_addr: BD_ADDR_ZERO,
685 link_type: 0x01,
686 state: ConnectionState::Idle,
687 encrypted: false,
688 link_key: [0u8; 16],
689 has_link_key: false,
690 }
691 }
692}
693
694pub const L2CAP_CID_SIGNALING: u16 = 0x0001;
700pub const L2CAP_CID_CONNECTIONLESS: u16 = 0x0002;
702pub const L2CAP_CID_ATT: u16 = 0x0004;
704pub const L2CAP_CID_LE_SIGNALING: u16 = 0x0005;
706pub const L2CAP_CID_SMP: u16 = 0x0006;
708
709#[derive(Debug, Clone, Copy, PartialEq, Eq)]
711pub struct L2capHeader {
712 pub length: u16,
714 pub cid: u16,
716}
717
718impl L2capHeader {
719 pub(crate) fn parse(buf: &[u8]) -> Result<Self, KernelError> {
721 if buf.len() < 4 {
722 return Err(KernelError::InvalidArgument {
723 name: "l2cap_buffer",
724 value: "too short for L2CAP header",
725 });
726 }
727 Ok(Self {
728 length: u16::from_le_bytes([buf[0], buf[1]]),
729 cid: u16::from_le_bytes([buf[2], buf[3]]),
730 })
731 }
732
733 pub(crate) fn serialize(&self, buf: &mut [u8]) -> Result<(), KernelError> {
735 if buf.len() < 4 {
736 return Err(KernelError::InvalidArgument {
737 name: "buffer",
738 value: "too small for L2CAP header",
739 });
740 }
741 buf[0..2].copy_from_slice(&self.length.to_le_bytes());
742 buf[2..4].copy_from_slice(&self.cid.to_le_bytes());
743 Ok(())
744 }
745}
746
747#[derive(Debug, Clone, Copy, PartialEq, Eq)]
749#[repr(u8)]
750pub enum L2capSignalCode {
751 ConnectionRequest = 0x02,
753 ConnectionResponse = 0x03,
755 ConfigurationRequest = 0x04,
757 ConfigurationResponse = 0x05,
759 DisconnectionRequest = 0x06,
761 DisconnectionResponse = 0x07,
763 InformationRequest = 0x0A,
765 InformationResponse = 0x0B,
767}
768
769#[derive(Debug, Clone, Copy, PartialEq, Eq)]
771pub struct L2capSignalHeader {
772 pub code: u8,
773 pub identifier: u8,
774 pub length: u16,
775}
776
777impl L2capSignalHeader {
778 pub(crate) fn parse(buf: &[u8]) -> Result<Self, KernelError> {
779 if buf.len() < 4 {
780 return Err(KernelError::InvalidArgument {
781 name: "signal_buffer",
782 value: "too short for L2CAP signal header",
783 });
784 }
785 Ok(Self {
786 code: buf[0],
787 identifier: buf[1],
788 length: u16::from_le_bytes([buf[2], buf[3]]),
789 })
790 }
791}
792
793#[derive(Debug, Clone, Copy, PartialEq, Eq)]
799#[repr(u8)]
800pub enum SdpPduId {
801 ErrorResponse = 0x01,
803 ServiceSearchRequest = 0x02,
805 ServiceSearchResponse = 0x03,
807 ServiceAttributeRequest = 0x04,
809 ServiceAttributeResponse = 0x05,
811 ServiceSearchAttributeRequest = 0x06,
813 ServiceSearchAttributeResponse = 0x07,
815}
816
817pub const UUID_SDP: u16 = 0x0001;
819pub const UUID_RFCOMM: u16 = 0x0003;
820pub const UUID_L2CAP: u16 = 0x0100;
821pub const UUID_SERIAL_PORT: u16 = 0x1101;
822pub const UUID_OBEX_PUSH: u16 = 0x1105;
823pub const UUID_A2DP_SOURCE: u16 = 0x110A;
824pub const UUID_A2DP_SINK: u16 = 0x110B;
825pub const UUID_HFP: u16 = 0x111E;
826pub const UUID_HID: u16 = 0x1124;
827
828#[derive(Debug, Clone, Copy)]
830pub struct SdpServiceRecord {
831 pub handle: u32,
833 pub service_class_uuid: u16,
835 pub protocol_channel: u16,
837 pub valid: bool,
839}
840
841impl SdpServiceRecord {
842 pub const fn empty() -> Self {
843 Self {
844 handle: 0,
845 service_class_uuid: 0,
846 protocol_channel: 0,
847 valid: false,
848 }
849 }
850}
851
852pub const MAX_SDP_RECORDS: usize = 8;
854
855pub(crate) fn sdp_uuid_match(record: &SdpServiceRecord, uuid: u16) -> bool {
857 record.valid && record.service_class_uuid == uuid
858}
859
860#[derive(Debug, Clone, Copy, PartialEq, Eq)]
866pub enum ControllerState {
867 Off,
869 Initializing,
871 Ready,
873 Scanning,
875 Connected,
877}
878
879#[derive(Debug, Clone, Copy, Default)]
881pub struct BluetoothStats {
882 pub commands_sent: u64,
883 pub events_received: u64,
884 pub acl_packets_sent: u64,
885 pub acl_packets_received: u64,
886 pub errors: u64,
887}
888
889pub struct BluetoothController {
891 state: ControllerState,
893 local_addr: BdAddr,
895 local_name: [u8; 248],
897 local_name_len: usize,
899 transport: HciUsbTransport,
901 connections: [HciConnection; MAX_CONNECTIONS],
903 connection_count: usize,
905 discovered: [DiscoveredDevice; MAX_DISCOVERED_DEVICES],
907 discovered_count: usize,
909 sdp_records: [SdpServiceRecord; MAX_SDP_RECORDS],
911 sdp_record_count: usize,
913 next_signal_id: u8,
915 stats: BluetoothStats,
917}
918
919impl fmt::Debug for BluetoothController {
920 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
921 f.debug_struct("BluetoothController")
922 .field("state", &self.state)
923 .field("local_addr", &format_args!("{:?}", self.local_addr))
924 .field("connections", &self.connection_count)
925 .field("discovered", &self.discovered_count)
926 .finish()
927 }
928}
929
930impl Default for BluetoothController {
931 fn default() -> Self {
932 Self::new()
933 }
934}
935
936impl BluetoothController {
937 pub fn new() -> Self {
939 Self {
940 state: ControllerState::Off,
941 local_addr: BD_ADDR_ZERO,
942 local_name: [0u8; 248],
943 local_name_len: 0,
944 transport: HciUsbTransport::new(),
945 connections: [HciConnection::empty(); MAX_CONNECTIONS],
946 connection_count: 0,
947 discovered: {
948 let empty = DiscoveredDevice::empty();
950 [empty; MAX_DISCOVERED_DEVICES]
951 },
952 discovered_count: 0,
953 sdp_records: [SdpServiceRecord::empty(); MAX_SDP_RECORDS],
954 sdp_record_count: 0,
955 next_signal_id: 1,
956 stats: BluetoothStats::default(),
957 }
958 }
959
960 pub(crate) fn state(&self) -> ControllerState {
962 self.state
963 }
964
965 pub(crate) fn local_addr(&self) -> &BdAddr {
967 &self.local_addr
968 }
969
970 pub(crate) fn stats(&self) -> &BluetoothStats {
972 &self.stats
973 }
974
975 pub(crate) fn connection_count(&self) -> usize {
977 self.connection_count
978 }
979
980 pub(crate) fn discovered_count(&self) -> usize {
982 self.discovered_count
983 }
984
985 pub(crate) fn initialize(&mut self, usb_device_addr: u8) -> Result<(), KernelError> {
989 if self.state != ControllerState::Off {
990 return Err(KernelError::InvalidState {
991 expected: "Off",
992 actual: "not Off",
993 });
994 }
995
996 self.state = ControllerState::Initializing;
997 self.transport.configure(usb_device_addr);
998
999 self.send_reset()?;
1001
1002 self.state = ControllerState::Ready;
1003 Ok(())
1004 }
1005
1006 pub(crate) fn send_reset(&mut self) -> Result<(), KernelError> {
1008 let cmd = HciCommand::new(HCI_RESET);
1009 self.transport.send_command(&cmd)?;
1010 self.stats.commands_sent += 1;
1011 Ok(())
1012 }
1013
1014 pub(crate) fn read_bd_addr(&mut self) -> Result<(), KernelError> {
1016 self.ensure_ready()?;
1017 let cmd = HciCommand::new(HCI_READ_BD_ADDR);
1018 self.transport.send_command(&cmd)?;
1019 self.stats.commands_sent += 1;
1020 Ok(())
1021 }
1022
1023 pub(crate) fn read_local_name(&mut self) -> Result<(), KernelError> {
1025 self.ensure_ready()?;
1026 let cmd = HciCommand::new(HCI_READ_LOCAL_NAME);
1027 self.transport.send_command(&cmd)?;
1028 self.stats.commands_sent += 1;
1029 Ok(())
1030 }
1031
1032 pub(crate) fn write_scan_enable(&mut self, mode: ScanEnable) -> Result<(), KernelError> {
1034 self.ensure_ready()?;
1035 let cmd = HciCommand::with_params(HCI_WRITE_SCAN_ENABLE, &[mode as u8])?;
1036 self.transport.send_command(&cmd)?;
1037 self.stats.commands_sent += 1;
1038 Ok(())
1039 }
1040
1041 pub(crate) fn start_inquiry(
1047 &mut self,
1048 inquiry_length: u8,
1049 max_responses: u8,
1050 ) -> Result<(), KernelError> {
1051 self.ensure_ready()?;
1052
1053 self.discovered_count = 0;
1055 for dev in &mut self.discovered {
1056 dev.valid = false;
1057 }
1058
1059 let lap_bytes = GIAC_LAP.to_le_bytes();
1062 let params = [
1063 lap_bytes[0],
1064 lap_bytes[1],
1065 lap_bytes[2],
1066 inquiry_length.clamp(1, 30),
1067 max_responses,
1068 ];
1069 let cmd = HciCommand::with_params(HCI_INQUIRY, ¶ms)?;
1070 self.transport.send_command(&cmd)?;
1071 self.stats.commands_sent += 1;
1072
1073 self.state = ControllerState::Scanning;
1074 Ok(())
1075 }
1076
1077 pub(crate) fn handle_inquiry_result(
1079 &mut self,
1080 addr: BdAddr,
1081 page_scan_rep_mode: u8,
1082 class_of_device: u32,
1083 clock_offset: u16,
1084 ) {
1085 if self.discovered_count >= MAX_DISCOVERED_DEVICES {
1086 return;
1087 }
1088
1089 for dev in &self.discovered[..self.discovered_count] {
1091 if dev.valid && dev.addr == addr {
1092 return;
1093 }
1094 }
1095
1096 let slot = &mut self.discovered[self.discovered_count];
1097 slot.addr = addr;
1098 slot.page_scan_rep_mode = page_scan_rep_mode;
1099 slot.class_of_device = class_of_device;
1100 slot.clock_offset = clock_offset;
1101 slot.valid = true;
1102 self.discovered_count += 1;
1103 }
1104
1105 pub(crate) fn handle_inquiry_complete(&mut self) {
1107 if self.state == ControllerState::Scanning {
1108 if self.connection_count > 0 {
1109 self.state = ControllerState::Connected;
1110 } else {
1111 self.state = ControllerState::Ready;
1112 }
1113 }
1114 }
1115
1116 pub(crate) fn get_discovered(&self, index: usize) -> Option<&DiscoveredDevice> {
1118 if index < self.discovered_count {
1119 let dev = &self.discovered[index];
1120 if dev.valid {
1121 return Some(dev);
1122 }
1123 }
1124 None
1125 }
1126
1127 pub(crate) fn create_connection(&mut self, addr: &BdAddr) -> Result<(), KernelError> {
1131 self.ensure_ready_or_connected()?;
1132
1133 if self.connection_count >= MAX_CONNECTIONS {
1134 return Err(KernelError::ResourceExhausted {
1135 resource: "bluetooth connections",
1136 });
1137 }
1138
1139 let mut params = [0u8; 13];
1143 params[0..6].copy_from_slice(addr);
1144 params[6..8].copy_from_slice(&0xCC18u16.to_le_bytes());
1146 params[8] = 0x02; params[9] = 0x00; params[10..12].copy_from_slice(&0x0000u16.to_le_bytes()); params[12] = 0x01; let cmd = HciCommand::with_params(HCI_CREATE_CONNECTION, ¶ms)?;
1152 self.transport.send_command(&cmd)?;
1153 self.stats.commands_sent += 1;
1154
1155 for conn in &mut self.connections {
1157 if conn.state == ConnectionState::Idle {
1158 conn.remote_addr = *addr;
1159 conn.state = ConnectionState::Connecting;
1160 break;
1161 }
1162 }
1163
1164 Ok(())
1165 }
1166
1167 pub(crate) fn handle_connection_complete(
1169 &mut self,
1170 status: u8,
1171 handle: u16,
1172 addr: &BdAddr,
1173 link_type: u8,
1174 ) -> Result<(), KernelError> {
1175 for conn in &mut self.connections {
1177 if conn.state == ConnectionState::Connecting && conn.remote_addr == *addr {
1178 if status == 0x00 {
1179 conn.handle = handle;
1180 conn.link_type = link_type;
1181 conn.state = ConnectionState::Connected;
1182 self.connection_count += 1;
1183 self.state = ControllerState::Connected;
1184 } else {
1185 conn.state = ConnectionState::Idle;
1186 conn.remote_addr = BD_ADDR_ZERO;
1187 }
1188 return Ok(());
1189 }
1190 }
1191 Err(KernelError::NotFound {
1192 resource: "connection slot",
1193 id: 0,
1194 })
1195 }
1196
1197 pub(crate) fn disconnect(&mut self, handle: u16, reason: u8) -> Result<(), KernelError> {
1199 let found = self.connections.iter_mut().any(|conn| {
1201 if conn.state == ConnectionState::Connected && conn.handle == handle {
1202 conn.state = ConnectionState::Disconnecting;
1203 true
1204 } else {
1205 false
1206 }
1207 });
1208
1209 if !found {
1210 return Err(KernelError::NotFound {
1211 resource: "connection",
1212 id: handle as u64,
1213 });
1214 }
1215
1216 let mut params = [0u8; 3];
1217 params[0..2].copy_from_slice(&handle.to_le_bytes());
1218 params[2] = reason;
1219
1220 let cmd = HciCommand::with_params(HCI_DISCONNECT, ¶ms)?;
1221 self.transport.send_command(&cmd)?;
1222 self.stats.commands_sent += 1;
1223 Ok(())
1224 }
1225
1226 pub(crate) fn handle_disconnection_complete(&mut self, _status: u8, handle: u16) {
1228 for conn in &mut self.connections {
1229 if conn.handle == handle
1230 && (conn.state == ConnectionState::Connected
1231 || conn.state == ConnectionState::Disconnecting)
1232 {
1233 *conn = HciConnection::empty();
1234 if self.connection_count > 0 {
1235 self.connection_count -= 1;
1236 }
1237 break;
1238 }
1239 }
1240
1241 if self.connection_count == 0 && self.state == ControllerState::Connected {
1242 self.state = ControllerState::Ready;
1243 }
1244 }
1245
1246 pub(crate) fn find_connection(&self, handle: u16) -> Option<&HciConnection> {
1248 self.connections
1249 .iter()
1250 .find(|c| c.state == ConnectionState::Connected && c.handle == handle)
1251 }
1252
1253 pub(crate) fn store_link_key(&mut self, addr: &BdAddr, key: &[u8; 16]) {
1255 for conn in &mut self.connections {
1256 if conn.state == ConnectionState::Connected && conn.remote_addr == *addr {
1257 conn.link_key = *key;
1258 conn.has_link_key = true;
1259 return;
1260 }
1261 }
1262 }
1263
1264 pub(crate) fn send_acl(&mut self, handle: u16, data: &[u8]) -> Result<(), KernelError> {
1268 let conn = self
1269 .connections
1270 .iter()
1271 .find(|c| c.state == ConnectionState::Connected && c.handle == handle);
1272 if conn.is_none() {
1273 return Err(KernelError::NotFound {
1274 resource: "connection",
1275 id: handle as u64,
1276 });
1277 }
1278 if data.len() > ACL_MAX_DATA_LEN {
1279 return Err(KernelError::InvalidArgument {
1280 name: "acl_data",
1281 value: "exceeds max ACL data length",
1282 });
1283 }
1284
1285 let header = AclHeader {
1286 handle,
1287 boundary: AclBoundaryFlag::FirstFlushable,
1288 broadcast: AclBroadcastFlag::PointToPoint,
1289 data_len: data.len() as u16,
1290 };
1291 self.transport.send_acl_data(&header, data)?;
1292 self.stats.acl_packets_sent += 1;
1293 Ok(())
1294 }
1295
1296 pub(crate) fn register_sdp_record(
1300 &mut self,
1301 uuid: u16,
1302 channel: u16,
1303 ) -> Result<u32, KernelError> {
1304 if self.sdp_record_count >= MAX_SDP_RECORDS {
1305 return Err(KernelError::ResourceExhausted {
1306 resource: "SDP service records",
1307 });
1308 }
1309 let handle = (self.sdp_record_count as u32) + 0x10000;
1310 let slot = &mut self.sdp_records[self.sdp_record_count];
1311 slot.handle = handle;
1312 slot.service_class_uuid = uuid;
1313 slot.protocol_channel = channel;
1314 slot.valid = true;
1315 self.sdp_record_count += 1;
1316 Ok(handle)
1317 }
1318
1319 pub(crate) fn sdp_search_local(&self, uuid: u16) -> Option<&SdpServiceRecord> {
1321 self.sdp_records[..self.sdp_record_count]
1322 .iter()
1323 .find(|r| sdp_uuid_match(r, uuid))
1324 }
1325
1326 pub(crate) fn process_event(&mut self, event: &HciEvent) {
1330 self.stats.events_received += 1;
1331
1332 match HciEventCode::from_u8(event.event_code) {
1333 Some(HciEventCode::CommandComplete) => {
1334 if let Some(opcode) = event.command_complete_opcode() {
1336 self.handle_command_complete(opcode, event);
1337 }
1338 }
1339 Some(HciEventCode::CommandStatus) => {
1340 }
1342 Some(HciEventCode::InquiryComplete) => {
1343 self.handle_inquiry_complete();
1344 }
1345 Some(HciEventCode::InquiryResult) => {
1346 self.process_inquiry_result(event);
1347 }
1348 Some(HciEventCode::ConnectionComplete) => {
1349 self.process_connection_complete(event);
1350 }
1351 Some(HciEventCode::DisconnectionComplete) => {
1352 self.process_disconnection_complete(event);
1353 }
1354 Some(HciEventCode::ExtendedInquiryResult) => {
1355 self.process_extended_inquiry_result(event);
1356 }
1357 _ => {
1358 }
1360 }
1361 }
1362
1363 fn handle_command_complete(&mut self, opcode: u16, event: &HciEvent) {
1365 match opcode {
1366 HCI_READ_BD_ADDR => {
1367 if event.param_len >= 10 {
1369 let status = event.params[3];
1370 if status == 0x00 {
1371 self.local_addr.copy_from_slice(&event.params[4..10]);
1372 }
1373 }
1374 }
1375 HCI_READ_LOCAL_NAME => {
1376 if event.param_len >= 5 {
1378 let status = event.params[3];
1379 if status == 0x00 {
1380 let name_start = 4;
1381 let name_end = (event.param_len as usize).min(252);
1382 let name_slice = &event.params[name_start..name_end];
1383 let len = name_slice
1385 .iter()
1386 .position(|&b| b == 0)
1387 .unwrap_or(name_slice.len());
1388 let copy_len = len.min(248);
1389 self.local_name[..copy_len].copy_from_slice(&name_slice[..copy_len]);
1390 self.local_name_len = copy_len;
1391 }
1392 }
1393 }
1394 HCI_RESET => {
1395 if event.param_len >= 4 && event.params[3] == 0x00 {
1396 self.state = ControllerState::Ready;
1397 }
1398 }
1399 _ => {}
1400 }
1401 }
1402
1403 fn process_inquiry_result(&mut self, event: &HciEvent) {
1405 if event.param_len < 1 {
1406 return;
1407 }
1408 let num_responses = event.params[0] as usize;
1409 let mut offset = 1;
1412 for _ in 0..num_responses {
1413 if offset + 14 > event.param_len as usize {
1414 break;
1415 }
1416 let mut addr = BD_ADDR_ZERO;
1417 addr.copy_from_slice(&event.params[offset..offset + 6]);
1418 let psrm = event.params[offset + 6];
1419 let cod = u32::from_le_bytes([
1421 event.params[offset + 9],
1422 event.params[offset + 10],
1423 event.params[offset + 11],
1424 0,
1425 ]);
1426 let clock = u16::from_le_bytes([event.params[offset + 12], event.params[offset + 13]]);
1427 self.handle_inquiry_result(addr, psrm, cod, clock);
1428 offset += 14;
1429 }
1430 }
1431
1432 fn process_connection_complete(&mut self, event: &HciEvent) {
1434 if event.param_len < 11 {
1436 return;
1437 }
1438 let status = event.params[0];
1439 let handle = u16::from_le_bytes([event.params[1], event.params[2]]);
1440 let mut addr = BD_ADDR_ZERO;
1441 addr.copy_from_slice(&event.params[3..9]);
1442 let link_type = event.params[9];
1443 let _ = self.handle_connection_complete(status, handle, &addr, link_type);
1444 }
1445
1446 fn process_disconnection_complete(&mut self, event: &HciEvent) {
1448 if event.param_len < 4 {
1450 return;
1451 }
1452 let status = event.params[0];
1453 let handle = u16::from_le_bytes([event.params[1], event.params[2]]);
1454 self.handle_disconnection_complete(status, handle);
1455 }
1456
1457 fn process_extended_inquiry_result(&mut self, event: &HciEvent) {
1459 if event.param_len < 15 {
1462 return;
1463 }
1464 let mut addr = BD_ADDR_ZERO;
1465 addr.copy_from_slice(&event.params[1..7]);
1466 let psrm = event.params[7];
1467 let cod = u32::from_le_bytes([event.params[9], event.params[10], event.params[11], 0]);
1468 let clock = u16::from_le_bytes([event.params[12], event.params[13]]);
1469 let rssi = event.params[14] as i8;
1470
1471 self.handle_inquiry_result(addr, psrm, cod, clock);
1472
1473 if event.param_len > 15 {
1475 let eir_data = &event.params[15..event.param_len as usize];
1476 if let Some((name, name_len)) = parse_eir_name(eir_data) {
1477 for dev in &mut self.discovered[..self.discovered_count] {
1479 if dev.valid && dev.addr == addr {
1480 dev.name = name;
1481 dev.name_len = name_len;
1482 dev.rssi = rssi;
1483 break;
1484 }
1485 }
1486 }
1487 }
1488 }
1489
1490 pub(crate) fn poll(&mut self) -> Result<(), KernelError> {
1492 if self.state == ControllerState::Off {
1493 return Ok(());
1494 }
1495
1496 if let Some(event) = self.transport.poll_event()? {
1498 self.process_event(&event);
1499 }
1500
1501 if let Some((_header, _data, _len)) = self.transport.poll_acl_data()? {
1503 self.stats.acl_packets_received += 1;
1504 }
1505
1506 Ok(())
1507 }
1508
1509 fn ensure_ready(&self) -> Result<(), KernelError> {
1512 match self.state {
1513 ControllerState::Ready | ControllerState::Scanning | ControllerState::Connected => {
1514 Ok(())
1515 }
1516 ControllerState::Off => Err(KernelError::InvalidState {
1517 expected: "Ready",
1518 actual: "Off",
1519 }),
1520 ControllerState::Initializing => Err(KernelError::InvalidState {
1521 expected: "Ready",
1522 actual: "Initializing",
1523 }),
1524 }
1525 }
1526
1527 fn ensure_ready_or_connected(&self) -> Result<(), KernelError> {
1528 match self.state {
1529 ControllerState::Ready | ControllerState::Connected => Ok(()),
1530 _ => Err(KernelError::InvalidState {
1531 expected: "Ready or Connected",
1532 actual: "other",
1533 }),
1534 }
1535 }
1536
1537 fn next_signal_identifier(&mut self) -> u8 {
1538 let id = self.next_signal_id;
1539 self.next_signal_id = self.next_signal_id.wrapping_add(1);
1540 if self.next_signal_id == 0 {
1541 self.next_signal_id = 1; }
1543 id
1544 }
1545}
1546
1547pub fn init() {
1553 crate::println!("[BT-HCI] HCI driver initialized");
1554}
1555
1556#[cfg(test)]
1561mod tests {
1562 use super::*;
1563
1564 #[test]
1565 fn test_make_opcode() {
1566 let op = make_opcode(0x03, 0x0003);
1568 assert_eq!(opcode_ogf(op), 0x03);
1569 assert_eq!(opcode_ocf(op), 0x0003);
1570 assert_eq!(op, HCI_RESET);
1571 }
1572
1573 #[test]
1574 fn test_opcode_constants() {
1575 assert_eq!(opcode_ogf(HCI_INQUIRY), 0x01);
1576 assert_eq!(opcode_ocf(HCI_INQUIRY), 0x0001);
1577 assert_eq!(opcode_ogf(HCI_READ_BD_ADDR), 0x04);
1578 assert_eq!(opcode_ocf(HCI_READ_BD_ADDR), 0x0009);
1579 assert_eq!(opcode_ogf(HCI_WRITE_SCAN_ENABLE), 0x03);
1580 assert_eq!(opcode_ocf(HCI_WRITE_SCAN_ENABLE), 0x001A);
1581 }
1582
1583 #[test]
1584 fn test_hci_packet_type_roundtrip() {
1585 assert_eq!(HciPacketType::from_u8(0x01), Some(HciPacketType::Command));
1586 assert_eq!(HciPacketType::from_u8(0x02), Some(HciPacketType::AclData));
1587 assert_eq!(HciPacketType::from_u8(0x03), Some(HciPacketType::ScoData));
1588 assert_eq!(HciPacketType::from_u8(0x04), Some(HciPacketType::Event));
1589 assert_eq!(HciPacketType::from_u8(0x05), None);
1590 }
1591
1592 #[test]
1593 fn test_hci_command_no_params() {
1594 let cmd = HciCommand::new(HCI_RESET);
1595 assert_eq!(cmd.opcode, HCI_RESET);
1596 assert_eq!(cmd.param_len, 0);
1597 }
1598
1599 #[test]
1600 fn test_hci_command_with_params() {
1601 let params = [0x03u8]; let cmd = HciCommand::with_params(HCI_WRITE_SCAN_ENABLE, ¶ms).unwrap();
1603 assert_eq!(cmd.opcode, HCI_WRITE_SCAN_ENABLE);
1604 assert_eq!(cmd.param_len, 1);
1605 assert_eq!(cmd.params[0], 0x03);
1606 }
1607
1608 #[test]
1609 fn test_hci_command_serialize() {
1610 let cmd = HciCommand::new(HCI_RESET);
1611 let mut buf = [0u8; 16];
1612 let len = cmd.serialize(&mut buf).unwrap();
1613 assert_eq!(len, 4); assert_eq!(buf[0], 0x01); assert_eq!(u16::from_le_bytes([buf[1], buf[2]]), HCI_RESET);
1616 assert_eq!(buf[3], 0); }
1618
1619 #[test]
1620 fn test_hci_event_parse() {
1621 let raw = [
1623 0x0E, 0x04, 0x01, 0x03, 0x0C, 0x00, ];
1629 let evt = HciEvent::parse(&raw).unwrap();
1630 assert_eq!(evt.event_code, 0x0E);
1631 assert_eq!(evt.param_len, 4);
1632 assert!(evt.is_command_complete());
1633 assert!(!evt.is_command_status());
1634 assert_eq!(evt.command_complete_opcode(), Some(HCI_RESET));
1635 assert_eq!(evt.command_complete_status(), Some(0x00));
1636 }
1637
1638 #[test]
1639 fn test_acl_header_roundtrip() {
1640 let header = AclHeader {
1641 handle: 0x0042,
1642 boundary: AclBoundaryFlag::FirstFlushable,
1643 broadcast: AclBroadcastFlag::PointToPoint,
1644 data_len: 128,
1645 };
1646 let mut buf = [0u8; 4];
1647 header.serialize(&mut buf).unwrap();
1648 let parsed = AclHeader::parse(&buf).unwrap();
1649 assert_eq!(parsed.handle, 0x0042);
1650 assert_eq!(parsed.boundary, AclBoundaryFlag::FirstFlushable);
1651 assert_eq!(parsed.broadcast, AclBroadcastFlag::PointToPoint);
1652 assert_eq!(parsed.data_len, 128);
1653 }
1654
1655 #[test]
1656 fn test_l2cap_header_roundtrip() {
1657 let hdr = L2capHeader {
1658 length: 48,
1659 cid: L2CAP_CID_ATT,
1660 };
1661 let mut buf = [0u8; 4];
1662 hdr.serialize(&mut buf).unwrap();
1663 let parsed = L2capHeader::parse(&buf).unwrap();
1664 assert_eq!(parsed.length, 48);
1665 assert_eq!(parsed.cid, L2CAP_CID_ATT);
1666 }
1667
1668 #[test]
1669 fn test_controller_state_machine() {
1670 let mut ctrl = BluetoothController::new();
1671 assert_eq!(ctrl.state(), ControllerState::Off);
1672
1673 ctrl.initialize(1).unwrap();
1675 assert_eq!(ctrl.state(), ControllerState::Ready);
1676
1677 assert!(ctrl.initialize(2).is_err());
1679 }
1680
1681 #[test]
1682 fn test_inquiry_result_handling() {
1683 let mut ctrl = BluetoothController::new();
1684 ctrl.state = ControllerState::Scanning;
1685
1686 let addr: BdAddr = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
1687 ctrl.handle_inquiry_result(addr, 0x01, 0x001F00, 0x0000);
1688 assert_eq!(ctrl.discovered_count(), 1);
1689
1690 let dev = ctrl.get_discovered(0).unwrap();
1691 assert_eq!(dev.addr, addr);
1692 assert_eq!(dev.class_of_device, 0x001F00);
1693
1694 ctrl.handle_inquiry_result(addr, 0x01, 0x001F00, 0x0000);
1696 assert_eq!(ctrl.discovered_count(), 1);
1697 }
1698
1699 #[test]
1700 fn test_eir_name_parsing() {
1701 let eir = [
1703 0x05, 0x09, b'T', b'e', b's', b't', 0x00, ];
1708 let (name, len) = parse_eir_name(&eir).unwrap();
1709 assert_eq!(len, 4);
1710 assert_eq!(&name[..4], b"Test");
1711 }
1712
1713 #[test]
1714 fn test_sdp_record_registration() {
1715 let mut ctrl = BluetoothController::new();
1716 let handle = ctrl.register_sdp_record(UUID_SERIAL_PORT, 1).unwrap();
1717 assert!(handle >= 0x10000);
1718
1719 let record = ctrl.sdp_search_local(UUID_SERIAL_PORT);
1720 assert!(record.is_some());
1721 assert_eq!(record.unwrap().protocol_channel, 1);
1722
1723 assert!(ctrl.sdp_search_local(UUID_HID).is_none());
1725 }
1726
1727 #[test]
1728 fn test_connection_lifecycle() {
1729 let mut ctrl = BluetoothController::new();
1730 ctrl.state = ControllerState::Ready;
1731 ctrl.transport.active = true;
1732
1733 let addr: BdAddr = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF];
1734 ctrl.create_connection(&addr).unwrap();
1735
1736 ctrl.handle_connection_complete(0x00, 0x0040, &addr, 0x01)
1738 .unwrap();
1739 assert_eq!(ctrl.connection_count(), 1);
1740 assert_eq!(ctrl.state(), ControllerState::Connected);
1741 assert!(ctrl.find_connection(0x0040).is_some());
1742
1743 ctrl.disconnect(0x0040, 0x13).unwrap(); ctrl.handle_disconnection_complete(0x00, 0x0040);
1746 assert_eq!(ctrl.connection_count(), 0);
1747 assert_eq!(ctrl.state(), ControllerState::Ready);
1748 }
1749
1750 #[test]
1751 fn test_format_bd_addr() {
1752 let addr: BdAddr = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF];
1753 let formatted = format_bd_addr(&addr);
1754 assert_eq!(&formatted, b"FF:EE:DD:CC:BB:AA");
1755 }
1756}