veridian_kernel/drivers/bluetooth/
device_node.rs1#![allow(dead_code)]
19
20use core::result::Result;
21
22use spin::Mutex;
23
24use crate::error::KernelError;
25
26const EVENT_QUEUE_CAPACITY: usize = 32;
32
33const MAX_EVENT_SIZE: usize = 259;
35
36const MAX_COMMAND_SIZE: usize = 259;
38
39const H4_COMMAND: u8 = 0x01;
41
42const H4_EVENT: u8 = 0x04;
44
45pub const BT_DEVICE_PATH: &str = "/dev/bluetooth/hci0";
47
48pub const BT_IOCTL_GET_ADAPTER_INFO: u32 = 0x4201;
54
55pub const BT_IOCTL_SET_SCAN_MODE: u32 = 0x4202;
57
58pub const BT_IOCTL_RESET: u32 = 0x4203;
60
61#[derive(Clone)]
67struct EventEntry {
68 data: [u8; MAX_EVENT_SIZE],
70 len: usize,
72}
73
74impl Default for EventEntry {
75 fn default() -> Self {
76 Self {
77 data: [0u8; MAX_EVENT_SIZE],
78 len: 0,
79 }
80 }
81}
82
83struct EventQueue {
89 entries: [EventEntry; EVENT_QUEUE_CAPACITY],
90 head: usize,
91 tail: usize,
92 count: usize,
93}
94
95impl EventQueue {
96 const fn new() -> Self {
97 Self {
100 entries: [const {
101 EventEntry {
102 data: [0u8; MAX_EVENT_SIZE],
103 len: 0,
104 }
105 }; EVENT_QUEUE_CAPACITY],
106 head: 0,
107 tail: 0,
108 count: 0,
109 }
110 }
111
112 fn push(&mut self, data: &[u8]) -> Result<(), KernelError> {
114 if self.count >= EVENT_QUEUE_CAPACITY {
115 return Err(KernelError::ResourceExhausted {
116 resource: "bluetooth event queue",
117 });
118 }
119
120 if data.len() > MAX_EVENT_SIZE {
121 return Err(KernelError::InvalidArgument {
122 name: "event_data",
123 value: "exceeds maximum event size",
124 });
125 }
126
127 let entry = &mut self.entries[self.tail];
128 entry.data[..data.len()].copy_from_slice(data);
129 entry.len = data.len();
130
131 self.tail = (self.tail + 1) % EVENT_QUEUE_CAPACITY;
132 self.count += 1;
133 Ok(())
134 }
135
136 fn pop(&mut self) -> Option<(usize, [u8; MAX_EVENT_SIZE])> {
138 if self.count == 0 {
139 return None;
140 }
141
142 let entry = &self.entries[self.head];
143 let len = entry.len;
144 let data = entry.data;
145
146 self.head = (self.head + 1) % EVENT_QUEUE_CAPACITY;
147 self.count -= 1;
148
149 Some((len, data))
150 }
151
152 fn is_empty(&self) -> bool {
154 self.count == 0
155 }
156
157 fn len(&self) -> usize {
159 self.count
160 }
161}
162
163#[derive(Debug, Clone, Copy, PartialEq, Eq)]
169pub struct BtDeviceHandle {
170 index: u32,
172 open: bool,
174}
175
176struct DeviceNodeState {
182 event_queue: EventQueue,
184 initialized: bool,
186 open_count: u32,
188}
189
190impl DeviceNodeState {
191 const fn new() -> Self {
192 Self {
193 event_queue: EventQueue::new(),
194 initialized: false,
195 open_count: 0,
196 }
197 }
198}
199
200static DEVICE_NODE: Mutex<DeviceNodeState> = Mutex::new(DeviceNodeState::new());
202
203pub fn init() -> Result<(), KernelError> {
211 let mut state = DEVICE_NODE.lock();
212
213 if state.initialized {
214 return Err(KernelError::InvalidArgument {
215 name: "bt_device_node",
216 value: "already initialized",
217 });
218 }
219
220 state.initialized = true;
221
222 crate::println!("[BT] Device node {} registered", BT_DEVICE_PATH);
223 Ok(())
224}
225
226pub fn bt_device_open() -> Result<BtDeviceHandle, KernelError> {
233 let mut state = DEVICE_NODE.lock();
234
235 if !state.initialized {
236 return Err(KernelError::InvalidArgument {
237 name: "bt_device_node",
238 value: "not initialized",
239 });
240 }
241
242 state.open_count += 1;
243
244 Ok(BtDeviceHandle {
245 index: 0,
246 open: true,
247 })
248}
249
250pub fn bt_device_close(handle: &mut BtDeviceHandle) -> Result<(), KernelError> {
252 if !handle.open {
253 return Err(KernelError::InvalidArgument {
254 name: "handle",
255 value: "not open",
256 });
257 }
258
259 let mut state = DEVICE_NODE.lock();
260 if state.open_count > 0 {
261 state.open_count -= 1;
262 }
263
264 handle.open = false;
265 Ok(())
266}
267
268pub fn bt_device_write(handle: &BtDeviceHandle, data: &[u8]) -> Result<usize, KernelError> {
276 if !handle.open {
277 return Err(KernelError::InvalidArgument {
278 name: "handle",
279 value: "not open",
280 });
281 }
282
283 if data.is_empty() {
284 return Err(KernelError::InvalidArgument {
285 name: "data",
286 value: "empty write buffer",
287 });
288 }
289
290 if data.len() > MAX_COMMAND_SIZE {
291 return Err(KernelError::InvalidArgument {
292 name: "data",
293 value: "exceeds maximum command size",
294 });
295 }
296
297 if data[0] != H4_COMMAND {
299 return Err(KernelError::InvalidArgument {
300 name: "packet_type",
301 value: "expected HCI command (0x01)",
302 });
303 }
304
305 if data.len() < 4 {
307 return Err(KernelError::InvalidArgument {
308 name: "command",
309 value: "too short for HCI command header",
310 });
311 }
312
313 let opcode = u16::from_le_bytes([data[1], data[2]]);
314 let param_len = data[3] as usize;
315
316 if data.len() < 4 + param_len {
318 return Err(KernelError::InvalidArgument {
319 name: "command",
320 value: "truncated command parameters",
321 });
322 }
323
324 let controller = super::get_controller();
328 let mut ctrl = controller.lock();
329
330 match opcode {
331 super::hci::HCI_RESET => {
332 let _result = ctrl.send_reset();
333 }
334 super::hci::HCI_READ_BD_ADDR => {
335 let _result = ctrl.read_bd_addr();
336 }
337 super::hci::HCI_READ_LOCAL_NAME => {
338 let _result = ctrl.read_local_name();
339 }
340 super::hci::HCI_WRITE_SCAN_ENABLE => {
341 if param_len >= 1 {
342 let mode = match data[4] {
343 0x00 => super::hci::ScanEnable::NoScans,
344 0x01 => super::hci::ScanEnable::InquiryScanOnly,
345 0x02 => super::hci::ScanEnable::PageScanOnly,
346 _ => super::hci::ScanEnable::InquiryAndPageScan,
347 };
348 let _result = ctrl.write_scan_enable(mode);
349 }
350 }
351 super::hci::HCI_INQUIRY => {
352 if param_len >= 5 {
353 let inquiry_length = data[7]; let max_responses = data[8]; let _result = ctrl.start_inquiry(inquiry_length, max_responses);
356 }
357 }
358 super::hci::HCI_CREATE_CONNECTION => {
359 if param_len >= 6 {
360 let mut addr = [0u8; 6];
361 addr.copy_from_slice(&data[4..10]);
362 let _result = ctrl.create_connection(&addr);
363 }
364 }
365 super::hci::HCI_DISCONNECT => {
366 if param_len >= 3 {
367 let handle = u16::from_le_bytes([data[4], data[5]]);
368 let reason = data[6];
369 let _result = ctrl.disconnect(handle, reason);
370 }
371 }
372 _ => {
373 }
375 }
376
377 Ok(data.len())
378}
379
380pub fn bt_device_read(handle: &BtDeviceHandle, buf: &mut [u8]) -> Result<usize, KernelError> {
387 if !handle.open {
388 return Err(KernelError::InvalidArgument {
389 name: "handle",
390 value: "not open",
391 });
392 }
393
394 if buf.is_empty() {
395 return Err(KernelError::InvalidArgument {
396 name: "buf",
397 value: "empty read buffer",
398 });
399 }
400
401 let mut state = DEVICE_NODE.lock();
402
403 match state.event_queue.pop() {
404 Some((len, data)) => {
405 let copy_len = core::cmp::min(len, buf.len());
406 buf[..copy_len].copy_from_slice(&data[..copy_len]);
407 Ok(copy_len)
408 }
409 None => Ok(0), }
411}
412
413pub fn bt_device_ioctl(handle: &BtDeviceHandle, cmd: u32, arg: u64) -> Result<u64, KernelError> {
420 if !handle.open {
421 return Err(KernelError::InvalidArgument {
422 name: "handle",
423 value: "not open",
424 });
425 }
426
427 match cmd {
428 BT_IOCTL_GET_ADAPTER_INFO => {
429 let controller = super::get_controller();
433 let ctrl = controller.lock();
434
435 let state_val: u8 = match ctrl.state() {
436 super::ControllerState::Off => 0,
437 super::ControllerState::Initializing => 1,
438 super::ControllerState::Ready => 2,
439 super::ControllerState::Scanning => 3,
440 super::ControllerState::Connected => 4,
441 };
442
443 let dev_state = DEVICE_NODE.lock();
444 let result = (state_val as u64) | ((dev_state.open_count as u64) << 8);
445 Ok(result)
446 }
447
448 BT_IOCTL_SET_SCAN_MODE => {
449 let scan_mode = (arg & 0xFF) as u8;
450 let controller = super::get_controller();
451 let mut ctrl = controller.lock();
452
453 let mode = match scan_mode {
454 0x00 => super::hci::ScanEnable::NoScans,
455 0x01 => super::hci::ScanEnable::InquiryScanOnly,
456 0x02 => super::hci::ScanEnable::PageScanOnly,
457 _ => super::hci::ScanEnable::InquiryAndPageScan,
458 };
459 let _result = ctrl.write_scan_enable(mode);
460 Ok(0)
461 }
462
463 BT_IOCTL_RESET => {
464 let controller = super::get_controller();
465 let mut ctrl = controller.lock();
466
467 let _result = ctrl.send_reset();
468 Ok(0)
469 }
470
471 _ => Err(KernelError::InvalidArgument {
472 name: "ioctl_cmd",
473 value: "unknown ioctl command",
474 }),
475 }
476}
477
478pub fn push_event(data: &[u8]) -> Result<(), KernelError> {
489 let mut state = DEVICE_NODE.lock();
490
491 if !state.initialized {
492 return Err(KernelError::InvalidArgument {
493 name: "bt_device_node",
494 value: "not initialized",
495 });
496 }
497
498 state.event_queue.push(data)
499}
500
501pub fn pending_event_count() -> usize {
503 let state = DEVICE_NODE.lock();
504 state.event_queue.len()
505}
506
507#[cfg(test)]
512mod tests {
513 use super::*;
514
515 #[test]
516 fn test_event_queue_push_pop() {
517 let mut queue = EventQueue::new();
518
519 assert!(queue.is_empty());
520 assert_eq!(queue.len(), 0);
521
522 let event_data = [H4_EVENT, 0x0E, 0x04, 0x01, 0x00, 0x00, 0x00];
524 assert!(queue.push(&event_data).is_ok());
525 assert!(!queue.is_empty());
526 assert_eq!(queue.len(), 1);
527
528 let result = queue.pop();
530 assert!(result.is_some());
531 let (len, data) = result.unwrap();
532 assert_eq!(len, event_data.len());
533 assert_eq!(&data[..len], &event_data);
534 assert!(queue.is_empty());
535 }
536
537 #[test]
538 fn test_event_queue_overflow() {
539 let mut queue = EventQueue::new();
540
541 let event_data = [H4_EVENT, 0x01, 0x01, 0x00];
542
543 for _ in 0..EVENT_QUEUE_CAPACITY {
545 assert!(queue.push(&event_data).is_ok());
546 }
547
548 assert!(queue.push(&event_data).is_err());
550 assert_eq!(queue.len(), EVENT_QUEUE_CAPACITY);
551 }
552
553 #[test]
554 fn test_event_queue_wrap_around() {
555 let mut queue = EventQueue::new();
556
557 let event_data = [H4_EVENT, 0x02, 0x02, 0xAA, 0xBB];
558
559 for i in 0..EVENT_QUEUE_CAPACITY * 2 {
561 assert!(queue.push(&event_data).is_ok());
562 let result = queue.pop();
563 assert!(result.is_some());
564 let (len, _data) = result.unwrap();
565 assert_eq!(len, event_data.len());
566 let _ = i;
567 }
568
569 assert!(queue.is_empty());
570 }
571
572 #[test]
573 fn test_event_queue_empty_pop() {
574 let mut queue = EventQueue::new();
575 assert!(queue.pop().is_none());
576 }
577
578 #[test]
579 fn test_event_queue_oversized_event() {
580 let mut queue = EventQueue::new();
581 let big_event = [0u8; MAX_EVENT_SIZE + 1];
582 assert!(queue.push(&big_event).is_err());
583 }
584}