1use alloc::boxed::Box;
2use core::{
3 mem::transmute,
4 ptr::{addr_of, addr_of_mut},
5};
6
7use esp_hal::time::Instant;
8use esp_phy::{PhyController, PhyInitGuard};
9
10use super::*;
11use crate::{
12 binary::{c_types::*, include::*},
13 compat::{self, OSI_FUNCS_TIME_BLOCKING, common::str_from_c, queue},
14 time::{blob_ticks_to_micros, blob_ticks_to_millis, millis_to_blob_ticks},
15};
16
17#[cfg_attr(esp32c2, path = "os_adapter_esp32c2.rs")]
18#[cfg_attr(esp32c6, path = "os_adapter_esp32c6.rs")]
19#[cfg_attr(esp32h2, path = "os_adapter_esp32h2.rs")]
20pub(crate) mod ble_os_adapter_chip_specific;
21
22const EVENT_QUEUE_SIZE: usize = 16;
23
24const TIME_FOREVER: u32 = crate::compat::OSI_FUNCS_TIME_BLOCKING;
25
26#[cfg(esp32c2)]
27const OS_MSYS_1_BLOCK_COUNT: i32 = 24;
28#[cfg(esp32c2)]
29const SYSINIT_MSYS_1_MEMPOOL_SIZE: usize = 768;
30#[cfg(esp32c2)]
31const SYSINIT_MSYS_1_MEMBLOCK_SIZE: i32 = 128;
32#[cfg(esp32c2)]
33const OS_MSYS_2_BLOCK_COUNT: i32 = 24;
34#[cfg(esp32c2)]
35const SYSINIT_MSYS_2_MEMPOOL_SIZE: usize = 1920;
36#[cfg(esp32c2)]
37const SYSINIT_MSYS_2_MEMBLOCK_SIZE: i32 = 320;
38
39const BLE_HCI_TRANS_BUF_CMD: i32 = 3;
40
41const ACL_DATA_MBUF_LEADINGSPACE: usize = 4;
43
44#[repr(C)]
45#[derive(Copy, Clone)]
46struct Callout {
47 eventq: *const ble_npl_eventq,
48 timer_handle: ets_timer,
49 events: ble_npl_event,
50}
51
52#[repr(C)]
53#[derive(Copy, Clone)]
54struct Event {
55 event_fn_ptr: *const ble_npl_event_fn,
56 ev_arg_ptr: *const c_void,
57 queued: bool,
58}
59
60#[cfg(esp32c2)]
61type OsMembufT = u32;
62
63#[repr(C)]
65pub(crate) struct OsMempool {
66 mp_block_size: u32,
68 mp_num_blocks: u16,
70 mp_num_free: u16,
72 mp_min_free: u16,
74 mp_flags: u8,
76 mp_membuf_addr: u32,
78
79 next: *const OsMempool,
81
82 first: *const c_void,
84
85 name: *const u8,
87}
88
89#[cfg(esp32c2)]
90impl OsMempool {
91 const fn zeroed() -> Self {
92 Self {
93 mp_block_size: 0,
94 mp_num_blocks: 0,
95 mp_num_free: 0,
96 mp_min_free: 0,
97 mp_flags: 0,
98 mp_membuf_addr: 0,
99 next: core::ptr::null(),
100 first: core::ptr::null(),
101 name: core::ptr::null(),
102 }
103 }
104}
105
106#[repr(C)]
112pub(crate) struct OsMbufPool {
113 omp_databuf_len: u16,
116 omp_pool: *const OsMempool,
118
119 next: *const OsMbufPool,
121}
122
123#[cfg(esp32c2)]
124impl OsMbufPool {
125 const fn zeroed() -> Self {
126 Self {
127 omp_databuf_len: 0,
128 omp_pool: core::ptr::null(),
129 next: core::ptr::null(),
130 }
131 }
132}
133
134#[repr(C)]
136pub(crate) struct OsMbuf {
137 om_data: *const u8,
139 om_flags: u8,
141 om_pkthdr_len: u8,
143 om_len: u16,
145
146 om_omp: *const OsMbufPool,
148
149 next: *const OsMbuf,
151
152 om_databuf: u32,
154}
155
156#[cfg(esp32c2)]
157pub(crate) static mut OS_MSYS_INIT_1_DATA: *mut OsMembufT = core::ptr::null_mut();
158#[cfg(esp32c2)]
159pub(crate) static mut OS_MSYS_INIT_1_MBUF_POOL: OsMbufPool = OsMbufPool::zeroed();
160#[cfg(esp32c2)]
161pub(crate) static mut OS_MSYS_INIT_1_MEMPOOL: OsMempool = OsMempool::zeroed();
162
163#[cfg(esp32c2)]
164pub(crate) static mut OS_MSYS_INIT_2_DATA: *mut OsMembufT = core::ptr::null_mut();
165#[cfg(esp32c2)]
166pub(crate) static mut OS_MSYS_INIT_2_MBUF_POOL: OsMbufPool = OsMbufPool::zeroed();
167#[cfg(esp32c2)]
168pub(crate) static mut OS_MSYS_INIT_2_MEMPOOL: OsMempool = OsMempool::zeroed();
169
170unsafe extern "C" {
171 pub(crate) fn r_ble_hci_trans_hs_acl_tx(om: *const OsMbuf) -> i32;
178
179 pub(crate) fn r_ble_hci_trans_hs_cmd_tx(cmd: *const u8) -> i32;
187
188 #[cfg(esp32c2)]
189 pub(crate) fn ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32;
190
191 #[cfg(not(esp32c2))]
192 pub(crate) fn r_ble_controller_disable() -> i32;
193
194 #[cfg(not(esp32c2))]
195 pub(crate) fn r_ble_controller_deinit() -> i32;
196
197 #[cfg(esp32c2)]
198 pub(crate) fn ble_controller_deinit() -> i32;
199
200 #[cfg(not(esp32c2))]
201 pub(crate) fn r_ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32;
202
203 #[cfg(esp32c2)]
204 pub(crate) fn ble_controller_enable(mode: u8) -> i32;
205
206 #[cfg(not(esp32c2))]
207 pub(crate) fn r_ble_controller_enable(mode: u8) -> i32;
208
209 pub(crate) fn esp_unregister_ext_funcs();
210
211 pub(crate) fn esp_register_ext_funcs(funcs: *const ExtFuncsT) -> i32;
212
213 pub(crate) fn esp_register_npl_funcs(funcs: *const npl_funcs_t) -> i32;
214
215 pub(crate) fn esp_unregister_npl_funcs();
216
217 #[cfg(esp32c2)]
218 pub(crate) fn ble_get_npl_element_info(
219 cfg: *const esp_bt_controller_config_t,
220 npl_info: *const BleNplCountInfoT,
221 ) -> i32;
222
223 #[cfg(not(esp32c2))]
224 pub(crate) fn r_ble_get_npl_element_info(
225 cfg: *const esp_bt_controller_config_t,
226 npl_info: *const BleNplCountInfoT,
227 ) -> i32;
228
229 pub(crate) fn bt_bb_v2_init_cmplx(value: u8);
230
231 pub(crate) fn r_ble_hci_trans_cfg_hs(
232 evt: Option<unsafe extern "C" fn(cmd: *const u8, arg: *const c_void) -> i32>,
234 evt_arg: *const c_void,
235 acl_cb: Option<unsafe extern "C" fn(om: *const OsMbuf, arg: *const c_void) -> i32>,
237 acl_arg: *const c_void,
238 );
239
240 #[cfg(esp32c2)]
241 pub(crate) fn esp_ble_ll_set_public_addr(addr: *const u8);
242
243 #[cfg(not(esp32c2))]
244 pub(crate) fn r_esp_ble_ll_set_public_addr(addr: *const u8);
245
246 #[cfg(esp32c2)]
247 pub(crate) fn r_mem_init_mbuf_pool(
248 mem: *const c_void,
249 mempool: *const OsMempool,
250 mbuf_pool: *const OsMbufPool,
251 num_blocks: i32,
252 block_size: i32,
253 name: *const u8,
254 ) -> i32;
255
256 #[cfg(esp32c2)]
257 pub(crate) fn r_os_msys_reset();
258
259 #[cfg(esp32c2)]
260 pub(crate) fn r_os_msys_register(mbuf_pool: *const OsMbufPool) -> i32;
261
262 #[allow(unused)]
263 pub(crate) fn ble_osi_coex_funcs_register(coex_funcs: *const OsiCoexFuncsT) -> i32;
264
265 pub(crate) fn r_os_msys_get_pkthdr(dsize: u16, user_hdr_len: u16) -> *mut OsMbuf;
266
267 pub(crate) fn r_os_mbuf_append(om: *mut OsMbuf, src: *const u8, len: u16) -> i32;
268
269 pub(crate) fn r_os_mbuf_free_chain(om: *mut OsMbuf) -> i32;
270
271 pub(crate) fn r_ble_hci_trans_buf_alloc(typ: i32) -> *const u8;
272
273 pub(crate) fn r_ble_hci_trans_buf_free(buf: *const u8);
274
275 pub(crate) fn coex_pti_v2();
276}
277
278#[repr(C)]
279pub(crate) struct ExtFuncsT {
281 ext_version: u32,
282 esp_intr_alloc: Option<
283 unsafe extern "C" fn(
284 source: u32,
285 flags: u32,
286 handler: *mut c_void,
287 arg: *mut c_void,
288 ret_handle: *mut *mut c_void,
289 ) -> i32,
290 >,
291 esp_intr_free: Option<unsafe extern "C" fn(ret_handle: *mut *mut c_void) -> i32>,
292 malloc: Option<unsafe extern "C" fn(size: u32) -> *mut c_void>,
293 free: Option<unsafe extern "C" fn(*mut c_void)>,
294 #[cfg(esp32c2)]
295 hal_uart_start_tx: Option<unsafe extern "C" fn(i32)>,
296 #[cfg(esp32c2)]
297 hal_uart_init_cbs: Option<
298 unsafe extern "C" fn(i32, *const c_void, *const c_void, *const c_void, c_void) -> i32,
299 >,
300 #[cfg(esp32c2)]
301 hal_uart_config: Option<unsafe extern "C" fn(i32, i32, u8, u8, u8, u8) -> i32>,
302 #[cfg(esp32c2)]
303 hal_uart_close: Option<unsafe extern "C" fn(i32) -> i32>,
304 #[cfg(esp32c2)]
305 hal_uart_blocking_tx: Option<unsafe extern "C" fn(i32, u8)>,
306 #[cfg(esp32c2)]
307 hal_uart_init: Option<unsafe extern "C" fn(i32, *const c_void) -> i32>,
308 task_create: Option<
309 unsafe extern "C" fn(
310 *mut c_void,
311 *const c_char,
312 u32,
313 *mut c_void,
314 u32,
315 *const c_void,
316 u32,
317 ) -> i32,
318 >,
319 task_delete: Option<unsafe extern "C" fn(*mut c_void)>,
320 osi_assert: Option<unsafe extern "C" fn(u32, *const c_void, u32, u32)>,
321 os_random: Option<unsafe extern "C" fn() -> u32>,
322 ecc_gen_key_pair: Option<unsafe extern "C" fn(*const u8, *const u8) -> i32>,
323 ecc_gen_dh_key: Option<unsafe extern "C" fn(*const u8, *const u8, *const u8, *const u8) -> i32>,
324 #[cfg(not(esp32h2))]
325 esp_reset_rpa_moudle: Option<unsafe extern "C" fn()>,
326 #[cfg(esp32c2)]
327 esp_bt_track_pll_cap: Option<unsafe extern "C" fn()>,
328 magic: u32,
329}
330
331static G_OSI_FUNCS: ExtFuncsT = ExtFuncsT {
332 #[cfg(not(esp32c2))]
333 ext_version: 0x20250415,
334 #[cfg(esp32c2)]
335 ext_version: 0x20221122,
336
337 esp_intr_alloc: Some(self::ble_os_adapter_chip_specific::esp_intr_alloc),
338 esp_intr_free: Some(esp_intr_free),
339 malloc: Some(crate::ble::malloc),
340 free: Some(crate::ble::free),
341 #[cfg(esp32c2)]
342 hal_uart_start_tx: None,
343 #[cfg(esp32c2)]
344 hal_uart_init_cbs: None,
345 #[cfg(esp32c2)]
346 hal_uart_config: None,
347 #[cfg(esp32c2)]
348 hal_uart_close: None,
349 #[cfg(esp32c2)]
350 hal_uart_blocking_tx: None,
351 #[cfg(esp32c2)]
352 hal_uart_init: None,
353 task_create: Some(task_create),
354 task_delete: Some(task_delete),
355 osi_assert: Some(osi_assert),
356 os_random: Some(os_random),
357 ecc_gen_key_pair: Some(ecc_gen_key_pair),
358 ecc_gen_dh_key: Some(ecc_gen_dh_key),
359 #[cfg(not(esp32h2))]
360 esp_reset_rpa_moudle: Some(self::ble_os_adapter_chip_specific::esp_reset_rpa_moudle),
361 #[cfg(esp32c2)]
362 esp_bt_track_pll_cap: None,
363 magic: 0xA5A5A5A5,
364};
365
366unsafe extern "C" fn ecc_gen_dh_key(_: *const u8, _: *const u8, _: *const u8, _: *const u8) -> i32 {
367 todo!()
368}
369
370unsafe extern "C" fn ecc_gen_key_pair(_: *const u8, _: *const u8) -> i32 {
371 todo!()
372}
373
374unsafe extern "C" fn os_random() -> u32 {
375 trace!("os_random");
376 unsafe { (crate::common_adapter::random() & u32::MAX) as u32 }
377}
378
379unsafe extern "C" fn task_create(
380 task_func: *mut c_void,
381 name: *const c_char,
382 stack_depth: u32,
383 param: *mut c_void,
384 prio: u32,
385 task_handle: *const c_void,
386 core_id: u32,
387) -> i32 {
388 let name_str = unsafe { str_from_c(name) };
389 trace!(
390 "task_create {:?} {} {} {:?} {} {:?} {}",
391 task_func, name_str, stack_depth, param, prio, task_handle, core_id,
392 );
393
394 unsafe {
395 *(task_handle as *mut usize) = 0;
396 } unsafe {
399 let task_func = transmute::<*mut c_void, extern "C" fn(*mut c_void)>(task_func);
400
401 let task = crate::preempt::task_create(
402 name_str,
403 task_func,
404 param,
405 prio,
406 if core_id < 2 { Some(core_id) } else { None },
407 stack_depth as usize,
408 );
409 *(task_handle as *mut usize) = task as usize;
410 }
411
412 1
413}
414
415unsafe extern "C" fn task_delete(task: *mut c_void) {
416 trace!("task delete called for {:?}", task);
417
418 unsafe {
419 crate::preempt::schedule_task_deletion(task);
420 }
421}
422
423unsafe extern "C" fn osi_assert(ln: u32, fn_name: *const c_void, param1: u32, param2: u32) {
424 unsafe {
425 let name_str = str_from_c(fn_name as _);
426 panic!("ASSERT {}:{} {} {}", name_str, ln, param1, param2);
427 }
428}
429
430unsafe extern "C" fn esp_intr_free(_ret_handle: *mut *mut c_void) -> i32 {
431 todo!();
432}
433
434#[repr(C)]
435#[allow(non_camel_case_types)]
436pub(crate) struct npl_funcs_t {
438 p_ble_npl_os_started: Option<unsafe extern "C" fn() -> bool>,
439 p_ble_npl_get_current_task_id: Option<unsafe extern "C" fn() -> *const c_void>,
440 p_ble_npl_eventq_init: Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq)>,
441 p_ble_npl_eventq_deinit: Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq)>,
442 p_ble_npl_eventq_get: Option<
443 unsafe extern "C" fn(
444 queue: *mut ble_npl_eventq,
445 time: ble_npl_time_t,
446 ) -> *const ble_npl_event,
447 >,
448 p_ble_npl_eventq_put:
449 Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq, event: *const ble_npl_event)>,
450 p_ble_npl_eventq_remove:
451 Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq, event: *const ble_npl_event)>,
452 p_ble_npl_event_run: Option<unsafe extern "C" fn(event: *const ble_npl_event)>,
453 p_ble_npl_eventq_is_empty: Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq) -> bool>,
454 p_ble_npl_event_init: Option<
455 unsafe extern "C" fn(
456 event: *const ble_npl_event,
457 func: *const ble_npl_event_fn,
458 *const c_void,
459 ),
460 >,
461 p_ble_npl_event_deinit: Option<unsafe extern "C" fn(event: *const ble_npl_event)>,
462 p_ble_npl_event_reset: Option<unsafe extern "C" fn(event: *const ble_npl_event)>,
463 p_ble_npl_event_is_queued: Option<unsafe extern "C" fn(event: *const ble_npl_event) -> bool>,
464 p_ble_npl_event_get_arg:
465 Option<unsafe extern "C" fn(event: *const ble_npl_event) -> *const c_void>,
466 p_ble_npl_event_set_arg:
467 Option<unsafe extern "C" fn(event: *const ble_npl_event, arg: *const c_void)>,
468 p_ble_npl_mutex_init:
469 Option<unsafe extern "C" fn(mutex: *const ble_npl_mutex) -> ble_npl_error_t>,
470 p_ble_npl_mutex_deinit:
471 Option<unsafe extern "C" fn(mutex: *const ble_npl_mutex) -> ble_npl_error_t>,
472 p_ble_npl_mutex_pend: Option<
473 unsafe extern "C" fn(mutex: *const ble_npl_mutex, time: ble_npl_time_t) -> ble_npl_error_t,
474 >,
475 p_ble_npl_mutex_release:
476 Option<unsafe extern "C" fn(mutex: *const ble_npl_mutex) -> ble_npl_error_t>,
477 p_ble_npl_sem_init:
478 Option<unsafe extern "C" fn(sem: *const ble_npl_sem, val: u16) -> ble_npl_error_t>,
479 p_ble_npl_sem_deinit: Option<unsafe extern "C" fn(sem: *const ble_npl_sem) -> ble_npl_error_t>,
480 p_ble_npl_sem_pend: Option<
481 unsafe extern "C" fn(sem: *const ble_npl_sem, time: ble_npl_time_t) -> ble_npl_error_t,
482 >,
483 p_ble_npl_sem_release: Option<unsafe extern "C" fn(sem: *const ble_npl_sem) -> ble_npl_error_t>,
484 p_ble_npl_sem_get_count: Option<unsafe extern "C" fn(sem: *const ble_npl_sem) -> u16>,
485 p_ble_npl_callout_init: Option<
486 unsafe extern "C" fn(
487 callout: *const ble_npl_callout,
488 eventq: *const ble_npl_eventq,
489 func: *const ble_npl_event_fn,
490 args: *const c_void,
491 ) -> i32,
492 >,
493 p_ble_npl_callout_reset: Option<
494 unsafe extern "C" fn(
495 callout: *const ble_npl_callout,
496 time: ble_npl_time_t,
497 ) -> ble_npl_error_t,
498 >,
499 p_ble_npl_callout_stop: Option<unsafe extern "C" fn(callout: *const ble_npl_callout)>,
500 p_ble_npl_callout_deinit: Option<unsafe extern "C" fn(callout: *const ble_npl_callout)>,
501 p_ble_npl_callout_mem_reset: Option<unsafe extern "C" fn(callout: *const ble_npl_callout)>,
502 p_ble_npl_callout_is_active:
503 Option<unsafe extern "C" fn(callout: *const ble_npl_callout) -> bool>,
504 p_ble_npl_callout_get_ticks:
505 Option<unsafe extern "C" fn(callout: *const ble_npl_callout) -> ble_npl_time_t>,
506 p_ble_npl_callout_remaining_ticks:
507 Option<unsafe extern "C" fn(callout: *const ble_npl_callout, time: ble_npl_time_t) -> u32>,
508 p_ble_npl_callout_set_arg:
509 Option<unsafe extern "C" fn(callout: *const ble_npl_callout, arg: *const c_void)>,
510 p_ble_npl_time_get: Option<unsafe extern "C" fn() -> u32>,
511 p_ble_npl_time_ms_to_ticks:
512 Option<unsafe extern "C" fn(ms: u32, p_time: *mut ble_npl_time_t) -> ble_npl_error_t>,
513 p_ble_npl_time_ticks_to_ms:
514 Option<unsafe extern "C" fn(time: ble_npl_time_t, *mut u32) -> ble_npl_error_t>,
515 p_ble_npl_time_ms_to_ticks32: Option<unsafe extern "C" fn(ms: u32) -> ble_npl_time_t>,
516 p_ble_npl_time_ticks_to_ms32: Option<unsafe extern "C" fn(time: ble_npl_time_t) -> u32>,
517 p_ble_npl_time_delay: Option<unsafe extern "C" fn(time: ble_npl_time_t)>,
518 p_ble_npl_hw_set_isr: Option<unsafe extern "C" fn(no: i32, mask: u32)>,
519 p_ble_npl_hw_enter_critical: Option<unsafe extern "C" fn() -> u32>,
520 p_ble_npl_hw_exit_critical: Option<unsafe extern "C" fn(mask: u32)>,
521 p_ble_npl_get_time_forever: Option<unsafe extern "C" fn() -> u32>,
522 p_ble_npl_hw_is_in_critical: Option<unsafe extern "C" fn() -> u8>,
523}
524
525static mut G_NPL_FUNCS: npl_funcs_t = npl_funcs_t {
526 p_ble_npl_os_started: Some(ble_npl_os_started),
527 p_ble_npl_get_current_task_id: Some(ble_npl_get_current_task_id),
528 p_ble_npl_eventq_init: Some(ble_npl_eventq_init),
529 p_ble_npl_eventq_deinit: Some(ble_npl_eventq_deinit),
530 p_ble_npl_eventq_get: Some(ble_npl_eventq_get),
531 p_ble_npl_eventq_put: Some(ble_npl_eventq_put),
532 p_ble_npl_eventq_remove: Some(ble_npl_eventq_remove),
533 p_ble_npl_event_run: Some(ble_npl_event_run),
534 p_ble_npl_eventq_is_empty: Some(ble_npl_eventq_is_empty),
535 p_ble_npl_event_init: Some(ble_npl_event_init),
536 p_ble_npl_event_deinit: Some(ble_npl_event_deinit),
537 p_ble_npl_event_reset: Some(ble_npl_event_reset),
538 p_ble_npl_event_is_queued: Some(ble_npl_event_is_queued),
539 p_ble_npl_event_get_arg: Some(ble_npl_event_get_arg),
540 p_ble_npl_event_set_arg: Some(ble_npl_event_set_arg),
541 p_ble_npl_mutex_init: Some(ble_npl_mutex_init),
542 p_ble_npl_mutex_deinit: Some(ble_npl_mutex_deinit),
543 p_ble_npl_mutex_pend: Some(ble_npl_mutex_pend),
544 p_ble_npl_mutex_release: Some(ble_npl_mutex_release),
545 p_ble_npl_sem_init: Some(ble_npl_sem_init),
546 p_ble_npl_sem_deinit: Some(ble_npl_sem_deinit),
547 p_ble_npl_sem_pend: Some(ble_npl_sem_pend),
548 p_ble_npl_sem_release: Some(ble_npl_sem_release),
549 p_ble_npl_sem_get_count: Some(ble_npl_sem_get_count),
550 p_ble_npl_callout_init: Some(ble_npl_callout_init),
551 p_ble_npl_callout_reset: Some(ble_npl_callout_reset),
552 p_ble_npl_callout_stop: Some(ble_npl_callout_stop),
553 p_ble_npl_callout_deinit: Some(ble_npl_callout_deinit),
554 p_ble_npl_callout_mem_reset: Some(ble_npl_callout_mem_reset),
555 p_ble_npl_callout_is_active: Some(ble_npl_callout_is_active),
556 p_ble_npl_callout_get_ticks: Some(ble_npl_callout_get_ticks),
557 p_ble_npl_callout_remaining_ticks: Some(ble_npl_callout_remaining_ticks),
558 p_ble_npl_callout_set_arg: Some(ble_npl_callout_set_arg),
559 p_ble_npl_time_get: Some(ble_npl_time_get),
560 p_ble_npl_time_ms_to_ticks: Some(ble_npl_time_ms_to_ticks),
561 p_ble_npl_time_ticks_to_ms: Some(ble_npl_time_ticks_to_ms),
562 p_ble_npl_time_ms_to_ticks32: Some(ble_npl_time_ms_to_ticks32),
563 p_ble_npl_time_ticks_to_ms32: Some(ble_npl_time_ticks_to_ms32),
564 p_ble_npl_time_delay: Some(ble_npl_time_delay),
565 p_ble_npl_hw_set_isr: Some(ble_npl_hw_set_isr),
566 p_ble_npl_hw_enter_critical: Some(ble_npl_hw_enter_critical),
567 p_ble_npl_hw_exit_critical: Some(ble_npl_hw_exit_critical),
568 p_ble_npl_get_time_forever: Some(ble_npl_get_time_forever),
569 p_ble_npl_hw_is_in_critical: Some(ble_npl_hw_is_in_critical),
570};
571
572#[repr(C)]
573pub(crate) struct OsiCoexFuncsT {
575 magic: u32,
576 version: u32,
577 coex_wifi_sleep_set: Option<unsafe extern "C" fn(sleep: bool)>,
578 coex_core_ble_conn_dyn_prio_get:
579 Option<unsafe extern "C" fn(low: *mut bool, high: *mut bool) -> i32>,
580 coex_schm_status_bit_set: Option<unsafe extern "C" fn(_type: u32, status: u32)>,
581 coex_schm_status_bit_clear: Option<unsafe extern "C" fn(_type: u32, status: u32)>,
582}
583
584#[allow(unused)]
585static G_COEX_FUNCS: OsiCoexFuncsT = OsiCoexFuncsT {
586 magic: 0xFADEBEAD,
587 version: 0x00010006,
588 coex_wifi_sleep_set: Some(coex_wifi_sleep_set),
589 coex_core_ble_conn_dyn_prio_get: Some(coex_core_ble_conn_dyn_prio_get),
590 coex_schm_status_bit_set: Some(coex_schm_status_bit_set),
591 coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear),
592};
593
594#[allow(unused)]
595unsafe extern "C" fn coex_wifi_sleep_set(_sleep: bool) {
596 todo!()
597}
598
599#[allow(unused)]
600unsafe extern "C" fn coex_core_ble_conn_dyn_prio_get(_low: *mut bool, _high: *mut bool) -> i32 {
601 todo!()
602}
603
604#[allow(unused)]
605unsafe extern "C" fn coex_schm_status_bit_set(_type: u32, _status: u32) {
606 trace!("coex_schm_status_bit_set is an empty stub");
607}
608
609#[allow(unused)]
610unsafe extern "C" fn coex_schm_status_bit_clear(_type: u32, _status: u32) {
611 trace!("coex_schm_status_bit_clear is an empty stub");
612}
613
614unsafe extern "C" fn ble_npl_hw_is_in_critical() -> u8 {
615 todo!()
616}
617
618unsafe extern "C" fn ble_npl_get_time_forever() -> u32 {
619 trace!("ble_npl_get_time_forever");
620 TIME_FOREVER
621}
622
623unsafe extern "C" fn ble_npl_hw_exit_critical(mask: u32) {
624 trace!("ble_npl_hw_exit_critical {}", mask);
625 unsafe {
626 let token = esp_sync::RestoreState::new(mask);
627 crate::ESP_RADIO_LOCK.release(token);
628 }
629}
630
631unsafe extern "C" fn ble_npl_hw_enter_critical() -> u32 {
632 trace!("ble_npl_hw_enter_critical");
633 unsafe { crate::ESP_RADIO_LOCK.acquire().inner() }
634}
635
636unsafe extern "C" fn ble_npl_hw_set_isr(_no: i32, _mask: u32) {
637 todo!()
638}
639
640unsafe extern "C" fn ble_npl_time_delay(time: ble_npl_time_t) {
641 let time = blob_ticks_to_micros(time);
642 crate::preempt::usleep(time);
643}
644
645unsafe extern "C" fn ble_npl_time_ticks_to_ms32(time: ble_npl_time_t) -> u32 {
646 trace!("ble_npl_time_ticks_to_ms32 {}", time);
647 blob_ticks_to_millis(time)
648}
649
650unsafe extern "C" fn ble_npl_time_ms_to_ticks32(ms: u32) -> ble_npl_time_t {
651 trace!("ble_npl_time_ms_to_ticks32 {}", ms);
652 millis_to_blob_ticks(ms)
653}
654
655unsafe extern "C" fn ble_npl_time_ticks_to_ms(
656 time: ble_npl_time_t,
657 p_ms: *mut u32,
658) -> ble_npl_error_t {
659 trace!("ble_npl_time_ticks_to_ms {}", time);
660 unsafe { *p_ms = blob_ticks_to_millis(time) };
661 0
662}
663
664unsafe extern "C" fn ble_npl_time_ms_to_ticks(
665 ms: u32,
666 p_time: *mut ble_npl_time_t,
667) -> ble_npl_error_t {
668 trace!("ble_npl_time_ms_to_ticks {}", ms);
669 unsafe { *p_time = millis_to_blob_ticks(ms) };
670 0
671}
672
673unsafe extern "C" fn ble_npl_time_get() -> u32 {
674 trace!("ble_npl_time_get");
675 Instant::now().duration_since_epoch().as_millis() as u32
676}
677
678unsafe extern "C" fn ble_npl_callout_set_arg(
679 _callout: *const ble_npl_callout,
680 _arg: *const c_void,
681) {
682 todo!()
683}
684
685unsafe extern "C" fn ble_npl_callout_remaining_ticks(
686 _callout: *const ble_npl_callout,
687 _time: ble_npl_time_t,
688) -> u32 {
689 todo!()
690}
691
692unsafe extern "C" fn ble_npl_callout_get_ticks(_callout: *const ble_npl_callout) -> ble_npl_time_t {
693 todo!()
694}
695
696unsafe extern "C" fn ble_npl_callout_is_active(callout: *const ble_npl_callout) -> bool {
697 debug!(
698 "Missing real implementation: ble_npl_callout_is_active {:?}",
699 callout
700 );
701
702 assert!(unsafe { (*callout).dummy != 0 });
703
704 unsafe {
705 let co = (*callout).dummy as *mut Callout;
706 compat::timer_compat::compat_timer_is_active(&raw mut (*co).timer_handle)
707 }
708}
709
710unsafe extern "C" fn ble_npl_callout_mem_reset(callout: *const ble_npl_callout) {
711 trace!("ble_npl_callout_mem_reset");
712 unsafe {
713 ble_npl_callout_stop(callout);
714 }
715}
716
717unsafe extern "C" fn ble_npl_callout_deinit(callout: *const ble_npl_callout) {
718 trace!("ble_npl_callout_deinit");
719 unsafe {
720 ble_npl_callout_stop(callout);
721 }
722}
723
724unsafe extern "C" fn ble_npl_callout_stop(callout: *const ble_npl_callout) {
725 trace!("ble_npl_callout_stop {:?}", callout);
726
727 assert!(unsafe { (*callout).dummy != 0 });
728
729 unsafe {
730 let co = (*callout).dummy as *mut Callout;
731 compat::timer_compat::compat_timer_disarm(&raw mut (*co).timer_handle);
733 }
734}
735
736unsafe extern "C" fn ble_npl_callout_reset(
737 callout: *const ble_npl_callout,
738 time: ble_npl_time_t,
739) -> ble_npl_error_t {
740 trace!("ble_npl_callout_reset {:?} {}", callout, time);
741
742 let co = unsafe { (*callout).dummy } as *mut Callout;
743 unsafe {
744 compat::timer_compat::compat_timer_arm(
746 &raw mut (*co).timer_handle,
747 blob_ticks_to_millis(time),
748 false,
749 );
750 }
751 0
752}
753
754unsafe extern "C" fn ble_npl_sem_get_count(_sem: *const ble_npl_sem) -> u16 {
755 todo!()
756}
757
758unsafe extern "C" fn ble_npl_sem_release(_sem: *const ble_npl_sem) -> ble_npl_error_t {
759 todo!()
760}
761
762unsafe extern "C" fn ble_npl_sem_pend(
763 _sem: *const ble_npl_sem,
764 _time: ble_npl_time_t,
765) -> ble_npl_error_t {
766 todo!()
767}
768
769unsafe extern "C" fn ble_npl_sem_deinit(_sem: *const ble_npl_sem) -> ble_npl_error_t {
770 todo!()
771}
772
773unsafe extern "C" fn ble_npl_sem_init(_sem: *const ble_npl_sem, _val: u16) -> ble_npl_error_t {
774 todo!()
775}
776
777unsafe extern "C" fn ble_npl_mutex_release(_mutex: *const ble_npl_mutex) -> ble_npl_error_t {
778 todo!()
779}
780
781unsafe extern "C" fn ble_npl_mutex_pend(
782 _mutex: *const ble_npl_mutex,
783 _time: ble_npl_time_t,
784) -> ble_npl_error_t {
785 todo!()
786}
787
788unsafe extern "C" fn ble_npl_mutex_deinit(_mutex: *const ble_npl_mutex) -> ble_npl_error_t {
789 todo!()
790}
791
792unsafe extern "C" fn ble_npl_event_set_arg(event: *const ble_npl_event, arg: *const c_void) {
793 trace!("ble_npl_event_set_arg {:?} {:?}", event, arg);
794
795 let evt = unsafe { (*event).dummy } as *mut Event;
796 assert!(!evt.is_null());
797
798 unsafe {
799 (*evt).ev_arg_ptr = arg;
800 }
801}
802
803unsafe extern "C" fn ble_npl_event_get_arg(event: *const ble_npl_event) -> *const c_void {
804 trace!("ble_npl_event_get_arg {:?}", event);
805
806 unsafe {
807 let evt = (*event).dummy as *mut Event;
808 assert!(!evt.is_null());
809
810 let arg_ptr = (*evt).ev_arg_ptr;
811
812 trace!("returning arg {:x}", arg_ptr as usize);
813
814 arg_ptr
815 }
816}
817
818unsafe extern "C" fn ble_npl_event_is_queued(event: *const ble_npl_event) -> bool {
819 trace!("ble_npl_event_is_queued {:?}", event);
820
821 let evt = unsafe { (*event).dummy } as *mut Event;
822 assert!(!evt.is_null());
823
824 unsafe { (*evt).queued }
825}
826
827unsafe extern "C" fn ble_npl_event_reset(event: *const ble_npl_event) {
828 trace!("ble_npl_event_reset {:?}", event);
829
830 let evt = unsafe { (*event).dummy } as *mut Event;
831 assert!(!evt.is_null());
832
833 unsafe { (*evt).queued = false }
834}
835
836unsafe extern "C" fn ble_npl_event_deinit(event: *const ble_npl_event) {
837 trace!("ble_npl_event_deinit {:?}", event);
838
839 let event = event as *mut ble_npl_event;
840 let evt = unsafe { (*event).dummy } as *mut Event;
841 assert!(!evt.is_null());
842
843 unsafe {
844 crate::compat::malloc::free(evt.cast());
845 }
846
847 unsafe {
848 (*event).dummy = 0;
849 }
850}
851
852unsafe extern "C" fn ble_npl_event_init(
853 event: *const ble_npl_event,
854 func: *const ble_npl_event_fn,
855 arg: *const c_void,
856) {
857 trace!("ble_npl_event_init {:?} {:?} {:?}", event, func, arg);
858
859 if unsafe { (*event).dummy } == 0 {
860 unsafe {
861 let evt = crate::compat::malloc::calloc(1, core::mem::size_of::<Event>()) as *mut Event;
862
863 (*evt).event_fn_ptr = func;
864 (*evt).ev_arg_ptr = arg;
865 (*evt).queued = false;
866
867 let event = event.cast_mut();
868 (*event).dummy = evt as i32;
869 }
870 }
871}
872
873unsafe extern "C" fn ble_npl_eventq_is_empty(queue: *mut ble_npl_eventq) -> bool {
874 trace!("ble_npl_eventq_is_empty {:?}", queue);
875 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
876
877 queue::queue_messages_waiting(wrapper.dummy as _) == 0
878}
879
880unsafe extern "C" fn ble_npl_event_run(event: *const ble_npl_event) {
881 trace!("ble_npl_event_run {:?}", event);
882
883 let evt = unsafe { (*event).dummy } as *mut Event;
884 assert!(!evt.is_null());
885
886 trace!(
887 "info {:?} with arg {:x}",
888 unsafe { (*evt).event_fn_ptr },
889 event as u32
890 );
891 unsafe {
892 let func: unsafe extern "C" fn(u32) = transmute((*evt).event_fn_ptr);
893 func(event as u32);
894 }
895
896 trace!("ble_npl_event_run done");
897}
898
899unsafe extern "C" fn ble_npl_eventq_remove(
900 queue: *mut ble_npl_eventq,
901 event: *const ble_npl_event,
902) {
903 trace!("ble_npl_eventq_remove {:?} {:?}", queue, event);
904
905 unsafe {
906 let evt = (*event).dummy as *mut Event;
907 assert!(!evt.is_null());
908
909 if !(*evt).queued {
910 return;
911 }
912
913 let wrapper = unwrap!(queue.as_mut(), "queue wrapper is null");
914 queue::queue_remove(wrapper.dummy as _, (&raw const event).cast());
915
916 (*evt).queued = false;
917 }
918}
919
920unsafe extern "C" fn ble_npl_eventq_put(queue: *mut ble_npl_eventq, event: *const ble_npl_event) {
921 trace!("ble_npl_eventq_put {:?} {:?}", queue, event);
922
923 let evt = unsafe { (*event).dummy } as *mut Event;
924 assert!(!evt.is_null());
925
926 if unsafe { (*evt).queued } {
927 trace!("Event already queued, skipping put");
928 return;
929 }
930
931 unsafe {
932 (*evt).queued = true;
933 }
934
935 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
936
937 queue::queue_send_to_back(
939 wrapper.dummy as _,
940 (&raw const event).cast(),
941 OSI_FUNCS_TIME_BLOCKING,
942 );
943}
944
945unsafe extern "C" fn ble_npl_eventq_get(
946 queue: *mut ble_npl_eventq,
947 timeout: ble_npl_time_t,
948) -> *const ble_npl_event {
949 trace!("ble_npl_eventq_get {:?} {}", queue, timeout);
950
951 let mut evt = core::ptr::null_mut::<ble_npl_event>();
952 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
953
954 if queue::queue_receive(
955 wrapper.dummy as _,
956 (&raw mut evt).cast(),
957 blob_ticks_to_micros(timeout),
958 ) == 1
959 {
960 trace!("got {:x}", evt as usize);
961 unsafe {
962 let evt = (*evt).dummy as *mut Event;
963 (*evt).queued = false;
964 }
965 }
966
967 evt.cast_const()
968}
969
970unsafe extern "C" fn ble_npl_eventq_init(queue: *mut ble_npl_eventq) {
971 trace!("ble_npl_eventq_init {:?}", queue);
972
973 let queue_ptr = queue::queue_create(EVENT_QUEUE_SIZE as _, core::mem::size_of::<usize>() as _);
974
975 unsafe {
976 (*queue).dummy = queue_ptr as i32;
977 }
978}
979
980unsafe extern "C" fn ble_npl_eventq_deinit(queue: *mut ble_npl_eventq) {
981 trace!("ble_npl_eventq_deinit {:?}", queue);
982
983 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
984 queue::queue_delete(wrapper.dummy as _);
985 wrapper.dummy = 0;
986}
987
988unsafe extern "C" fn ble_npl_callout_init(
989 callout: *const ble_npl_callout,
990 eventq: *const ble_npl_eventq,
991 func: *const ble_npl_event_fn,
992 args: *const c_void,
993) -> i32 {
994 trace!(
995 "ble_npl_callout_init {:?} {:?} {:?} {:?}",
996 callout, eventq, func, args
997 );
998
999 if unsafe { (*callout).dummy } == 0 {
1000 let callout = callout.cast_mut();
1001
1002 unsafe {
1003 let new_callout =
1004 crate::compat::malloc::calloc(1, core::mem::size_of::<Callout>()) as *mut Callout;
1005 ble_npl_event_init(addr_of_mut!((*new_callout).events), func, args);
1006 (*callout).dummy = new_callout as i32;
1007
1008 crate::compat::timer_compat::compat_timer_setfn(
1009 addr_of_mut!((*new_callout).timer_handle),
1010 callout_timer_callback_wrapper,
1011 callout as *mut c_void,
1012 );
1013 }
1014 }
1015
1016 0
1017}
1018
1019unsafe extern "C" fn callout_timer_callback_wrapper(arg: *mut c_void) {
1020 trace!("callout_timer_callback_wrapper {:?}", arg);
1021 let co = unsafe { (*(arg as *mut ble_npl_callout)).dummy } as *mut Callout;
1022
1023 unsafe {
1024 if !(*co).eventq.is_null() {
1025 ble_npl_eventq_put((*co).eventq.cast_mut(), addr_of!((*co).events));
1026 } else {
1027 ble_npl_event_run(addr_of!((*co).events));
1028 }
1029 }
1030}
1031
1032unsafe extern "C" fn ble_npl_mutex_init(_mutex: *const ble_npl_mutex) -> u32 {
1033 todo!()
1034}
1035
1036unsafe extern "C" fn ble_npl_get_current_task_id() -> *const c_void {
1037 todo!()
1038}
1039
1040unsafe extern "C" fn ble_npl_os_started() -> bool {
1041 todo!();
1042}
1043
1044#[repr(C)]
1045pub(crate) struct BleNplCountInfoT {
1047 evt_count: u16,
1048 evtq_count: u16,
1049 co_count: u16,
1050 sem_count: u16,
1051 mutex_count: u16,
1052}
1053
1054pub(crate) fn ble_init(config: &Config) -> PhyInitGuard<'static> {
1055 let phy_init_guard;
1056 unsafe {
1057 (*addr_of_mut!(HCI_OUT_COLLECTOR)).write(HciOutCollector::new());
1058
1059 #[allow(static_mut_refs)]
1061 #[cfg(all(feature = "sys-logs", esp32c2))]
1062 {
1063 extern "C" {
1064 static mut g_ble_plf_log_level: u32;
1065 }
1066
1067 debug!("g_ble_plf_log_level = {}", g_ble_plf_log_level);
1068 g_ble_plf_log_level = 10;
1069 }
1070
1071 self::ble_os_adapter_chip_specific::ble_rtc_clk_init();
1072
1073 let cfg = ble_os_adapter_chip_specific::create_ble_config(config);
1074
1075 let res = esp_register_ext_funcs(&G_OSI_FUNCS as *const ExtFuncsT);
1076 assert!(res == 0, "esp_register_ext_funcs returned {}", res);
1077
1078 #[cfg(esp32c2)]
1079 {
1080 debug!("Init esp_ble_rom_func_ptr_init_all");
1081 unsafe extern "C" {
1082 fn esp_ble_rom_func_ptr_init_all() -> i32;
1083 }
1084 let res = esp_ble_rom_func_ptr_init_all();
1085 assert!(res == 0, "esp_ble_rom_func_ptr_init_all returned {}", res);
1086 }
1087
1088 #[cfg(coex)]
1089 {
1090 let res = crate::wifi::coex_init();
1091 assert!(res == 0, "coex_init failed");
1092 }
1093
1094 ble_os_adapter_chip_specific::bt_periph_module_enable();
1095
1096 ble_os_adapter_chip_specific::disable_sleep_mode();
1097
1098 let res = esp_register_npl_funcs(core::ptr::addr_of!(G_NPL_FUNCS));
1099 assert!(res == 0, "esp_register_npl_funcs returned {}", res);
1100
1101 let npl_info = BleNplCountInfoT {
1102 evt_count: 0,
1103 evtq_count: 0,
1104 co_count: 0,
1105 sem_count: 0,
1106 mutex_count: 0,
1107 };
1108 #[cfg(esp32c2)]
1109 let res = ble_get_npl_element_info(
1110 &cfg as *const esp_bt_controller_config_t,
1111 &npl_info as *const BleNplCountInfoT,
1112 );
1113 #[cfg(not(esp32c2))]
1114 let res = r_ble_get_npl_element_info(
1115 &cfg as *const esp_bt_controller_config_t,
1116 &npl_info as *const BleNplCountInfoT,
1117 );
1118 assert!(res == 0, "ble_get_npl_element_info returned {}", res);
1119
1120 #[cfg(esp32c2)]
1123 {
1124 let ret = os_msys_buf_alloc();
1126 assert!(ret, "os_msys_buf_alloc failed");
1127
1128 os_msys_init();
1129 }
1130
1131 phy_init_guard = esp_hal::peripherals::BT::steal().enable_phy();
1132
1133 bt_bb_v2_init_cmplx(1);
1135
1136 coex_pti_v2();
1137
1138 #[cfg(coex)]
1139 {
1140 let rc = ble_osi_coex_funcs_register(&G_COEX_FUNCS as *const OsiCoexFuncsT);
1141 assert!(rc == 0, "ble_osi_coex_funcs_register returned {}", rc);
1142 }
1143
1144 #[cfg(not(esp32c2))]
1145 {
1146 unsafe extern "C" {
1147 fn esp_ble_register_bb_funcs() -> i32;
1148 }
1149 let res = esp_ble_register_bb_funcs();
1150 assert!(res == 0, "esp_ble_register_bb_funcs returned {}", res);
1151 }
1152
1153 #[cfg(esp32c2)]
1154 let res = ble_controller_init(&cfg as *const esp_bt_controller_config_t);
1155 #[cfg(not(esp32c2))]
1156 let res = r_ble_controller_init(&cfg as *const esp_bt_controller_config_t);
1157
1158 assert!(res == 0, "ble_controller_init returned {}", res);
1159
1160 #[cfg(not(esp32c2))]
1161 {
1162 unsafe extern "C" {
1163 fn r_esp_ble_msys_init(
1164 msys_size1: u16,
1165 msys_size2: u16,
1166 msys_cnt1: u16,
1167 msys_cnt2: u16,
1168 from_heap: u8,
1169 ) -> i32;
1170
1171 fn base_stack_initEnv() -> i32;
1172 fn conn_stack_initEnv() -> i32;
1173 fn adv_stack_initEnv() -> i32;
1174 fn extAdv_stack_initEnv() -> i32;
1175 fn sync_stack_initEnv() -> i32;
1176 }
1177
1178 let res = base_stack_initEnv();
1179 assert!(res == 0, "base_stack_initEnv returned {}", res);
1180
1181 let res = conn_stack_initEnv();
1182 assert!(res == 0, "conn_stack_initEnv returned {}", res);
1183
1184 let res = adv_stack_initEnv();
1185 assert!(res == 0, "adv_stack_initEnv returned {}", res);
1186
1187 let res = extAdv_stack_initEnv();
1188 if res != 0 {
1189 panic!("extAdv_stack_initEnv returned {}", res);
1190 }
1191
1192 let res = sync_stack_initEnv();
1193 assert!(res == 0, "sync_stack_initEnv returned {}", res);
1194
1195 let res = r_esp_ble_msys_init(256, 320, 12, 24, 1);
1196 assert!(res == 0, "esp_ble_msys_init returned {}", res);
1197 }
1198
1199 #[cfg(coex)]
1200 crate::binary::include::coex_enable();
1201
1202 let mut mac = [0u8; 6];
1203 crate::common_adapter::read_mac(mac.as_mut_ptr(), 2);
1204 mac.reverse();
1205
1206 #[cfg(esp32c2)]
1207 esp_ble_ll_set_public_addr(&mac as *const u8);
1208 #[cfg(not(esp32c2))]
1209 r_esp_ble_ll_set_public_addr(&mac as *const u8);
1210
1211 unsafe extern "C" {
1212 fn r_ble_hci_trans_init(m: u8);
1213 }
1214 r_ble_hci_trans_init(0);
1215
1216 r_ble_hci_trans_cfg_hs(
1217 Some(ble_hs_hci_rx_evt),
1218 core::ptr::null(),
1219 Some(ble_hs_rx_data),
1220 core::ptr::null(),
1221 );
1222
1223 #[cfg(esp32c2)]
1224 let res = ble_controller_enable(1); #[cfg(not(esp32c2))]
1226 let res = r_ble_controller_enable(1); assert!(res == 0, "ble_controller_enable returned {}", res);
1228
1229 crate::preempt::usleep(10_000);
1232 }
1233
1234 unsafe { esp_hal::rng::TrngSource::increase_entropy_source_counter() };
1236
1237 debug!("The ble_controller_init was initialized");
1238 phy_init_guard
1239}
1240
1241pub(crate) fn ble_deinit() {
1242 esp_hal::rng::TrngSource::decrease_entropy_source_counter(unsafe {
1243 esp_hal::Internal::conjure()
1244 });
1245
1246 #[cfg(not(esp32c2))]
1247 unsafe extern "C" {
1248 fn base_stack_deinitEnv() -> i32;
1249 fn conn_stack_deinitEnv() -> i32;
1250 fn adv_stack_deinitEnv() -> i32;
1251 fn extAdv_stack_deinitEnv() -> i32;
1252 fn sync_stack_deinitEnv() -> i32;
1253 }
1254
1255 unsafe {
1256 crate::preempt::usleep(10_000);
1260 npl::r_ble_hci_trans_cfg_hs(None, core::ptr::null(), None, core::ptr::null());
1262
1263 #[cfg(not(esp32c2))]
1264 npl::r_ble_controller_disable();
1265
1266 #[cfg(not(esp32c2))]
1267 {
1268 conn_stack_deinitEnv();
1269 sync_stack_deinitEnv();
1270 extAdv_stack_deinitEnv();
1271 adv_stack_deinitEnv();
1272 base_stack_deinitEnv();
1273 }
1274
1275 #[cfg(not(esp32c2))]
1276 let res = npl::r_ble_controller_deinit();
1277
1278 #[cfg(esp32c2)]
1279 let res = npl::ble_controller_deinit();
1280
1281 if res != 0 {
1282 panic!("ble_controller_deinit returned {}", res);
1283 }
1284
1285 npl::esp_unregister_npl_funcs();
1286
1287 npl::esp_unregister_ext_funcs();
1288 }
1289}
1290
1291#[cfg(esp32c2)]
1292fn os_msys_buf_alloc() -> bool {
1293 unsafe {
1294 OS_MSYS_INIT_1_DATA = crate::compat::malloc::calloc(
1295 1,
1296 core::mem::size_of::<OsMembufT>() * SYSINIT_MSYS_1_MEMPOOL_SIZE,
1297 ) as *mut u32;
1298 OS_MSYS_INIT_2_DATA = crate::compat::malloc::calloc(
1299 1,
1300 core::mem::size_of::<OsMembufT>() * SYSINIT_MSYS_2_MEMPOOL_SIZE,
1301 ) as *mut u32;
1302
1303 !(OS_MSYS_INIT_1_DATA.is_null() || OS_MSYS_INIT_2_DATA.is_null())
1304 }
1305}
1306
1307#[cfg(esp32c2)]
1308fn os_msys_init() {
1309 static MSYS1: &[u8] = b"msys_1\0";
1310 static MSYS2: &[u8] = b"msys_2\0";
1311
1312 unsafe {
1313 r_os_msys_reset();
1314
1315 let rc = r_mem_init_mbuf_pool(
1316 OS_MSYS_INIT_1_DATA as *const c_void,
1317 addr_of!(OS_MSYS_INIT_1_MEMPOOL),
1318 addr_of!(OS_MSYS_INIT_1_MBUF_POOL),
1319 OS_MSYS_1_BLOCK_COUNT,
1320 SYSINIT_MSYS_1_MEMBLOCK_SIZE,
1321 MSYS1 as *const _ as *const u8,
1322 );
1323 if rc != 0 {
1324 panic!("r_mem_init_mbuf_pool failed");
1325 }
1326
1327 let rc = r_os_msys_register(addr_of!(OS_MSYS_INIT_1_MBUF_POOL));
1328 if rc != 0 {
1329 panic!("r_os_msys_register failed");
1330 }
1331
1332 let rc = r_mem_init_mbuf_pool(
1333 OS_MSYS_INIT_2_DATA as *const c_void,
1334 addr_of!(OS_MSYS_INIT_2_MEMPOOL),
1335 addr_of!(OS_MSYS_INIT_2_MBUF_POOL),
1336 OS_MSYS_2_BLOCK_COUNT,
1337 SYSINIT_MSYS_2_MEMBLOCK_SIZE,
1338 MSYS2 as *const _ as *const u8,
1339 );
1340 if rc != 0 {
1341 panic!("r_mem_init_mbuf_pool failed");
1342 }
1343
1344 let rc = r_os_msys_register(addr_of!(OS_MSYS_INIT_2_MBUF_POOL));
1345 if rc != 0 {
1346 panic!("r_os_msys_register failed");
1347 }
1348 }
1349}
1350
1351unsafe extern "C" fn ble_hs_hci_rx_evt(cmd: *const u8, arg: *const c_void) -> i32 {
1352 trace!("ble_hs_hci_rx_evt {:?} {:?}", cmd, arg);
1353 trace!("$ cmd = {:x}", unsafe { *cmd });
1354 trace!("$ len = {:x}", unsafe { *(cmd.offset(1)) });
1355
1356 let event = unsafe { *cmd };
1357 let len = unsafe { *(cmd.offset(1)) } as usize;
1358 let payload = unsafe { core::slice::from_raw_parts(cmd.offset(2), len) };
1359 trace!("$ pld = {:?}", payload);
1360
1361 super::BT_STATE.with(|state| {
1362 let mut data = [0u8; 256];
1363
1364 data[0] = 0x04; data[1] = event;
1366 data[2] = len as u8;
1367 data[3..][..len].copy_from_slice(payload);
1368
1369 state.rx_queue.push_back(ReceivedPacket {
1370 data: Box::from(&data[..len + 3]),
1371 });
1372
1373 dump_packet_info(&data[..(len + 3)]);
1374 });
1375
1376 unsafe {
1377 r_ble_hci_trans_buf_free(cmd);
1378 }
1379
1380 crate::ble::controller::hci_read_data_available();
1381
1382 0
1383}
1384
1385unsafe extern "C" fn ble_hs_rx_data(om: *const OsMbuf, arg: *const c_void) -> i32 {
1386 trace!("ble_hs_rx_data {:?} {:?}", om, arg);
1387
1388 let data_ptr = unsafe { (*om).om_data };
1389 let len = unsafe { (*om).om_len };
1390 let data_slice = unsafe { core::slice::from_raw_parts(data_ptr, len as usize) };
1391
1392 super::BT_STATE.with(|state| {
1393 let mut data = [0u8; 256];
1394
1395 data[0] = 0x02; data[1..][..data_slice.len()].copy_from_slice(data_slice);
1397
1398 state.rx_queue.push_back(ReceivedPacket {
1399 data: Box::from(&data[..data_slice.len() + 1]),
1400 });
1401
1402 super::dump_packet_info(&data[..(len + 1) as usize]);
1403 });
1404
1405 unsafe {
1406 r_os_mbuf_free_chain(om as *mut _);
1407 }
1408
1409 crate::ble::controller::hci_read_data_available();
1410
1411 0
1412}
1413
1414#[instability::unstable]
1416pub fn send_hci(data: &[u8]) {
1417 let hci_out = unsafe { (*addr_of_mut!(HCI_OUT_COLLECTOR)).assume_init_mut() };
1418 hci_out.push(data);
1419
1420 if hci_out.is_ready() {
1421 let packet = hci_out.packet();
1422
1423 unsafe {
1424 const DATA_TYPE_COMMAND: u8 = 1;
1425 const DATA_TYPE_ACL: u8 = 2;
1426
1427 dump_packet_info(packet);
1428
1429 super::BT_STATE.with(|_state| {
1430 if packet[0] == DATA_TYPE_COMMAND {
1431 let cmd = r_ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD);
1432 core::ptr::copy_nonoverlapping(
1433 &packet[1] as *const _ as *mut u8, cmd as *mut u8,
1435 packet.len() - 1,
1436 );
1437
1438 let res = r_ble_hci_trans_hs_cmd_tx(cmd);
1439
1440 if res != 0 {
1441 warn!("ble_hci_trans_hs_cmd_tx res == {}", res);
1442 }
1443 } else if packet[0] == DATA_TYPE_ACL {
1444 let om = r_os_msys_get_pkthdr(
1445 packet.len() as u16,
1446 ACL_DATA_MBUF_LEADINGSPACE as u16,
1447 );
1448
1449 let res =
1450 r_os_mbuf_append(om, packet.as_ptr().offset(1), (packet.len() - 1) as u16);
1451 if res != 0 {
1452 panic!("r_os_mbuf_append returned {}", res);
1453 }
1454
1455 *((*om).om_data as *mut u8).offset(1) = 0;
1458
1459 let res = r_ble_hci_trans_hs_acl_tx(om);
1460 if res != 0 {
1461 panic!("ble_hci_trans_hs_acl_tx returned {}", res);
1462 }
1463 trace!("ACL tx done");
1464 }
1465 });
1466 }
1467
1468 hci_out.reset();
1469 }
1470}