1#![no_std]
33#![allow(clippy::not_unsafe_ptr_arg_deref)]
34
35use core::ffi::c_void;
36
37#[cfg(feature = "posix-c-port")]
45#[doc(hidden)]
46#[inline(never)]
47pub extern "C" fn _nros_force_link_cffi() {}
48
49unsafe extern "C" {
58 pub fn nros_platform_clock_ms() -> u64;
60 pub fn nros_platform_clock_us() -> u64;
61
62 pub fn nros_platform_alloc(size: usize) -> *mut c_void;
64 pub fn nros_platform_realloc(ptr: *mut c_void, size: usize) -> *mut c_void;
65 pub fn nros_platform_dealloc(ptr: *mut c_void);
66 pub fn nros_platform_heap_used_bytes() -> usize;
67 pub fn nros_platform_heap_total_bytes() -> usize;
68
69 pub fn nros_platform_sleep_us(us: usize);
71 pub fn nros_platform_sleep_ms(ms: usize);
72 pub fn nros_platform_sleep_s(s: usize);
73
74 pub fn nros_platform_yield_now();
76
77 pub fn nros_platform_random_u8() -> u8;
79 pub fn nros_platform_random_u16() -> u16;
80 pub fn nros_platform_random_u32() -> u32;
81 pub fn nros_platform_random_u64() -> u64;
82 pub fn nros_platform_random_fill(buf: *mut c_void, len: usize);
83
84 pub fn nros_platform_time_now_ms() -> u64;
86 pub fn nros_platform_time_since_epoch_secs() -> u32;
87 pub fn nros_platform_time_since_epoch_nanos() -> u32;
88
89 pub fn nros_platform_task_init(
91 task: *mut c_void,
92 attr: *mut c_void,
93 entry: Option<unsafe extern "C" fn(*mut c_void) -> *mut c_void>,
94 arg: *mut c_void,
95 ) -> i8;
96 pub fn nros_platform_task_join(task: *mut c_void) -> i8;
97 pub fn nros_platform_task_detach(task: *mut c_void) -> i8;
98 pub fn nros_platform_task_cancel(task: *mut c_void) -> i8;
99 pub fn nros_platform_task_exit();
100 pub fn nros_platform_task_free(task: *mut *mut c_void);
101
102 pub fn nros_platform_mutex_init(m: *mut c_void) -> i8;
104 pub fn nros_platform_mutex_drop(m: *mut c_void) -> i8;
105 pub fn nros_platform_mutex_lock(m: *mut c_void) -> i8;
106 pub fn nros_platform_mutex_try_lock(m: *mut c_void) -> i8;
107 pub fn nros_platform_mutex_unlock(m: *mut c_void) -> i8;
108
109 pub fn nros_platform_mutex_rec_init(m: *mut c_void) -> i8;
111 pub fn nros_platform_mutex_rec_drop(m: *mut c_void) -> i8;
112 pub fn nros_platform_mutex_rec_lock(m: *mut c_void) -> i8;
113 pub fn nros_platform_mutex_rec_try_lock(m: *mut c_void) -> i8;
114 pub fn nros_platform_mutex_rec_unlock(m: *mut c_void) -> i8;
115
116 pub fn nros_platform_condvar_init(cv: *mut c_void) -> i8;
118 pub fn nros_platform_condvar_drop(cv: *mut c_void) -> i8;
119 pub fn nros_platform_condvar_signal(cv: *mut c_void) -> i8;
120 pub fn nros_platform_condvar_signal_all(cv: *mut c_void) -> i8;
121 pub fn nros_platform_condvar_signal_from_isr(cv: *mut c_void) -> i8;
124 pub fn nros_platform_condvar_wait(cv: *mut c_void, m: *mut c_void) -> i8;
125 pub fn nros_platform_condvar_wait_until(cv: *mut c_void, m: *mut c_void, abstime: u64) -> i8;
126
127 pub fn nros_platform_wake_init(w: *mut c_void) -> i8;
132 pub fn nros_platform_wake_drop(w: *mut c_void) -> i8;
133 pub fn nros_platform_wake_wait_ms(w: *mut c_void, timeout_ms: u32) -> i8;
134 pub fn nros_platform_wake_signal(w: *mut c_void) -> i8;
135 pub fn nros_platform_wake_signal_from_isr(w: *mut c_void) -> i8;
136 pub fn nros_platform_wake_storage_size() -> usize;
137 pub fn nros_platform_wake_storage_align() -> usize;
138
139 pub fn nros_platform_critical_section_acquire() -> u32;
141 pub fn nros_platform_critical_section_release(token: u32);
142
143 pub fn nros_platform_log_write(
145 severity: u8,
146 name_ptr: *const u8,
147 name_len: usize,
148 msg_ptr: *const u8,
149 msg_len: usize,
150 );
151 pub fn nros_platform_log_flush();
152}
153
154pub type NrosPlatformLogWriterFn = unsafe extern "C" fn(
160 severity: u8,
161 name_ptr: *const u8,
162 name_len: usize,
163 msg_ptr: *const u8,
164 msg_len: usize,
165);
166
167pub type NrosPlatformLogFlushFn = unsafe extern "C" fn();
171
172unsafe extern "C" {
173 pub fn nros_platform_register_log_writer(
177 writer: Option<NrosPlatformLogWriterFn>,
178 flusher: Option<NrosPlatformLogFlushFn>,
179 );
180}
181
182unsafe extern "C" {
194 pub fn nros_platform_timer_create_periodic(
196 period_us: u32,
197 callback: unsafe extern "C" fn(*mut c_void),
198 user_data: *mut c_void,
199 ) -> *mut c_void;
200 pub fn nros_platform_timer_create_oneshot(
201 timeout_us: u32,
202 callback: unsafe extern "C" fn(*mut c_void),
203 user_data: *mut c_void,
204 ) -> *mut c_void;
205 pub fn nros_platform_timer_destroy(handle: *mut c_void);
206 pub fn nros_platform_timer_cancel(handle: *mut c_void) -> i8;
207
208 pub fn nros_platform_tcp_create_endpoint(
210 ep: *mut c_void,
211 address: *const u8,
212 port: *const u8,
213 ) -> i8;
214 pub fn nros_platform_tcp_free_endpoint(ep: *mut c_void);
215 pub fn nros_platform_tcp_open(
216 sock: *mut c_void,
217 endpoint: *const c_void,
218 timeout_ms: u32,
219 ) -> i8;
220 pub fn nros_platform_tcp_listen(sock: *mut c_void, endpoint: *const c_void) -> i8;
221 pub fn nros_platform_tcp_close(sock: *mut c_void);
222 pub fn nros_platform_tcp_read(sock: *const c_void, buf: *mut u8, len: usize) -> usize;
223 pub fn nros_platform_tcp_read_exact(sock: *const c_void, buf: *mut u8, len: usize) -> usize;
224 pub fn nros_platform_tcp_send(sock: *const c_void, buf: *const u8, len: usize) -> usize;
225
226 pub fn nros_platform_udp_create_endpoint(
228 ep: *mut c_void,
229 address: *const u8,
230 port: *const u8,
231 ) -> i8;
232 pub fn nros_platform_udp_free_endpoint(ep: *mut c_void);
233 pub fn nros_platform_udp_open(
234 sock: *mut c_void,
235 endpoint: *const c_void,
236 timeout_ms: u32,
237 ) -> i8;
238 pub fn nros_platform_udp_listen(
239 sock: *mut c_void,
240 endpoint: *const c_void,
241 timeout_ms: u32,
242 ) -> i8;
243 pub fn nros_platform_udp_close(sock: *mut c_void);
244 pub fn nros_platform_udp_read(sock: *const c_void, buf: *mut u8, len: usize) -> usize;
245 pub fn nros_platform_udp_read_exact(sock: *const c_void, buf: *mut u8, len: usize) -> usize;
246 pub fn nros_platform_udp_send(
247 sock: *const c_void,
248 buf: *const u8,
249 len: usize,
250 endpoint: *const c_void,
251 ) -> usize;
252 pub fn nros_platform_udp_set_recv_timeout(sock: *const c_void, timeout_ms: u32);
253
254 pub fn nros_platform_udp_mcast_open(
256 sock: *mut c_void,
257 endpoint: *const c_void,
258 lep: *mut c_void,
259 timeout_ms: u32,
260 iface: *const u8,
261 ) -> i8;
262 pub fn nros_platform_udp_mcast_listen(
263 sock: *mut c_void,
264 endpoint: *const c_void,
265 timeout_ms: u32,
266 iface: *const u8,
267 join: *const u8,
268 ) -> i8;
269 pub fn nros_platform_udp_mcast_close(
270 sockrecv: *mut c_void,
271 socksend: *mut c_void,
272 rep: *const c_void,
273 lep: *const c_void,
274 );
275 pub fn nros_platform_udp_mcast_read(
276 sock: *const c_void,
277 buf: *mut u8,
278 len: usize,
279 lep: *const c_void,
280 addr: *mut c_void,
281 ) -> usize;
282 pub fn nros_platform_udp_mcast_read_exact(
283 sock: *const c_void,
284 buf: *mut u8,
285 len: usize,
286 lep: *const c_void,
287 addr: *mut c_void,
288 ) -> usize;
289 pub fn nros_platform_udp_mcast_send(
290 sock: *const c_void,
291 buf: *const u8,
292 len: usize,
293 endpoint: *const c_void,
294 ) -> usize;
295
296 pub fn nros_platform_socket_set_non_blocking(sock: *const c_void) -> i8;
298 pub fn nros_platform_socket_accept(sock_in: *const c_void, sock_out: *mut c_void) -> i8;
299 pub fn nros_platform_socket_close(sock: *mut c_void);
300 pub fn nros_platform_socket_wait_event(peers: *mut c_void, mutex: *mut c_void) -> i8;
301
302 pub fn nros_platform_network_poll();
304}
305
306pub type NrosPlatformRet = i32;
312
313pub const NROS_PLATFORM_RET_OK: NrosPlatformRet = 0;
314pub const NROS_PLATFORM_RET_ERROR: NrosPlatformRet = -1;
315pub const NROS_PLATFORM_RET_UNSUPPORTED: NrosPlatformRet = -5;
316
317pub struct CffiPlatform;
328
329impl nros_platform_api::PlatformClock for CffiPlatform {
330 #[inline]
331 fn clock_ms() -> u64 {
332 unsafe { nros_platform_clock_ms() }
333 }
334
335 #[inline]
336 fn clock_us() -> u64 {
337 unsafe { nros_platform_clock_us() }
338 }
339}
340
341impl nros_platform_api::PlatformAlloc for CffiPlatform {
342 #[inline]
343 fn alloc(size: usize) -> *mut c_void {
344 unsafe { nros_platform_alloc(size) }
345 }
346
347 #[inline]
348 fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void {
349 unsafe { nros_platform_realloc(ptr, size) }
350 }
351
352 #[inline]
353 fn dealloc(ptr: *mut c_void) {
354 unsafe { nros_platform_dealloc(ptr) }
355 }
356
357 #[inline]
358 fn heap_used_bytes() -> usize {
359 unsafe { nros_platform_heap_used_bytes() }
360 }
361
362 #[inline]
363 fn heap_total_bytes() -> usize {
364 unsafe { nros_platform_heap_total_bytes() }
365 }
366}
367
368impl nros_platform_api::PlatformSleep for CffiPlatform {
369 #[inline]
370 fn sleep_us(us: usize) {
371 unsafe { nros_platform_sleep_us(us) }
372 }
373
374 #[inline]
375 fn sleep_ms(ms: usize) {
376 unsafe { nros_platform_sleep_ms(ms) }
377 }
378
379 #[inline]
380 fn sleep_s(s: usize) {
381 unsafe { nros_platform_sleep_s(s) }
382 }
383}
384
385impl nros_platform_api::PlatformYield for CffiPlatform {
386 #[inline]
387 fn yield_now() {
388 unsafe { nros_platform_yield_now() }
389 }
390}
391
392impl nros_platform_api::PlatformScheduler for CffiPlatform {
396 #[inline]
397 fn yield_now() {
398 unsafe { nros_platform_yield_now() }
399 }
400}
401
402#[derive(Debug)]
413pub struct CffiTimerHandle(*mut c_void);
414
415unsafe impl Send for CffiTimerHandle {}
422unsafe impl Sync for CffiTimerHandle {}
423
424impl nros_platform_api::PlatformTimer for CffiPlatform {
425 type TimerHandle = CffiTimerHandle;
426
427 fn create_periodic(
428 period_us: u32,
429 callback: extern "C" fn(*mut c_void),
430 user_data: *mut c_void,
431 ) -> Result<Self::TimerHandle, nros_platform_api::TimerError> {
432 let cb: unsafe extern "C" fn(*mut c_void) = callback;
436 let raw = unsafe { nros_platform_timer_create_periodic(period_us, cb, user_data) };
437 if raw.is_null() {
438 return Err(nros_platform_api::TimerError::KernelError);
446 }
447 Ok(CffiTimerHandle(raw))
448 }
449
450 fn create_oneshot(
451 timeout_us: u32,
452 callback: extern "C" fn(*mut c_void),
453 user_data: *mut c_void,
454 ) -> Result<Self::TimerHandle, nros_platform_api::TimerError> {
455 let cb: unsafe extern "C" fn(*mut c_void) = callback;
456 let raw = unsafe { nros_platform_timer_create_oneshot(timeout_us, cb, user_data) };
457 if raw.is_null() {
458 return Err(nros_platform_api::TimerError::KernelError);
459 }
460 Ok(CffiTimerHandle(raw))
461 }
462
463 fn destroy(handle: Self::TimerHandle) {
464 unsafe { nros_platform_timer_destroy(handle.0) }
465 }
466
467 fn cancel(handle: &mut Self::TimerHandle) -> bool {
468 let rc = unsafe { nros_platform_timer_cancel(handle.0) };
469 rc == 1
473 }
474}
475
476impl nros_platform_api::PlatformRandom for CffiPlatform {
477 #[inline]
478 fn random_u8() -> u8 {
479 unsafe { nros_platform_random_u8() }
480 }
481
482 #[inline]
483 fn random_u16() -> u16 {
484 unsafe { nros_platform_random_u16() }
485 }
486
487 #[inline]
488 fn random_u32() -> u32 {
489 unsafe { nros_platform_random_u32() }
490 }
491
492 #[inline]
493 fn random_u64() -> u64 {
494 unsafe { nros_platform_random_u64() }
495 }
496
497 #[inline]
498 fn random_fill(buf: *mut c_void, len: usize) {
499 unsafe { nros_platform_random_fill(buf, len) }
500 }
501}
502
503impl nros_platform_api::PlatformTime for CffiPlatform {
504 #[inline]
505 fn time_now_ms() -> u64 {
506 unsafe { nros_platform_time_now_ms() }
507 }
508
509 #[inline]
510 fn time_since_epoch_secs() -> u32 {
511 unsafe { nros_platform_time_since_epoch_secs() }
512 }
513
514 #[inline]
515 fn time_since_epoch_nanos() -> u32 {
516 unsafe { nros_platform_time_since_epoch_nanos() }
517 }
518}
519
520impl nros_platform_api::PlatformThreading for CffiPlatform {
521 fn task_init(
522 task: *mut c_void,
523 attr: *mut c_void,
524 entry: Option<unsafe extern "C" fn(*mut c_void) -> *mut c_void>,
525 arg: *mut c_void,
526 ) -> i8 {
527 unsafe { nros_platform_task_init(task, attr, entry, arg) }
528 }
529 fn task_join(task: *mut c_void) -> i8 {
530 unsafe { nros_platform_task_join(task) }
531 }
532 fn task_detach(task: *mut c_void) -> i8 {
533 unsafe { nros_platform_task_detach(task) }
534 }
535 fn task_cancel(task: *mut c_void) -> i8 {
536 unsafe { nros_platform_task_cancel(task) }
537 }
538 fn task_exit() {
539 unsafe { nros_platform_task_exit() }
540 }
541 fn task_free(task: *mut *mut c_void) {
542 unsafe { nros_platform_task_free(task) }
543 }
544 fn mutex_init(m: *mut c_void) -> i8 {
545 unsafe { nros_platform_mutex_init(m) }
546 }
547 fn mutex_drop(m: *mut c_void) -> i8 {
548 unsafe { nros_platform_mutex_drop(m) }
549 }
550 fn mutex_lock(m: *mut c_void) -> i8 {
551 unsafe { nros_platform_mutex_lock(m) }
552 }
553 fn mutex_try_lock(m: *mut c_void) -> i8 {
554 unsafe { nros_platform_mutex_try_lock(m) }
555 }
556 fn mutex_unlock(m: *mut c_void) -> i8 {
557 unsafe { nros_platform_mutex_unlock(m) }
558 }
559 fn mutex_rec_init(m: *mut c_void) -> i8 {
560 unsafe { nros_platform_mutex_rec_init(m) }
561 }
562 fn mutex_rec_drop(m: *mut c_void) -> i8 {
563 unsafe { nros_platform_mutex_rec_drop(m) }
564 }
565 fn mutex_rec_lock(m: *mut c_void) -> i8 {
566 unsafe { nros_platform_mutex_rec_lock(m) }
567 }
568 fn mutex_rec_try_lock(m: *mut c_void) -> i8 {
569 unsafe { nros_platform_mutex_rec_try_lock(m) }
570 }
571 fn mutex_rec_unlock(m: *mut c_void) -> i8 {
572 unsafe { nros_platform_mutex_rec_unlock(m) }
573 }
574 fn condvar_init(cv: *mut c_void) -> i8 {
575 unsafe { nros_platform_condvar_init(cv) }
576 }
577 fn condvar_drop(cv: *mut c_void) -> i8 {
578 unsafe { nros_platform_condvar_drop(cv) }
579 }
580 fn condvar_signal(cv: *mut c_void) -> i8 {
581 unsafe { nros_platform_condvar_signal(cv) }
582 }
583 fn condvar_signal_all(cv: *mut c_void) -> i8 {
584 unsafe { nros_platform_condvar_signal_all(cv) }
585 }
586 fn condvar_signal_from_isr(cv: *mut c_void) -> i8 {
587 unsafe { nros_platform_condvar_signal_from_isr(cv) }
588 }
589 fn condvar_wait(cv: *mut c_void, m: *mut c_void) -> i8 {
590 unsafe { nros_platform_condvar_wait(cv, m) }
591 }
592 fn condvar_wait_until(cv: *mut c_void, m: *mut c_void, abstime: u64) -> i8 {
593 unsafe { nros_platform_condvar_wait_until(cv, m, abstime) }
594 }
595 fn wake_init(w: *mut c_void) -> i8 {
596 unsafe { nros_platform_wake_init(w) }
597 }
598 fn wake_drop(w: *mut c_void) -> i8 {
599 unsafe { nros_platform_wake_drop(w) }
600 }
601 fn wake_wait_ms(w: *mut c_void, timeout_ms: u32) -> i8 {
602 unsafe { nros_platform_wake_wait_ms(w, timeout_ms) }
603 }
604 fn wake_signal(w: *mut c_void) -> i8 {
605 unsafe { nros_platform_wake_signal(w) }
606 }
607 fn wake_signal_from_isr(w: *mut c_void) -> i8 {
608 unsafe { nros_platform_wake_signal_from_isr(w) }
609 }
610 fn wake_storage_size() -> usize {
611 unsafe { nros_platform_wake_storage_size() }
612 }
613 fn wake_storage_align() -> usize {
614 unsafe { nros_platform_wake_storage_align() }
615 }
616}
617
618impl nros_platform_api::PlatformTcp for CffiPlatform {
629 fn create_endpoint(ep: *mut c_void, address: *const u8, port: *const u8) -> i8 {
630 unsafe { nros_platform_tcp_create_endpoint(ep, address, port) }
631 }
632 fn free_endpoint(ep: *mut c_void) {
633 unsafe { nros_platform_tcp_free_endpoint(ep) }
634 }
635 fn open(sock: *mut c_void, endpoint: *const c_void, timeout_ms: u32) -> i8 {
636 unsafe { nros_platform_tcp_open(sock, endpoint, timeout_ms) }
637 }
638 fn listen(sock: *mut c_void, endpoint: *const c_void) -> i8 {
639 unsafe { nros_platform_tcp_listen(sock, endpoint) }
640 }
641 fn close(sock: *mut c_void) {
642 unsafe { nros_platform_tcp_close(sock) }
643 }
644 fn read(sock: *const c_void, buf: *mut u8, len: usize) -> usize {
645 unsafe { nros_platform_tcp_read(sock, buf, len) }
646 }
647 fn read_exact(sock: *const c_void, buf: *mut u8, len: usize) -> usize {
648 unsafe { nros_platform_tcp_read_exact(sock, buf, len) }
649 }
650 fn send(sock: *const c_void, buf: *const u8, len: usize) -> usize {
651 unsafe { nros_platform_tcp_send(sock, buf, len) }
652 }
653}
654
655impl nros_platform_api::PlatformUdp for CffiPlatform {
656 fn create_endpoint(ep: *mut c_void, address: *const u8, port: *const u8) -> i8 {
657 unsafe { nros_platform_udp_create_endpoint(ep, address, port) }
658 }
659 fn free_endpoint(ep: *mut c_void) {
660 unsafe { nros_platform_udp_free_endpoint(ep) }
661 }
662 fn open(sock: *mut c_void, endpoint: *const c_void, timeout_ms: u32) -> i8 {
663 unsafe { nros_platform_udp_open(sock, endpoint, timeout_ms) }
664 }
665 fn listen(sock: *mut c_void, endpoint: *const c_void, timeout_ms: u32) -> i8 {
666 unsafe { nros_platform_udp_listen(sock, endpoint, timeout_ms) }
667 }
668 fn close(sock: *mut c_void) {
669 unsafe { nros_platform_udp_close(sock) }
670 }
671 fn read(sock: *const c_void, buf: *mut u8, len: usize) -> usize {
672 unsafe { nros_platform_udp_read(sock, buf, len) }
673 }
674 fn read_exact(sock: *const c_void, buf: *mut u8, len: usize) -> usize {
675 unsafe { nros_platform_udp_read_exact(sock, buf, len) }
676 }
677 fn send(sock: *const c_void, buf: *const u8, len: usize, endpoint: *const c_void) -> usize {
678 unsafe { nros_platform_udp_send(sock, buf, len, endpoint) }
679 }
680 fn set_recv_timeout(sock: *const c_void, timeout_ms: u32) {
681 unsafe { nros_platform_udp_set_recv_timeout(sock, timeout_ms) }
682 }
683}
684
685impl nros_platform_api::PlatformUdpMulticast for CffiPlatform {
686 fn mcast_open(
687 sock: *mut c_void,
688 endpoint: *const c_void,
689 lep: *mut c_void,
690 timeout_ms: u32,
691 iface: *const u8,
692 ) -> i8 {
693 unsafe { nros_platform_udp_mcast_open(sock, endpoint, lep, timeout_ms, iface) }
694 }
695 fn mcast_listen(
696 sock: *mut c_void,
697 endpoint: *const c_void,
698 timeout_ms: u32,
699 iface: *const u8,
700 join: *const u8,
701 ) -> i8 {
702 unsafe { nros_platform_udp_mcast_listen(sock, endpoint, timeout_ms, iface, join) }
703 }
704 fn mcast_close(
705 sockrecv: *mut c_void,
706 socksend: *mut c_void,
707 rep: *const c_void,
708 lep: *const c_void,
709 ) {
710 unsafe { nros_platform_udp_mcast_close(sockrecv, socksend, rep, lep) }
711 }
712 fn mcast_read(
713 sock: *const c_void,
714 buf: *mut u8,
715 len: usize,
716 lep: *const c_void,
717 addr: *mut c_void,
718 ) -> usize {
719 unsafe { nros_platform_udp_mcast_read(sock, buf, len, lep, addr) }
720 }
721 fn mcast_read_exact(
722 sock: *const c_void,
723 buf: *mut u8,
724 len: usize,
725 lep: *const c_void,
726 addr: *mut c_void,
727 ) -> usize {
728 unsafe { nros_platform_udp_mcast_read_exact(sock, buf, len, lep, addr) }
729 }
730 fn mcast_send(
731 sock: *const c_void,
732 buf: *const u8,
733 len: usize,
734 endpoint: *const c_void,
735 ) -> usize {
736 unsafe { nros_platform_udp_mcast_send(sock, buf, len, endpoint) }
737 }
738}
739
740impl nros_platform_api::PlatformSocketHelpers for CffiPlatform {
741 fn set_non_blocking(sock: *const c_void) -> i8 {
742 unsafe { nros_platform_socket_set_non_blocking(sock) }
743 }
744 fn accept(sock_in: *const c_void, sock_out: *mut c_void) -> i8 {
745 unsafe { nros_platform_socket_accept(sock_in, sock_out) }
746 }
747 fn close(sock: *mut c_void) {
748 unsafe { nros_platform_socket_close(sock) }
749 }
750 fn wait_event(peers: *mut c_void, mutex: *mut c_void) -> i8 {
751 unsafe { nros_platform_socket_wait_event(peers, mutex) }
752 }
753}
754
755impl nros_platform_api::PlatformNetworkPoll for CffiPlatform {
756 fn network_poll() {
757 unsafe { nros_platform_network_poll() }
758 }
759}
760
761impl nros_platform_api::PlatformCriticalSection for CffiPlatform {
762 fn acquire() -> u32 {
763 unsafe { nros_platform_critical_section_acquire() }
764 }
765 fn release(token: u32) {
766 unsafe { nros_platform_critical_section_release(token) }
767 }
768}
769
770impl nros_platform_api::PlatformLog for CffiPlatform {
771 fn write(severity: u8, name: &[u8], message: &[u8]) {
772 unsafe {
776 nros_platform_log_write(
777 severity,
778 name.as_ptr(),
779 name.len(),
780 message.as_ptr(),
781 message.len(),
782 );
783 }
784 }
785
786 fn flush() {
787 unsafe { nros_platform_log_flush() };
789 }
790}
791
792#[macro_export]
811macro_rules! nros_platform_export_clock {
812 ($ty:ty) => {
813 #[unsafe(no_mangle)]
814 pub extern "C" fn nros_platform_clock_ms() -> u64 {
815 <$ty as ::nros_platform_api::PlatformClock>::clock_ms()
816 }
817 #[unsafe(no_mangle)]
818 pub extern "C" fn nros_platform_clock_us() -> u64 {
819 <$ty as ::nros_platform_api::PlatformClock>::clock_us()
820 }
821 };
822}
823
824#[macro_export]
827macro_rules! nros_platform_export_alloc {
828 ($ty:ty) => {
829 #[unsafe(no_mangle)]
830 pub extern "C" fn nros_platform_alloc(size: usize) -> *mut ::core::ffi::c_void {
831 <$ty as ::nros_platform_api::PlatformAlloc>::alloc(size)
832 }
833 #[unsafe(no_mangle)]
834 pub extern "C" fn nros_platform_realloc(
835 ptr: *mut ::core::ffi::c_void,
836 size: usize,
837 ) -> *mut ::core::ffi::c_void {
838 <$ty as ::nros_platform_api::PlatformAlloc>::realloc(ptr, size)
839 }
840 #[unsafe(no_mangle)]
841 pub extern "C" fn nros_platform_dealloc(ptr: *mut ::core::ffi::c_void) {
842 <$ty as ::nros_platform_api::PlatformAlloc>::dealloc(ptr)
843 }
844 #[unsafe(no_mangle)]
845 pub extern "C" fn nros_platform_heap_used_bytes() -> usize {
846 <$ty as ::nros_platform_api::PlatformAlloc>::heap_used_bytes()
847 }
848 #[unsafe(no_mangle)]
849 pub extern "C" fn nros_platform_heap_total_bytes() -> usize {
850 <$ty as ::nros_platform_api::PlatformAlloc>::heap_total_bytes()
851 }
852 };
853}
854
855#[macro_export]
858macro_rules! nros_platform_export_sleep {
859 ($ty:ty) => {
860 #[unsafe(no_mangle)]
861 pub extern "C" fn nros_platform_sleep_us(us: usize) {
862 <$ty as ::nros_platform_api::PlatformSleep>::sleep_us(us)
863 }
864 #[unsafe(no_mangle)]
865 pub extern "C" fn nros_platform_sleep_ms(ms: usize) {
866 <$ty as ::nros_platform_api::PlatformSleep>::sleep_ms(ms)
867 }
868 #[unsafe(no_mangle)]
869 pub extern "C" fn nros_platform_sleep_s(s: usize) {
870 <$ty as ::nros_platform_api::PlatformSleep>::sleep_s(s)
871 }
872 };
873}
874
875#[macro_export]
878macro_rules! nros_platform_export_yield {
879 ($ty:ty) => {
880 #[unsafe(no_mangle)]
881 pub extern "C" fn nros_platform_yield_now() {
882 <$ty as ::nros_platform_api::PlatformYield>::yield_now()
883 }
884 };
885}
886
887#[macro_export]
889macro_rules! nros_platform_export_random {
890 ($ty:ty) => {
891 #[unsafe(no_mangle)]
892 pub extern "C" fn nros_platform_random_u8() -> u8 {
893 <$ty as ::nros_platform_api::PlatformRandom>::random_u8()
894 }
895 #[unsafe(no_mangle)]
896 pub extern "C" fn nros_platform_random_u16() -> u16 {
897 <$ty as ::nros_platform_api::PlatformRandom>::random_u16()
898 }
899 #[unsafe(no_mangle)]
900 pub extern "C" fn nros_platform_random_u32() -> u32 {
901 <$ty as ::nros_platform_api::PlatformRandom>::random_u32()
902 }
903 #[unsafe(no_mangle)]
904 pub extern "C" fn nros_platform_random_u64() -> u64 {
905 <$ty as ::nros_platform_api::PlatformRandom>::random_u64()
906 }
907 #[unsafe(no_mangle)]
908 pub extern "C" fn nros_platform_random_fill(buf: *mut ::core::ffi::c_void, len: usize) {
909 <$ty as ::nros_platform_api::PlatformRandom>::random_fill(buf, len)
910 }
911 };
912}
913
914#[macro_export]
916macro_rules! nros_platform_export_time {
917 ($ty:ty) => {
918 #[unsafe(no_mangle)]
919 pub extern "C" fn nros_platform_time_now_ms() -> u64 {
920 <$ty as ::nros_platform_api::PlatformTime>::time_now_ms()
921 }
922 #[unsafe(no_mangle)]
923 pub extern "C" fn nros_platform_time_since_epoch_secs() -> u32 {
924 <$ty as ::nros_platform_api::PlatformTime>::time_since_epoch_secs()
925 }
926 #[unsafe(no_mangle)]
927 pub extern "C" fn nros_platform_time_since_epoch_nanos() -> u32 {
928 <$ty as ::nros_platform_api::PlatformTime>::time_since_epoch_nanos()
929 }
930 };
931}
932
933#[macro_export]
938macro_rules! nros_platform_export_threading {
939 ($ty:ty) => {
940 #[unsafe(no_mangle)]
941 pub extern "C" fn nros_platform_task_init(
942 task: *mut ::core::ffi::c_void,
943 attr: *mut ::core::ffi::c_void,
944 entry: ::core::option::Option<
945 unsafe extern "C" fn(*mut ::core::ffi::c_void) -> *mut ::core::ffi::c_void,
946 >,
947 arg: *mut ::core::ffi::c_void,
948 ) -> i8 {
949 <$ty as ::nros_platform_api::PlatformThreading>::task_init(task, attr, entry, arg)
950 }
951 #[unsafe(no_mangle)]
952 pub extern "C" fn nros_platform_task_join(task: *mut ::core::ffi::c_void) -> i8 {
953 <$ty as ::nros_platform_api::PlatformThreading>::task_join(task)
954 }
955 #[unsafe(no_mangle)]
956 pub extern "C" fn nros_platform_task_detach(task: *mut ::core::ffi::c_void) -> i8 {
957 <$ty as ::nros_platform_api::PlatformThreading>::task_detach(task)
958 }
959 #[unsafe(no_mangle)]
960 pub extern "C" fn nros_platform_task_cancel(task: *mut ::core::ffi::c_void) -> i8 {
961 <$ty as ::nros_platform_api::PlatformThreading>::task_cancel(task)
962 }
963 #[unsafe(no_mangle)]
964 pub extern "C" fn nros_platform_task_exit() {
965 <$ty as ::nros_platform_api::PlatformThreading>::task_exit()
966 }
967 #[unsafe(no_mangle)]
968 pub extern "C" fn nros_platform_task_free(task: *mut *mut ::core::ffi::c_void) {
969 <$ty as ::nros_platform_api::PlatformThreading>::task_free(task)
970 }
971 #[unsafe(no_mangle)]
972 pub extern "C" fn nros_platform_mutex_init(m: *mut ::core::ffi::c_void) -> i8 {
973 <$ty as ::nros_platform_api::PlatformThreading>::mutex_init(m)
974 }
975 #[unsafe(no_mangle)]
976 pub extern "C" fn nros_platform_mutex_drop(m: *mut ::core::ffi::c_void) -> i8 {
977 <$ty as ::nros_platform_api::PlatformThreading>::mutex_drop(m)
978 }
979 #[unsafe(no_mangle)]
980 pub extern "C" fn nros_platform_mutex_lock(m: *mut ::core::ffi::c_void) -> i8 {
981 <$ty as ::nros_platform_api::PlatformThreading>::mutex_lock(m)
982 }
983 #[unsafe(no_mangle)]
984 pub extern "C" fn nros_platform_mutex_try_lock(m: *mut ::core::ffi::c_void) -> i8 {
985 <$ty as ::nros_platform_api::PlatformThreading>::mutex_try_lock(m)
986 }
987 #[unsafe(no_mangle)]
988 pub extern "C" fn nros_platform_mutex_unlock(m: *mut ::core::ffi::c_void) -> i8 {
989 <$ty as ::nros_platform_api::PlatformThreading>::mutex_unlock(m)
990 }
991 #[unsafe(no_mangle)]
992 pub extern "C" fn nros_platform_mutex_rec_init(m: *mut ::core::ffi::c_void) -> i8 {
993 <$ty as ::nros_platform_api::PlatformThreading>::mutex_rec_init(m)
994 }
995 #[unsafe(no_mangle)]
996 pub extern "C" fn nros_platform_mutex_rec_drop(m: *mut ::core::ffi::c_void) -> i8 {
997 <$ty as ::nros_platform_api::PlatformThreading>::mutex_rec_drop(m)
998 }
999 #[unsafe(no_mangle)]
1000 pub extern "C" fn nros_platform_mutex_rec_lock(m: *mut ::core::ffi::c_void) -> i8 {
1001 <$ty as ::nros_platform_api::PlatformThreading>::mutex_rec_lock(m)
1002 }
1003 #[unsafe(no_mangle)]
1004 pub extern "C" fn nros_platform_mutex_rec_try_lock(m: *mut ::core::ffi::c_void) -> i8 {
1005 <$ty as ::nros_platform_api::PlatformThreading>::mutex_rec_try_lock(m)
1006 }
1007 #[unsafe(no_mangle)]
1008 pub extern "C" fn nros_platform_mutex_rec_unlock(m: *mut ::core::ffi::c_void) -> i8 {
1009 <$ty as ::nros_platform_api::PlatformThreading>::mutex_rec_unlock(m)
1010 }
1011 #[unsafe(no_mangle)]
1012 pub extern "C" fn nros_platform_condvar_init(cv: *mut ::core::ffi::c_void) -> i8 {
1013 <$ty as ::nros_platform_api::PlatformThreading>::condvar_init(cv)
1014 }
1015 #[unsafe(no_mangle)]
1016 pub extern "C" fn nros_platform_condvar_drop(cv: *mut ::core::ffi::c_void) -> i8 {
1017 <$ty as ::nros_platform_api::PlatformThreading>::condvar_drop(cv)
1018 }
1019 #[unsafe(no_mangle)]
1020 pub extern "C" fn nros_platform_condvar_signal(cv: *mut ::core::ffi::c_void) -> i8 {
1021 <$ty as ::nros_platform_api::PlatformThreading>::condvar_signal(cv)
1022 }
1023 #[unsafe(no_mangle)]
1024 pub extern "C" fn nros_platform_condvar_signal_all(cv: *mut ::core::ffi::c_void) -> i8 {
1025 <$ty as ::nros_platform_api::PlatformThreading>::condvar_signal_all(cv)
1026 }
1027 #[unsafe(no_mangle)]
1028 pub extern "C" fn nros_platform_condvar_signal_from_isr(
1029 cv: *mut ::core::ffi::c_void,
1030 ) -> i8 {
1031 <$ty as ::nros_platform_api::PlatformThreading>::condvar_signal_from_isr(cv)
1032 }
1033 #[unsafe(no_mangle)]
1034 pub extern "C" fn nros_platform_condvar_wait(
1035 cv: *mut ::core::ffi::c_void,
1036 m: *mut ::core::ffi::c_void,
1037 ) -> i8 {
1038 <$ty as ::nros_platform_api::PlatformThreading>::condvar_wait(cv, m)
1039 }
1040 #[unsafe(no_mangle)]
1041 pub extern "C" fn nros_platform_condvar_wait_until(
1042 cv: *mut ::core::ffi::c_void,
1043 m: *mut ::core::ffi::c_void,
1044 abstime: u64,
1045 ) -> i8 {
1046 <$ty as ::nros_platform_api::PlatformThreading>::condvar_wait_until(cv, m, abstime)
1047 }
1048 #[unsafe(no_mangle)]
1050 pub extern "C" fn nros_platform_wake_init(w: *mut ::core::ffi::c_void) -> i8 {
1051 <$ty as ::nros_platform_api::PlatformThreading>::wake_init(w)
1052 }
1053 #[unsafe(no_mangle)]
1054 pub extern "C" fn nros_platform_wake_drop(w: *mut ::core::ffi::c_void) -> i8 {
1055 <$ty as ::nros_platform_api::PlatformThreading>::wake_drop(w)
1056 }
1057 #[unsafe(no_mangle)]
1058 pub extern "C" fn nros_platform_wake_wait_ms(
1059 w: *mut ::core::ffi::c_void,
1060 timeout_ms: u32,
1061 ) -> i8 {
1062 <$ty as ::nros_platform_api::PlatformThreading>::wake_wait_ms(w, timeout_ms)
1063 }
1064 #[unsafe(no_mangle)]
1065 pub extern "C" fn nros_platform_wake_signal(w: *mut ::core::ffi::c_void) -> i8 {
1066 <$ty as ::nros_platform_api::PlatformThreading>::wake_signal(w)
1067 }
1068 #[unsafe(no_mangle)]
1069 pub extern "C" fn nros_platform_wake_signal_from_isr(w: *mut ::core::ffi::c_void) -> i8 {
1070 <$ty as ::nros_platform_api::PlatformThreading>::wake_signal_from_isr(w)
1071 }
1072 #[unsafe(no_mangle)]
1073 pub extern "C" fn nros_platform_wake_storage_size() -> usize {
1074 <$ty as ::nros_platform_api::PlatformThreading>::wake_storage_size()
1075 }
1076 #[unsafe(no_mangle)]
1077 pub extern "C" fn nros_platform_wake_storage_align() -> usize {
1078 <$ty as ::nros_platform_api::PlatformThreading>::wake_storage_align()
1079 }
1080 };
1081}
1082
1083#[macro_export]
1087macro_rules! nros_platform_export_critical_section {
1088 ($ty:ty) => {
1089 #[unsafe(no_mangle)]
1090 pub extern "C" fn nros_platform_critical_section_acquire() -> u32 {
1091 <$ty as ::nros_platform_api::PlatformCriticalSection>::acquire()
1092 }
1093 #[unsafe(no_mangle)]
1094 pub extern "C" fn nros_platform_critical_section_release(token: u32) {
1095 <$ty as ::nros_platform_api::PlatformCriticalSection>::release(token)
1096 }
1097 };
1098}
1099
1100#[macro_export]
1106macro_rules! nros_platform_export_log {
1107 ($ty:ty) => {
1108 #[unsafe(no_mangle)]
1109 pub extern "C" fn nros_platform_log_write(
1110 severity: u8,
1111 name_ptr: *const u8,
1112 name_len: usize,
1113 msg_ptr: *const u8,
1114 msg_len: usize,
1115 ) {
1116 let name: &[u8] = if name_ptr.is_null() || name_len == 0 {
1120 &[]
1121 } else {
1122 unsafe { ::core::slice::from_raw_parts(name_ptr, name_len) }
1123 };
1124 let msg: &[u8] = if msg_ptr.is_null() || msg_len == 0 {
1125 &[]
1126 } else {
1127 unsafe { ::core::slice::from_raw_parts(msg_ptr, msg_len) }
1128 };
1129 <$ty as ::nros_platform_api::PlatformLog>::write(severity, name, msg);
1130 }
1131 #[unsafe(no_mangle)]
1132 pub extern "C" fn nros_platform_log_flush() {
1133 <$ty as ::nros_platform_api::PlatformLog>::flush()
1134 }
1135 #[unsafe(no_mangle)]
1145 pub extern "C" fn nros_platform_register_log_writer(
1146 _writer: ::core::option::Option<
1147 unsafe extern "C" fn(
1148 severity: u8,
1149 name_ptr: *const u8,
1150 name_len: usize,
1151 msg_ptr: *const u8,
1152 msg_len: usize,
1153 ),
1154 >,
1155 _flusher: ::core::option::Option<unsafe extern "C" fn()>,
1156 ) {
1157 }
1158 };
1159}
1160
1161#[macro_export]
1172macro_rules! nros_platform_export {
1173 ($ty:ty) => {
1174 $crate::nros_platform_export_clock!($ty);
1175 $crate::nros_platform_export_alloc!($ty);
1176 $crate::nros_platform_export_sleep!($ty);
1177 $crate::nros_platform_export_yield!($ty);
1178 $crate::nros_platform_export_random!($ty);
1179 $crate::nros_platform_export_time!($ty);
1180 $crate::nros_platform_export_threading!($ty);
1181 $crate::nros_platform_export_critical_section!($ty);
1182 };
1183}
1184
1185#[macro_export]
1206macro_rules! nros_platform_export_timer {
1207 ($ty:ty) => {
1208 const _: () = {
1215 if ::core::mem::size_of::<<$ty as ::nros_platform_api::PlatformTimer>::TimerHandle>()
1216 != ::core::mem::size_of::<*mut ::core::ffi::c_void>()
1217 {
1218 panic!(
1219 "nros_platform_export_timer! requires \
1220 PlatformTimer::TimerHandle to be pointer-sized"
1221 );
1222 }
1223 };
1224
1225 #[unsafe(no_mangle)]
1226 pub extern "C" fn nros_platform_timer_create_periodic(
1227 period_us: u32,
1228 callback: extern "C" fn(*mut ::core::ffi::c_void),
1229 user_data: *mut ::core::ffi::c_void,
1230 ) -> *mut ::core::ffi::c_void {
1231 match <$ty as ::nros_platform_api::PlatformTimer>::create_periodic(
1232 period_us, callback, user_data,
1233 ) {
1234 Ok(h) => unsafe {
1235 ::core::mem::transmute_copy::<
1236 <$ty as ::nros_platform_api::PlatformTimer>::TimerHandle,
1237 *mut ::core::ffi::c_void,
1238 >(&::core::mem::ManuallyDrop::new(h))
1239 },
1240 Err(_) => ::core::ptr::null_mut(),
1241 }
1242 }
1243 #[unsafe(no_mangle)]
1244 pub extern "C" fn nros_platform_timer_create_oneshot(
1245 timeout_us: u32,
1246 callback: extern "C" fn(*mut ::core::ffi::c_void),
1247 user_data: *mut ::core::ffi::c_void,
1248 ) -> *mut ::core::ffi::c_void {
1249 match <$ty as ::nros_platform_api::PlatformTimer>::create_oneshot(
1250 timeout_us, callback, user_data,
1251 ) {
1252 Ok(h) => unsafe {
1253 ::core::mem::transmute_copy::<
1254 <$ty as ::nros_platform_api::PlatformTimer>::TimerHandle,
1255 *mut ::core::ffi::c_void,
1256 >(&::core::mem::ManuallyDrop::new(h))
1257 },
1258 Err(_) => ::core::ptr::null_mut(),
1259 }
1260 }
1261 #[unsafe(no_mangle)]
1262 pub extern "C" fn nros_platform_timer_destroy(handle: *mut ::core::ffi::c_void) {
1263 let h: <$ty as ::nros_platform_api::PlatformTimer>::TimerHandle = unsafe {
1264 ::core::mem::transmute_copy::<
1265 *mut ::core::ffi::c_void,
1266 <$ty as ::nros_platform_api::PlatformTimer>::TimerHandle,
1267 >(&handle)
1268 };
1269 <$ty as ::nros_platform_api::PlatformTimer>::destroy(h)
1270 }
1271 #[unsafe(no_mangle)]
1272 pub extern "C" fn nros_platform_timer_cancel(handle: *mut ::core::ffi::c_void) -> i8 {
1273 let mut h: <$ty as ::nros_platform_api::PlatformTimer>::TimerHandle = unsafe {
1274 ::core::mem::transmute_copy::<
1275 *mut ::core::ffi::c_void,
1276 <$ty as ::nros_platform_api::PlatformTimer>::TimerHandle,
1277 >(&handle)
1278 };
1279 if <$ty as ::nros_platform_api::PlatformTimer>::cancel(&mut h) {
1280 1
1281 } else {
1282 0
1283 }
1284 }
1285 };
1286}
1287
1288#[macro_export]
1296macro_rules! nros_platform_export_net {
1297 ($ty:ty) => {
1298 #[unsafe(no_mangle)]
1300 pub extern "C" fn nros_platform_tcp_create_endpoint(
1301 ep: *mut ::core::ffi::c_void,
1302 address: *const u8,
1303 port: *const u8,
1304 ) -> i8 {
1305 <$ty as ::nros_platform_api::PlatformTcp>::create_endpoint(ep, address, port)
1306 }
1307 #[unsafe(no_mangle)]
1308 pub extern "C" fn nros_platform_tcp_free_endpoint(ep: *mut ::core::ffi::c_void) {
1309 <$ty as ::nros_platform_api::PlatformTcp>::free_endpoint(ep)
1310 }
1311 #[unsafe(no_mangle)]
1312 pub extern "C" fn nros_platform_tcp_open(
1313 sock: *mut ::core::ffi::c_void,
1314 endpoint: *const ::core::ffi::c_void,
1315 timeout_ms: u32,
1316 ) -> i8 {
1317 <$ty as ::nros_platform_api::PlatformTcp>::open(sock, endpoint, timeout_ms)
1318 }
1319 #[unsafe(no_mangle)]
1320 pub extern "C" fn nros_platform_tcp_listen(
1321 sock: *mut ::core::ffi::c_void,
1322 endpoint: *const ::core::ffi::c_void,
1323 ) -> i8 {
1324 <$ty as ::nros_platform_api::PlatformTcp>::listen(sock, endpoint)
1325 }
1326 #[unsafe(no_mangle)]
1327 pub extern "C" fn nros_platform_tcp_close(sock: *mut ::core::ffi::c_void) {
1328 <$ty as ::nros_platform_api::PlatformTcp>::close(sock)
1329 }
1330 #[unsafe(no_mangle)]
1331 pub extern "C" fn nros_platform_tcp_read(
1332 sock: *const ::core::ffi::c_void,
1333 buf: *mut u8,
1334 len: usize,
1335 ) -> usize {
1336 <$ty as ::nros_platform_api::PlatformTcp>::read(sock, buf, len)
1337 }
1338 #[unsafe(no_mangle)]
1339 pub extern "C" fn nros_platform_tcp_read_exact(
1340 sock: *const ::core::ffi::c_void,
1341 buf: *mut u8,
1342 len: usize,
1343 ) -> usize {
1344 <$ty as ::nros_platform_api::PlatformTcp>::read_exact(sock, buf, len)
1345 }
1346 #[unsafe(no_mangle)]
1347 pub extern "C" fn nros_platform_tcp_send(
1348 sock: *const ::core::ffi::c_void,
1349 buf: *const u8,
1350 len: usize,
1351 ) -> usize {
1352 <$ty as ::nros_platform_api::PlatformTcp>::send(sock, buf, len)
1353 }
1354
1355 #[unsafe(no_mangle)]
1357 pub extern "C" fn nros_platform_udp_create_endpoint(
1358 ep: *mut ::core::ffi::c_void,
1359 address: *const u8,
1360 port: *const u8,
1361 ) -> i8 {
1362 <$ty as ::nros_platform_api::PlatformUdp>::create_endpoint(ep, address, port)
1363 }
1364 #[unsafe(no_mangle)]
1365 pub extern "C" fn nros_platform_udp_free_endpoint(ep: *mut ::core::ffi::c_void) {
1366 <$ty as ::nros_platform_api::PlatformUdp>::free_endpoint(ep)
1367 }
1368 #[unsafe(no_mangle)]
1369 pub extern "C" fn nros_platform_udp_open(
1370 sock: *mut ::core::ffi::c_void,
1371 endpoint: *const ::core::ffi::c_void,
1372 timeout_ms: u32,
1373 ) -> i8 {
1374 <$ty as ::nros_platform_api::PlatformUdp>::open(sock, endpoint, timeout_ms)
1375 }
1376 #[unsafe(no_mangle)]
1377 pub extern "C" fn nros_platform_udp_listen(
1378 sock: *mut ::core::ffi::c_void,
1379 endpoint: *const ::core::ffi::c_void,
1380 timeout_ms: u32,
1381 ) -> i8 {
1382 <$ty as ::nros_platform_api::PlatformUdp>::listen(sock, endpoint, timeout_ms)
1383 }
1384 #[unsafe(no_mangle)]
1385 pub extern "C" fn nros_platform_udp_close(sock: *mut ::core::ffi::c_void) {
1386 <$ty as ::nros_platform_api::PlatformUdp>::close(sock)
1387 }
1388 #[unsafe(no_mangle)]
1389 pub extern "C" fn nros_platform_udp_read(
1390 sock: *const ::core::ffi::c_void,
1391 buf: *mut u8,
1392 len: usize,
1393 ) -> usize {
1394 <$ty as ::nros_platform_api::PlatformUdp>::read(sock, buf, len)
1395 }
1396 #[unsafe(no_mangle)]
1397 pub extern "C" fn nros_platform_udp_read_exact(
1398 sock: *const ::core::ffi::c_void,
1399 buf: *mut u8,
1400 len: usize,
1401 ) -> usize {
1402 <$ty as ::nros_platform_api::PlatformUdp>::read_exact(sock, buf, len)
1403 }
1404 #[unsafe(no_mangle)]
1405 pub extern "C" fn nros_platform_udp_send(
1406 sock: *const ::core::ffi::c_void,
1407 buf: *const u8,
1408 len: usize,
1409 endpoint: *const ::core::ffi::c_void,
1410 ) -> usize {
1411 <$ty as ::nros_platform_api::PlatformUdp>::send(sock, buf, len, endpoint)
1412 }
1413 #[unsafe(no_mangle)]
1414 pub extern "C" fn nros_platform_udp_set_recv_timeout(
1415 sock: *const ::core::ffi::c_void,
1416 timeout_ms: u32,
1417 ) {
1418 <$ty as ::nros_platform_api::PlatformUdp>::set_recv_timeout(sock, timeout_ms)
1419 }
1420
1421 #[unsafe(no_mangle)]
1423 pub extern "C" fn nros_platform_udp_mcast_open(
1424 sock: *mut ::core::ffi::c_void,
1425 endpoint: *const ::core::ffi::c_void,
1426 lep: *mut ::core::ffi::c_void,
1427 timeout_ms: u32,
1428 iface: *const u8,
1429 ) -> i8 {
1430 <$ty as ::nros_platform_api::PlatformUdpMulticast>::mcast_open(
1431 sock, endpoint, lep, timeout_ms, iface,
1432 )
1433 }
1434 #[unsafe(no_mangle)]
1435 pub extern "C" fn nros_platform_udp_mcast_listen(
1436 sock: *mut ::core::ffi::c_void,
1437 endpoint: *const ::core::ffi::c_void,
1438 timeout_ms: u32,
1439 iface: *const u8,
1440 join: *const u8,
1441 ) -> i8 {
1442 <$ty as ::nros_platform_api::PlatformUdpMulticast>::mcast_listen(
1443 sock, endpoint, timeout_ms, iface, join,
1444 )
1445 }
1446 #[unsafe(no_mangle)]
1447 pub extern "C" fn nros_platform_udp_mcast_close(
1448 sockrecv: *mut ::core::ffi::c_void,
1449 socksend: *mut ::core::ffi::c_void,
1450 rep: *const ::core::ffi::c_void,
1451 lep: *const ::core::ffi::c_void,
1452 ) {
1453 <$ty as ::nros_platform_api::PlatformUdpMulticast>::mcast_close(
1454 sockrecv, socksend, rep, lep,
1455 )
1456 }
1457 #[unsafe(no_mangle)]
1458 pub extern "C" fn nros_platform_udp_mcast_read(
1459 sock: *const ::core::ffi::c_void,
1460 buf: *mut u8,
1461 len: usize,
1462 lep: *const ::core::ffi::c_void,
1463 addr: *mut ::core::ffi::c_void,
1464 ) -> usize {
1465 <$ty as ::nros_platform_api::PlatformUdpMulticast>::mcast_read(
1466 sock, buf, len, lep, addr,
1467 )
1468 }
1469 #[unsafe(no_mangle)]
1470 pub extern "C" fn nros_platform_udp_mcast_read_exact(
1471 sock: *const ::core::ffi::c_void,
1472 buf: *mut u8,
1473 len: usize,
1474 lep: *const ::core::ffi::c_void,
1475 addr: *mut ::core::ffi::c_void,
1476 ) -> usize {
1477 <$ty as ::nros_platform_api::PlatformUdpMulticast>::mcast_read_exact(
1478 sock, buf, len, lep, addr,
1479 )
1480 }
1481 #[unsafe(no_mangle)]
1482 pub extern "C" fn nros_platform_udp_mcast_send(
1483 sock: *const ::core::ffi::c_void,
1484 buf: *const u8,
1485 len: usize,
1486 endpoint: *const ::core::ffi::c_void,
1487 ) -> usize {
1488 <$ty as ::nros_platform_api::PlatformUdpMulticast>::mcast_send(sock, buf, len, endpoint)
1489 }
1490
1491 #[unsafe(no_mangle)]
1493 pub extern "C" fn nros_platform_socket_set_non_blocking(
1494 sock: *const ::core::ffi::c_void,
1495 ) -> i8 {
1496 <$ty as ::nros_platform_api::PlatformSocketHelpers>::set_non_blocking(sock)
1497 }
1498 #[unsafe(no_mangle)]
1499 pub extern "C" fn nros_platform_socket_accept(
1500 sock_in: *const ::core::ffi::c_void,
1501 sock_out: *mut ::core::ffi::c_void,
1502 ) -> i8 {
1503 <$ty as ::nros_platform_api::PlatformSocketHelpers>::accept(sock_in, sock_out)
1504 }
1505 #[unsafe(no_mangle)]
1506 pub extern "C" fn nros_platform_socket_close(sock: *mut ::core::ffi::c_void) {
1507 <$ty as ::nros_platform_api::PlatformSocketHelpers>::close(sock)
1508 }
1509 #[unsafe(no_mangle)]
1510 pub extern "C" fn nros_platform_socket_wait_event(
1511 peers: *mut ::core::ffi::c_void,
1512 mutex: *mut ::core::ffi::c_void,
1513 ) -> i8 {
1514 <$ty as ::nros_platform_api::PlatformSocketHelpers>::wait_event(peers, mutex)
1515 }
1516
1517 #[unsafe(no_mangle)]
1519 pub extern "C" fn nros_platform_network_poll() {
1520 <$ty as ::nros_platform_api::PlatformNetworkPoll>::network_poll()
1521 }
1522 };
1523}
1524
1525#[cfg(all(test, not(feature = "c-stub-test"), not(feature = "posix-c-port")))]
1539mod test_self_export {
1540 use core::ffi::c_void;
1541 use nros_platform_api::{
1542 PlatformAlloc, PlatformClock, PlatformRandom, PlatformSleep, PlatformThreading,
1543 PlatformTime, PlatformYield,
1544 };
1545
1546 pub struct TestPlatform;
1547
1548 impl PlatformClock for TestPlatform {
1549 fn clock_ms() -> u64 {
1550 0
1551 }
1552 fn clock_us() -> u64 {
1553 0
1554 }
1555 }
1556 impl PlatformAlloc for TestPlatform {
1557 fn alloc(_: usize) -> *mut c_void {
1558 core::ptr::null_mut()
1559 }
1560 fn realloc(_: *mut c_void, _: usize) -> *mut c_void {
1561 core::ptr::null_mut()
1562 }
1563 fn dealloc(_: *mut c_void) {}
1564 }
1565 impl PlatformSleep for TestPlatform {
1566 fn sleep_us(_: usize) {}
1567 fn sleep_ms(_: usize) {}
1568 fn sleep_s(_: usize) {}
1569 }
1570 impl PlatformYield for TestPlatform {
1571 fn yield_now() {}
1572 }
1573 impl PlatformRandom for TestPlatform {
1574 fn random_u8() -> u8 {
1575 0
1576 }
1577 fn random_u16() -> u16 {
1578 0
1579 }
1580 fn random_u32() -> u32 {
1581 0
1582 }
1583 fn random_u64() -> u64 {
1584 0
1585 }
1586 fn random_fill(_: *mut c_void, _: usize) {}
1587 }
1588 impl PlatformTime for TestPlatform {
1589 fn time_now_ms() -> u64 {
1590 0
1591 }
1592 fn time_since_epoch_secs() -> u32 {
1593 0
1594 }
1595 fn time_since_epoch_nanos() -> u32 {
1596 0
1597 }
1598 }
1599 impl PlatformThreading for TestPlatform {
1600 fn task_init(
1601 _: *mut c_void,
1602 _: *mut c_void,
1603 _: Option<unsafe extern "C" fn(*mut c_void) -> *mut c_void>,
1604 _: *mut c_void,
1605 ) -> i8 {
1606 -1
1607 }
1608 fn task_join(_: *mut c_void) -> i8 {
1609 -1
1610 }
1611 fn task_detach(_: *mut c_void) -> i8 {
1612 -1
1613 }
1614 fn task_cancel(_: *mut c_void) -> i8 {
1615 -1
1616 }
1617 fn task_exit() {}
1618 fn task_free(_: *mut *mut c_void) {}
1619 fn mutex_init(_: *mut c_void) -> i8 {
1620 0
1621 }
1622 fn mutex_drop(_: *mut c_void) -> i8 {
1623 0
1624 }
1625 fn mutex_lock(_: *mut c_void) -> i8 {
1626 0
1627 }
1628 fn mutex_try_lock(_: *mut c_void) -> i8 {
1629 0
1630 }
1631 fn mutex_unlock(_: *mut c_void) -> i8 {
1632 0
1633 }
1634 fn mutex_rec_init(_: *mut c_void) -> i8 {
1635 0
1636 }
1637 fn mutex_rec_drop(_: *mut c_void) -> i8 {
1638 0
1639 }
1640 fn mutex_rec_lock(_: *mut c_void) -> i8 {
1641 0
1642 }
1643 fn mutex_rec_try_lock(_: *mut c_void) -> i8 {
1644 0
1645 }
1646 fn mutex_rec_unlock(_: *mut c_void) -> i8 {
1647 0
1648 }
1649 fn condvar_init(_: *mut c_void) -> i8 {
1650 0
1651 }
1652 fn condvar_drop(_: *mut c_void) -> i8 {
1653 0
1654 }
1655 fn condvar_signal(_: *mut c_void) -> i8 {
1656 0
1657 }
1658 fn condvar_signal_all(_: *mut c_void) -> i8 {
1659 0
1660 }
1661 fn condvar_wait(_: *mut c_void, _: *mut c_void) -> i8 {
1662 0
1663 }
1664 fn condvar_wait_until(_: *mut c_void, _: *mut c_void, _: u64) -> i8 {
1665 0
1666 }
1667 }
1668 impl ::nros_platform_api::PlatformCriticalSection for TestPlatform {
1669 fn acquire() -> u32 {
1670 0
1671 }
1672 fn release(_: u32) {}
1673 }
1674
1675 #[repr(transparent)]
1680 #[derive(Clone, Copy)]
1681 pub struct TestTimerHandle(pub *mut c_void);
1682 unsafe impl Send for TestTimerHandle {}
1683 unsafe impl Sync for TestTimerHandle {}
1684
1685 impl ::nros_platform_api::PlatformTimer for TestPlatform {
1686 type TimerHandle = TestTimerHandle;
1687 }
1692
1693 crate::nros_platform_export!(TestPlatform);
1694 crate::nros_platform_export_timer!(TestPlatform);
1695
1696 #[test]
1697 fn macro_expansion_dispatches() {
1698 assert_eq!(super::CffiPlatform::clock_ms(), 0);
1701 assert_eq!(
1702 <super::CffiPlatform as ::nros_platform_api::PlatformAlloc>::alloc(0),
1703 core::ptr::null_mut(),
1704 );
1705 <super::CffiPlatform as ::nros_platform_api::PlatformYield>::yield_now();
1706 }
1707
1708 #[test]
1709 fn timer_macro_emits() {
1710 let h = unsafe {
1712 super::nros_platform_timer_create_periodic(1000, noop_callback, core::ptr::null_mut())
1713 };
1714 assert!(h.is_null(), "default Unsupported impl must surface as NULL");
1715 }
1716
1717 extern "C" fn noop_callback(_: *mut c_void) {}
1718}