1#![allow(missing_docs)]
8
9use crate::ot::DnsTxtEntryIterator;
10use crate::prelude_internal::*;
11
12#[derive(Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, num_derive::FromPrimitive)]
16#[allow(missing_docs)]
17pub enum SrpServerState {
18 Disabled = OT_SRP_SERVER_STATE_DISABLED as isize,
21
22 Running = OT_SRP_SERVER_STATE_RUNNING as isize,
25
26 Stopped = OT_SRP_SERVER_STATE_STOPPED as isize,
29}
30
31#[derive(Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, num_derive::FromPrimitive)]
36#[allow(missing_docs)]
37pub enum SrpServerAddressMode {
38 Unicast = OT_SRP_SERVER_ADDRESS_MODE_UNICAST as isize,
41
42 Anycast = OT_SRP_SERVER_ADDRESS_MODE_ANYCAST as isize,
45}
46
47pub struct SrpServerHostIterator<'a, T: SrpServer> {
49 prev: Option<&'a SrpServerHost>,
50 ot_instance: &'a T,
51}
52
53impl<T: SrpServer> Clone for SrpServerHostIterator<'_, T> {
56 fn clone(&self) -> Self {
57 SrpServerHostIterator { prev: self.prev, ot_instance: self.ot_instance }
58 }
59}
60
61impl<T: SrpServer> std::fmt::Debug for SrpServerHostIterator<'_, T> {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 write!(f, "[")?;
64 for item in self.clone() {
65 item.fmt(f)?;
66 write!(f, ",")?;
67 }
68 write!(f, "]")
69 }
70}
71
72impl<'a, T: SrpServer> Iterator for SrpServerHostIterator<'a, T> {
73 type Item = &'a SrpServerHost;
74
75 fn next(&mut self) -> Option<Self::Item> {
76 self.prev = self.ot_instance.srp_server_next_host(self.prev);
77 self.prev
78 }
79}
80
81#[derive(Clone)]
83pub struct SrpServerServiceIterator<'a> {
84 prev: Option<&'a SrpServerService>,
85 host: &'a SrpServerHost,
86}
87
88impl std::fmt::Debug for SrpServerServiceIterator<'_> {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 write!(f, "[")?;
91 for item in self.clone() {
92 item.fmt(f)?;
93 write!(f, ",")?;
94 }
95 write!(f, "]")
96 }
97}
98
99impl<'a> Iterator for SrpServerServiceIterator<'a> {
100 type Item = &'a SrpServerService;
101
102 fn next(&mut self) -> Option<Self::Item> {
103 self.prev = self.host.next_service(self.prev);
104 self.prev
105 }
106}
107
108#[repr(transparent)]
112pub struct SrpServerHost(otSrpServerHost);
113impl_ot_castable!(opaque SrpServerHost, otSrpServerHost);
114
115impl std::fmt::Debug for SrpServerHost {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 f.debug_struct("otSrpServerHost")
118 .field("full_name", &self.full_name_cstr())
119 .field("addresses", &self.addresses())
120 .field("is_deleted", &self.is_deleted())
121 .field("services", &self.services())
122 .finish()
123 }
124}
125
126impl SrpServerHost {
127 pub fn addresses(&self) -> &[Ip6Address] {
130 let mut addresses_len = 0u8;
131 unsafe {
132 let addresses_ptr =
133 otSrpServerHostGetAddresses(self.as_ot_ptr(), &mut addresses_len as *mut u8);
134
135 if addresses_ptr.is_null() || addresses_len == 0 {
136 return &[];
137 }
138
139 std::slice::from_raw_parts(addresses_ptr as *const Ip6Address, addresses_len as usize)
140 }
141 }
142
143 pub fn matches_full_name_cstr(&self, full_name: &CStr) -> bool {
146 unsafe { otSrpServerHostMatchesFullName(self.as_ot_ptr(), full_name.as_ptr()) }
147 }
148
149 pub fn full_name_cstr(&self) -> &CStr {
152 unsafe { CStr::from_ptr(otSrpServerHostGetFullName(self.as_ot_ptr())) }
153 }
154
155 pub fn is_deleted(&self) -> bool {
158 unsafe { otSrpServerHostIsDeleted(self.as_ot_ptr()) }
159 }
160
161 pub fn get_lease_info(&self, lease_info: &mut SrpServerLeaseInfo) {
164 unsafe { otSrpServerHostGetLeaseInfo(self.as_ot_ptr(), lease_info.as_ot_mut_ptr()) }
165 }
166
167 pub fn next_service<'a>(
170 &'a self,
171 prev: Option<&'a SrpServerService>,
172 ) -> Option<&'a SrpServerService> {
173 let prev = prev.map(|x| x.as_ot_ptr()).unwrap_or(null());
174 unsafe {
175 SrpServerService::ref_from_ot_ptr(otSrpServerHostGetNextService(self.as_ot_ptr(), prev))
176 }
177 }
178
179 pub fn services(&self) -> SrpServerServiceIterator<'_> {
181 SrpServerServiceIterator { prev: None, host: self }
182 }
183}
184
185#[derive(Clone)]
187pub struct SrpServerServiceSubtypeIterator<'a> {
188 service: &'a SrpServerService,
189 next_i: u16,
190}
191
192impl std::fmt::Debug for SrpServerServiceSubtypeIterator<'_> {
193 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194 write!(f, "[")?;
195 for item in self.clone() {
196 item.fmt(f)?;
197 write!(f, ",")?;
198 }
199 write!(f, "]")
200 }
201}
202
203impl<'a> Iterator for SrpServerServiceSubtypeIterator<'a> {
204 type Item = &'a CStr;
205
206 fn next(&mut self) -> Option<Self::Item> {
207 let ret = self.service.subtype_service_name_at(self.next_i);
208 if ret.is_some() {
209 self.next_i += 1;
210 }
211 ret
212 }
213}
214
215#[repr(transparent)]
219pub struct SrpServerService(otSrpServerService);
220impl_ot_castable!(opaque SrpServerService, otSrpServerService);
221
222impl std::fmt::Debug for SrpServerService {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 if self.is_deleted() {
225 f.debug_struct("otSrpServerService")
226 .field("service_name", &self.service_name_cstr())
227 .field("instance_name", &self.instance_name_cstr())
228 .field("is_deleted", &self.is_deleted())
229 .finish()
230 } else {
231 f.debug_struct("otSrpServerService")
232 .field("service_name", &self.service_name_cstr())
233 .field("instance_name", &self.instance_name_cstr())
234 .field("is_deleted", &self.is_deleted())
235 .field("txt_data", &ascii_dump(self.txt_data()))
236 .field("txt_entries", &self.txt_entries().collect::<Vec<_>>())
237 .field("port", &self.port())
238 .field("priority", &self.priority())
239 .field("weight", &self.weight())
240 .field("subtypes", &self.subtypes())
241 .field("ttl", &self.ttl())
242 .finish()
243 }
244 }
245}
246
247impl SrpServerService {
248 pub fn port(&self) -> u16 {
251 unsafe { otSrpServerServiceGetPort(self.as_ot_ptr()) }
252 }
253
254 pub fn priority(&self) -> u16 {
257 unsafe { otSrpServerServiceGetPriority(self.as_ot_ptr()) }
258 }
259
260 pub fn is_deleted(&self) -> bool {
263 unsafe { otSrpServerServiceIsDeleted(self.as_ot_ptr()) }
264 }
265
266 pub fn get_lease_info(&self, lease_info: &mut SrpServerLeaseInfo) {
269 unsafe { otSrpServerServiceGetLeaseInfo(self.as_ot_ptr(), lease_info.as_ot_mut_ptr()) }
270 }
271
272 pub fn subtypes(&self) -> SrpServerServiceSubtypeIterator<'_> {
274 SrpServerServiceSubtypeIterator { service: self, next_i: 0 }
275 }
276
277 pub fn number_of_subtypes(&self) -> u16 {
280 unsafe { otSrpServerServiceGetNumberOfSubTypes(self.as_ot_ptr()) }
281 }
282
283 pub fn subtype_service_name_at(&self, i: u16) -> Option<&CStr> {
286 unsafe {
287 let ptr = otSrpServerServiceGetSubTypeServiceNameAt(self.as_ot_ptr(), i);
288 if ptr.is_null() { None } else { Some(CStr::from_ptr(ptr)) }
289 }
290 }
291
292 pub fn txt_data(&self) -> &[u8] {
295 let mut txt_data_len = 0u16;
296 unsafe {
297 let txt_data_ptr =
298 otSrpServerServiceGetTxtData(self.as_ot_ptr(), &mut txt_data_len as *mut u16);
299
300 if txt_data_ptr.is_null() || txt_data_len == 0 {
301 return &[];
302 }
303
304 std::slice::from_raw_parts(txt_data_ptr, txt_data_len as usize)
305 }
306 }
307
308 pub fn txt_entries(&self) -> DnsTxtEntryIterator<'_> {
310 DnsTxtEntryIterator::try_new(self.txt_data()).unwrap()
311 }
312
313 pub fn weight(&self) -> u16 {
316 unsafe { otSrpServerServiceGetWeight(self.as_ot_ptr()) }
317 }
318
319 pub fn service_name_cstr(&self) -> &CStr {
322 unsafe { CStr::from_ptr(otSrpServerServiceGetServiceName(self.as_ot_ptr())) }
323 }
324
325 pub fn instance_name_cstr(&self) -> &CStr {
328 unsafe { CStr::from_ptr(otSrpServerServiceGetInstanceName(self.as_ot_ptr())) }
329 }
330
331 pub fn instance_label_cstr(&self) -> &CStr {
334 unsafe { CStr::from_ptr(otSrpServerServiceGetInstanceLabel(self.as_ot_ptr())) }
335 }
336
337 pub fn ttl(&self) -> zx::MonotonicDuration {
340 unsafe {
341 zx::MonotonicDuration::from_seconds(otSrpServerServiceGetTtl(self.as_ot_ptr()).into())
342 }
343 }
344}
345
346#[derive(Debug, Hash, PartialEq, Eq, Clone)]
351pub struct SrpServerServiceUpdateId(otSrpServerServiceUpdateId);
352
353impl SrpServerServiceUpdateId {
354 fn new(x: otSrpServerServiceUpdateId) -> Self {
355 Self(x)
356 }
357
358 fn take(self) -> otSrpServerServiceUpdateId {
359 self.0
360 }
361}
362
363pub trait SrpServer {
367 fn srp_server_get_address_mode(&self) -> SrpServerAddressMode;
370
371 fn srp_server_get_state(&self) -> SrpServerState;
374
375 fn srp_server_get_port(&self) -> u16;
378
379 fn srp_server_set_enabled(&self, enabled: bool);
382
383 fn srp_server_set_auto_enable_mode(&self, enabled: bool);
386
387 fn srp_server_is_enabled(&self) -> bool;
389
390 fn srp_server_is_auto_enable_mode(&self) -> bool;
392
393 fn srp_server_is_running(&self) -> bool;
395
396 fn srp_server_set_domain(&self, domain: &CStr) -> Result;
399
400 fn srp_server_get_domain(&self) -> &CStr;
403
404 fn srp_server_get_response_counters(&self) -> &SrpServerResponseCounters;
407
408 fn srp_server_next_host<'a>(
411 &'a self,
412 prev: Option<&'a SrpServerHost>,
413 ) -> Option<&'a SrpServerHost>;
414
415 fn srp_server_hosts(&self) -> SrpServerHostIterator<'_, Self>
417 where
418 Self: Sized,
419 {
420 SrpServerHostIterator { prev: None, ot_instance: self }
421 }
422
423 fn srp_server_handle_service_update_result(&self, id: SrpServerServiceUpdateId, result: Result);
426
427 fn srp_server_set_service_update_fn<'a, F>(&'a self, f: Option<F>)
430 where
431 F: FnMut(&'a ot::Instance, SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a;
432
433 fn parse_label_from_subtype_service_name(
436 &self,
437 subtype_service_name: &CStr,
438 ) -> Result<CString, Error>;
439}
440
441impl<T: SrpServer + Boxable> SrpServer for ot::Box<T> {
442 fn srp_server_get_address_mode(&self) -> SrpServerAddressMode {
443 self.as_ref().srp_server_get_address_mode()
444 }
445
446 fn srp_server_get_state(&self) -> SrpServerState {
447 self.as_ref().srp_server_get_state()
448 }
449
450 fn srp_server_get_port(&self) -> u16 {
451 self.as_ref().srp_server_get_port()
452 }
453
454 fn srp_server_set_auto_enable_mode(&self, enabled: bool) {
455 self.as_ref().srp_server_set_auto_enable_mode(enabled)
456 }
457
458 fn srp_server_set_enabled(&self, enabled: bool) {
459 self.as_ref().srp_server_set_enabled(enabled)
460 }
461
462 fn srp_server_is_enabled(&self) -> bool {
463 self.as_ref().srp_server_is_enabled()
464 }
465
466 fn srp_server_is_auto_enable_mode(&self) -> bool {
467 self.as_ref().srp_server_is_auto_enable_mode()
468 }
469
470 fn srp_server_is_running(&self) -> bool {
471 self.as_ref().srp_server_is_running()
472 }
473
474 fn srp_server_set_domain(&self, domain: &CStr) -> Result {
475 self.as_ref().srp_server_set_domain(domain)
476 }
477
478 fn srp_server_get_domain(&self) -> &CStr {
479 self.as_ref().srp_server_get_domain()
480 }
481
482 fn srp_server_get_response_counters(&self) -> &SrpServerResponseCounters {
483 self.as_ref().srp_server_get_response_counters()
484 }
485
486 fn srp_server_next_host<'a>(
487 &'a self,
488 prev: Option<&'a SrpServerHost>,
489 ) -> Option<&'a SrpServerHost> {
490 self.as_ref().srp_server_next_host(prev)
491 }
492
493 fn srp_server_handle_service_update_result(
494 &self,
495 id: SrpServerServiceUpdateId,
496 result: Result,
497 ) {
498 self.as_ref().srp_server_handle_service_update_result(id, result)
499 }
500
501 fn srp_server_set_service_update_fn<'a, F>(&'a self, f: Option<F>)
502 where
503 F: FnMut(&'a ot::Instance, SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
504 {
505 self.as_ref().srp_server_set_service_update_fn(f)
506 }
507
508 fn parse_label_from_subtype_service_name(
509 &self,
510 subtype_service_name: &CStr,
511 ) -> Result<CString, Error> {
512 self.as_ref().parse_label_from_subtype_service_name(subtype_service_name)
513 }
514}
515
516impl SrpServer for Instance {
517 fn srp_server_get_address_mode(&self) -> SrpServerAddressMode {
518 unsafe {
519 SrpServerAddressMode::from_u32(otSrpServerGetAddressMode(self.as_ot_ptr())).unwrap()
520 }
521 }
522
523 fn srp_server_get_state(&self) -> SrpServerState {
524 unsafe { SrpServerState::from_u32(otSrpServerGetState(self.as_ot_ptr())).unwrap() }
525 }
526
527 fn srp_server_get_port(&self) -> u16 {
528 unsafe { otSrpServerGetPort(self.as_ot_ptr()) }
529 }
530
531 fn srp_server_set_auto_enable_mode(&self, enabled: bool) {
532 unsafe { otSrpServerSetAutoEnableMode(self.as_ot_ptr(), enabled) }
533 }
534
535 fn srp_server_set_enabled(&self, enabled: bool) {
536 unsafe { otSrpServerSetEnabled(self.as_ot_ptr(), enabled) }
537 }
538
539 fn srp_server_is_enabled(&self) -> bool {
540 #[allow(non_upper_case_globals)]
541 match unsafe { otSrpServerGetState(self.as_ot_ptr()) } {
542 OT_SRP_SERVER_STATE_DISABLED => false,
543 OT_SRP_SERVER_STATE_RUNNING => true,
544 OT_SRP_SERVER_STATE_STOPPED => true,
545 _ => panic!("Unexpected value from otSrpServerGetState"),
546 }
547 }
548
549 fn srp_server_is_auto_enable_mode(&self) -> bool {
550 unsafe { otSrpServerIsAutoEnableMode(self.as_ot_ptr()) }
551 }
552
553 fn srp_server_is_running(&self) -> bool {
554 #[allow(non_upper_case_globals)]
555 match unsafe { otSrpServerGetState(self.as_ot_ptr()) } {
556 OT_SRP_SERVER_STATE_DISABLED => false,
557 OT_SRP_SERVER_STATE_RUNNING => true,
558 OT_SRP_SERVER_STATE_STOPPED => false,
559 _ => panic!("Unexpected value from otSrpServerGetState"),
560 }
561 }
562
563 fn srp_server_set_domain(&self, domain: &CStr) -> Result {
564 Error::from(unsafe { otSrpServerSetDomain(self.as_ot_ptr(), domain.as_ptr()) }).into()
565 }
566
567 fn srp_server_get_domain(&self) -> &CStr {
568 unsafe { CStr::from_ptr(otSrpServerGetDomain(self.as_ot_ptr())) }
569 }
570
571 fn srp_server_get_response_counters(&self) -> &SrpServerResponseCounters {
572 unsafe {
573 SrpServerResponseCounters::ref_from_ot_ptr(otSrpServerGetResponseCounters(
574 self.as_ot_ptr(),
575 ))
576 .unwrap()
577 }
578 }
579
580 fn srp_server_next_host<'a>(
581 &'a self,
582 prev: Option<&'a SrpServerHost>,
583 ) -> Option<&'a SrpServerHost> {
584 let prev = prev.map(|x| x.as_ot_ptr()).unwrap_or(null());
585 unsafe { SrpServerHost::ref_from_ot_ptr(otSrpServerGetNextHost(self.as_ot_ptr(), prev)) }
586 }
587
588 fn srp_server_handle_service_update_result(
589 &self,
590 id: SrpServerServiceUpdateId,
591 result: Result,
592 ) {
593 unsafe {
594 otSrpServerHandleServiceUpdateResult(
595 self.as_ot_ptr(),
596 id.take(),
597 Error::from(result).into(),
598 )
599 }
600 }
601
602 fn srp_server_set_service_update_fn<'a, F>(&'a self, f: Option<F>)
603 where
604 F: FnMut(&'a ot::Instance, SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
605 {
606 unsafe extern "C" fn _ot_srp_server_service_update_handler<'a, F>(
607 id: otSrpServerServiceUpdateId,
608 host: *const otSrpServerHost,
609 timeout: u32,
610 context: *mut ::std::os::raw::c_void,
611 ) where
612 F: FnMut(SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
613 {
614 let sender = unsafe { &mut *(context as *mut F) };
616
617 sender(
618 SrpServerServiceUpdateId::new(id),
619 unsafe { SrpServerHost::ref_from_ot_ptr(host) }.unwrap(),
620 timeout,
621 )
622 }
623
624 fn get_service_update_handler<'a, X>(_: &X) -> otSrpServerServiceUpdateHandler
628 where
629 X: FnMut(SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
630 {
631 Some(_ot_srp_server_service_update_handler::<X>)
632 }
633
634 let (fn_ptr, fn_box, cb): (_, _, otSrpServerServiceUpdateHandler) = if let Some(mut f) = f {
635 let ot_instance_ptr = self.as_ot_ptr();
637
638 let f_wrapped =
641 move |id: SrpServerServiceUpdateId, host: &'a SrpServerHost, timeout: u32| {
642 let ot_instance =
648 unsafe { ot::Instance::ref_from_ot_ptr(ot_instance_ptr) }.unwrap();
649 f(ot_instance, id, host, timeout)
650 };
651
652 let service_update_handler = get_service_update_handler(&f_wrapped);
656
657 let mut x = Box::new(f_wrapped);
658
659 (
660 x.as_mut() as *mut _ as *mut ::std::os::raw::c_void,
661 Some(
662 x as Box<
663 dyn FnMut(ot::SrpServerServiceUpdateId, &'a ot::SrpServerHost, u32) + 'a,
664 >,
665 ),
666 service_update_handler,
667 )
668 } else {
669 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
670 };
671
672 unsafe {
673 otSrpServerSetServiceUpdateHandler(self.as_ot_ptr(), cb, fn_ptr);
674
675 self.borrow_backing().srp_server_service_update_fn.set(std::mem::transmute::<
681 Option<Box<dyn FnMut(SrpServerServiceUpdateId, &'a ot::SrpServerHost, u32) + 'a>>,
682 Option<Box<dyn FnMut(SrpServerServiceUpdateId, &ot::SrpServerHost, u32) + 'static>>,
683 >(fn_box));
684 }
685 }
686
687 fn parse_label_from_subtype_service_name(
688 &self,
689 subtype_service_name: &CStr,
690 ) -> Result<CString, Error> {
691 let mut bytes = [0 as c_char; 256];
692
693 Error::from(unsafe {
695 otSrpServerParseSubTypeServiceName(
696 subtype_service_name.as_ptr(),
697 (&mut bytes) as *mut c_char,
698 255,
699 )
700 })
701 .into_result()?;
702
703 Ok(unsafe { CStr::from_ptr(&bytes as *const c_char) }.to_owned())
705 }
706}