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 std::slice::from_raw_parts(addresses_ptr as *const Ip6Address, addresses_len as usize)
136 }
137 }
138
139 pub fn matches_full_name_cstr(&self, full_name: &CStr) -> bool {
142 unsafe { otSrpServerHostMatchesFullName(self.as_ot_ptr(), full_name.as_ptr()) }
143 }
144
145 pub fn full_name_cstr(&self) -> &CStr {
148 unsafe { CStr::from_ptr(otSrpServerHostGetFullName(self.as_ot_ptr())) }
149 }
150
151 pub fn is_deleted(&self) -> bool {
154 unsafe { otSrpServerHostIsDeleted(self.as_ot_ptr()) }
155 }
156
157 pub fn get_lease_info(&self, lease_info: &mut SrpServerLeaseInfo) {
160 unsafe { otSrpServerHostGetLeaseInfo(self.as_ot_ptr(), lease_info.as_ot_mut_ptr()) }
161 }
162
163 pub fn next_service<'a>(
166 &'a self,
167 prev: Option<&'a SrpServerService>,
168 ) -> Option<&'a SrpServerService> {
169 let prev = prev.map(|x| x.as_ot_ptr()).unwrap_or(null());
170 unsafe {
171 SrpServerService::ref_from_ot_ptr(otSrpServerHostGetNextService(self.as_ot_ptr(), prev))
172 }
173 }
174
175 pub fn services(&self) -> SrpServerServiceIterator<'_> {
177 SrpServerServiceIterator { prev: None, host: self }
178 }
179}
180
181#[derive(Clone)]
183pub struct SrpServerServiceSubtypeIterator<'a> {
184 service: &'a SrpServerService,
185 next_i: u16,
186}
187
188impl std::fmt::Debug for SrpServerServiceSubtypeIterator<'_> {
189 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
190 write!(f, "[")?;
191 for item in self.clone() {
192 item.fmt(f)?;
193 write!(f, ",")?;
194 }
195 write!(f, "]")
196 }
197}
198
199impl<'a> Iterator for SrpServerServiceSubtypeIterator<'a> {
200 type Item = &'a CStr;
201
202 fn next(&mut self) -> Option<Self::Item> {
203 let ret = self.service.subtype_service_name_at(self.next_i);
204 if ret.is_some() {
205 self.next_i += 1;
206 }
207 ret
208 }
209}
210
211#[repr(transparent)]
215pub struct SrpServerService(otSrpServerService);
216impl_ot_castable!(opaque SrpServerService, otSrpServerService);
217
218impl std::fmt::Debug for SrpServerService {
219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220 if self.is_deleted() {
221 f.debug_struct("otSrpServerService")
222 .field("service_name", &self.service_name_cstr())
223 .field("instance_name", &self.instance_name_cstr())
224 .field("is_deleted", &self.is_deleted())
225 .finish()
226 } else {
227 f.debug_struct("otSrpServerService")
228 .field("service_name", &self.service_name_cstr())
229 .field("instance_name", &self.instance_name_cstr())
230 .field("is_deleted", &self.is_deleted())
231 .field("txt_data", &ascii_dump(self.txt_data()))
232 .field("txt_entries", &self.txt_entries().collect::<Vec<_>>())
233 .field("port", &self.port())
234 .field("priority", &self.priority())
235 .field("weight", &self.weight())
236 .field("subtypes", &self.subtypes())
237 .finish()
238 }
239 }
240}
241
242impl SrpServerService {
243 pub fn port(&self) -> u16 {
246 unsafe { otSrpServerServiceGetPort(self.as_ot_ptr()) }
247 }
248
249 pub fn priority(&self) -> u16 {
252 unsafe { otSrpServerServiceGetPriority(self.as_ot_ptr()) }
253 }
254
255 pub fn is_deleted(&self) -> bool {
258 unsafe { otSrpServerServiceIsDeleted(self.as_ot_ptr()) }
259 }
260
261 pub fn get_lease_info(&self, lease_info: &mut SrpServerLeaseInfo) {
264 unsafe { otSrpServerServiceGetLeaseInfo(self.as_ot_ptr(), lease_info.as_ot_mut_ptr()) }
265 }
266
267 pub fn subtypes(&self) -> SrpServerServiceSubtypeIterator<'_> {
269 SrpServerServiceSubtypeIterator { service: self, next_i: 0 }
270 }
271
272 pub fn number_of_subtypes(&self) -> u16 {
275 unsafe { otSrpServerServiceGetNumberOfSubTypes(self.as_ot_ptr()) }
276 }
277
278 pub fn subtype_service_name_at(&self, i: u16) -> Option<&CStr> {
281 unsafe {
282 let ptr = otSrpServerServiceGetSubTypeServiceNameAt(self.as_ot_ptr(), i);
283 if ptr.is_null() {
284 None
285 } else {
286 Some(CStr::from_ptr(ptr))
287 }
288 }
289 }
290
291 pub fn txt_data(&self) -> &[u8] {
294 let mut txt_data_len = 0u16;
295 unsafe {
296 let txt_data_ptr =
297 otSrpServerServiceGetTxtData(self.as_ot_ptr(), &mut txt_data_len as *mut u16);
298
299 std::slice::from_raw_parts(txt_data_ptr, txt_data_len as usize)
300 }
301 }
302
303 pub fn txt_entries(&self) -> DnsTxtEntryIterator<'_> {
305 DnsTxtEntryIterator::try_new(self.txt_data()).unwrap()
306 }
307
308 pub fn weight(&self) -> u16 {
311 unsafe { otSrpServerServiceGetWeight(self.as_ot_ptr()) }
312 }
313
314 pub fn service_name_cstr(&self) -> &CStr {
317 unsafe { CStr::from_ptr(otSrpServerServiceGetServiceName(self.as_ot_ptr())) }
318 }
319
320 pub fn instance_name_cstr(&self) -> &CStr {
323 unsafe { CStr::from_ptr(otSrpServerServiceGetInstanceName(self.as_ot_ptr())) }
324 }
325
326 pub fn instance_label_cstr(&self) -> &CStr {
329 unsafe { CStr::from_ptr(otSrpServerServiceGetInstanceLabel(self.as_ot_ptr())) }
330 }
331}
332
333pub fn parse_label_from_subtype_service_name(
336 subtype_service_name: &CStr,
337) -> Result<CString, Error> {
338 let mut bytes = [0 as c_char; 256];
339
340 Error::from(unsafe {
342 otSrpServerParseSubTypeServiceName(
343 subtype_service_name.as_ptr(),
344 (&mut bytes) as *mut c_char,
345 255,
346 )
347 })
348 .into_result()?;
349
350 Ok(unsafe { CStr::from_ptr(&bytes as *const c_char) }.to_owned())
352}
353
354#[derive(Debug)]
362pub struct SrpServerServiceUpdateId(otSrpServerServiceUpdateId);
363
364impl SrpServerServiceUpdateId {
365 fn new(x: otSrpServerServiceUpdateId) -> Self {
366 Self(x)
367 }
368
369 fn take(self) -> otSrpServerServiceUpdateId {
370 let ret = self.0;
371 core::mem::forget(self);
372 ret
373 }
374}
375
376impl Drop for SrpServerServiceUpdateId {
377 fn drop(&mut self) {
378 panic!("SrpServerServiceUpdateId dropped without being passed to SrpServer::srp_server_handle_service_update_result");
379 }
380}
381
382pub trait SrpServer {
386 fn srp_server_get_address_mode(&self) -> SrpServerAddressMode;
389
390 fn srp_server_get_state(&self) -> SrpServerState;
393
394 fn srp_server_get_port(&self) -> u16;
397
398 fn srp_server_set_enabled(&self, enabled: bool);
401
402 fn srp_server_set_auto_enable_mode(&self, enabled: bool);
405
406 fn srp_server_is_enabled(&self) -> bool;
408
409 fn srp_server_is_auto_enable_mode(&self) -> bool;
411
412 fn srp_server_is_running(&self) -> bool;
414
415 fn srp_server_set_domain(&self, domain: &CStr) -> Result;
418
419 fn srp_server_get_domain(&self) -> &CStr;
422
423 fn srp_server_get_response_counters(&self) -> &SrpServerResponseCounters;
426
427 fn srp_server_next_host<'a>(
430 &'a self,
431 prev: Option<&'a SrpServerHost>,
432 ) -> Option<&'a SrpServerHost>;
433
434 fn srp_server_hosts(&self) -> SrpServerHostIterator<'_, Self>
436 where
437 Self: Sized,
438 {
439 SrpServerHostIterator { prev: None, ot_instance: self }
440 }
441
442 fn srp_server_handle_service_update_result(&self, id: SrpServerServiceUpdateId, result: Result);
445
446 fn srp_server_set_service_update_fn<'a, F>(&'a self, f: Option<F>)
449 where
450 F: FnMut(&'a ot::Instance, SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a;
451}
452
453impl<T: SrpServer + Boxable> SrpServer for ot::Box<T> {
454 fn srp_server_get_address_mode(&self) -> SrpServerAddressMode {
455 self.as_ref().srp_server_get_address_mode()
456 }
457
458 fn srp_server_get_state(&self) -> SrpServerState {
459 self.as_ref().srp_server_get_state()
460 }
461
462 fn srp_server_get_port(&self) -> u16 {
463 self.as_ref().srp_server_get_port()
464 }
465
466 fn srp_server_set_auto_enable_mode(&self, enabled: bool) {
467 self.as_ref().srp_server_set_auto_enable_mode(enabled)
468 }
469
470 fn srp_server_set_enabled(&self, enabled: bool) {
471 self.as_ref().srp_server_set_enabled(enabled)
472 }
473
474 fn srp_server_is_enabled(&self) -> bool {
475 self.as_ref().srp_server_is_enabled()
476 }
477
478 fn srp_server_is_auto_enable_mode(&self) -> bool {
479 self.as_ref().srp_server_is_auto_enable_mode()
480 }
481
482 fn srp_server_is_running(&self) -> bool {
483 self.as_ref().srp_server_is_running()
484 }
485
486 fn srp_server_set_domain(&self, domain: &CStr) -> Result {
487 self.as_ref().srp_server_set_domain(domain)
488 }
489
490 fn srp_server_get_domain(&self) -> &CStr {
491 self.as_ref().srp_server_get_domain()
492 }
493
494 fn srp_server_get_response_counters(&self) -> &SrpServerResponseCounters {
495 self.as_ref().srp_server_get_response_counters()
496 }
497
498 fn srp_server_next_host<'a>(
499 &'a self,
500 prev: Option<&'a SrpServerHost>,
501 ) -> Option<&'a SrpServerHost> {
502 self.as_ref().srp_server_next_host(prev)
503 }
504
505 fn srp_server_handle_service_update_result(
506 &self,
507 id: SrpServerServiceUpdateId,
508 result: Result,
509 ) {
510 self.as_ref().srp_server_handle_service_update_result(id, result)
511 }
512
513 fn srp_server_set_service_update_fn<'a, F>(&'a self, f: Option<F>)
514 where
515 F: FnMut(&'a ot::Instance, SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
516 {
517 self.as_ref().srp_server_set_service_update_fn(f)
518 }
519}
520
521impl SrpServer for Instance {
522 fn srp_server_get_address_mode(&self) -> SrpServerAddressMode {
523 unsafe {
524 SrpServerAddressMode::from_u32(otSrpServerGetAddressMode(self.as_ot_ptr())).unwrap()
525 }
526 }
527
528 fn srp_server_get_state(&self) -> SrpServerState {
529 unsafe { SrpServerState::from_u32(otSrpServerGetState(self.as_ot_ptr())).unwrap() }
530 }
531
532 fn srp_server_get_port(&self) -> u16 {
533 unsafe { otSrpServerGetPort(self.as_ot_ptr()) }
534 }
535
536 fn srp_server_set_auto_enable_mode(&self, enabled: bool) {
537 unsafe { otSrpServerSetAutoEnableMode(self.as_ot_ptr(), enabled) }
538 }
539
540 fn srp_server_set_enabled(&self, enabled: bool) {
541 unsafe { otSrpServerSetEnabled(self.as_ot_ptr(), enabled) }
542 }
543
544 fn srp_server_is_enabled(&self) -> bool {
545 #[allow(non_upper_case_globals)]
546 match unsafe { otSrpServerGetState(self.as_ot_ptr()) } {
547 OT_SRP_SERVER_STATE_DISABLED => false,
548 OT_SRP_SERVER_STATE_RUNNING => true,
549 OT_SRP_SERVER_STATE_STOPPED => true,
550 _ => panic!("Unexpected value from otSrpServerGetState"),
551 }
552 }
553
554 fn srp_server_is_auto_enable_mode(&self) -> bool {
555 unsafe { otSrpServerIsAutoEnableMode(self.as_ot_ptr()) }
556 }
557
558 fn srp_server_is_running(&self) -> bool {
559 #[allow(non_upper_case_globals)]
560 match unsafe { otSrpServerGetState(self.as_ot_ptr()) } {
561 OT_SRP_SERVER_STATE_DISABLED => false,
562 OT_SRP_SERVER_STATE_RUNNING => true,
563 OT_SRP_SERVER_STATE_STOPPED => false,
564 _ => panic!("Unexpected value from otSrpServerGetState"),
565 }
566 }
567
568 fn srp_server_set_domain(&self, domain: &CStr) -> Result {
569 Error::from(unsafe { otSrpServerSetDomain(self.as_ot_ptr(), domain.as_ptr()) }).into()
570 }
571
572 fn srp_server_get_domain(&self) -> &CStr {
573 unsafe { CStr::from_ptr(otSrpServerGetDomain(self.as_ot_ptr())) }
574 }
575
576 fn srp_server_get_response_counters(&self) -> &SrpServerResponseCounters {
577 unsafe {
578 SrpServerResponseCounters::ref_from_ot_ptr(otSrpServerGetResponseCounters(
579 self.as_ot_ptr(),
580 ))
581 .unwrap()
582 }
583 }
584
585 fn srp_server_next_host<'a>(
586 &'a self,
587 prev: Option<&'a SrpServerHost>,
588 ) -> Option<&'a SrpServerHost> {
589 let prev = prev.map(|x| x.as_ot_ptr()).unwrap_or(null());
590 unsafe { SrpServerHost::ref_from_ot_ptr(otSrpServerGetNextHost(self.as_ot_ptr(), prev)) }
591 }
592
593 fn srp_server_handle_service_update_result(
594 &self,
595 id: SrpServerServiceUpdateId,
596 result: Result,
597 ) {
598 unsafe {
599 otSrpServerHandleServiceUpdateResult(
600 self.as_ot_ptr(),
601 id.take(),
602 Error::from(result).into(),
603 )
604 }
605 }
606
607 fn srp_server_set_service_update_fn<'a, F>(&'a self, f: Option<F>)
608 where
609 F: FnMut(&'a ot::Instance, SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
610 {
611 unsafe extern "C" fn _ot_srp_server_service_update_handler<'a, F>(
612 id: otSrpServerServiceUpdateId,
613 host: *const otSrpServerHost,
614 timeout: u32,
615 context: *mut ::std::os::raw::c_void,
616 ) where
617 F: FnMut(SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
618 {
619 let sender = &mut *(context as *mut F);
621
622 sender(
623 SrpServerServiceUpdateId::new(id),
624 SrpServerHost::ref_from_ot_ptr(host).unwrap(),
625 timeout,
626 )
627 }
628
629 fn get_service_update_handler<'a, X>(_: &X) -> otSrpServerServiceUpdateHandler
633 where
634 X: FnMut(SrpServerServiceUpdateId, &'a SrpServerHost, u32) + 'a,
635 {
636 Some(_ot_srp_server_service_update_handler::<X>)
637 }
638
639 let (fn_ptr, fn_box, cb): (_, _, otSrpServerServiceUpdateHandler) = if let Some(mut f) = f {
640 let ot_instance_ptr = self.as_ot_ptr();
642
643 let f_wrapped =
646 move |id: SrpServerServiceUpdateId, host: &'a SrpServerHost, timeout: u32| {
647 let ot_instance =
653 unsafe { ot::Instance::ref_from_ot_ptr(ot_instance_ptr) }.unwrap();
654 f(ot_instance, id, host, timeout)
655 };
656
657 let service_update_handler = get_service_update_handler(&f_wrapped);
661
662 let mut x = Box::new(f_wrapped);
663
664 (
665 x.as_mut() as *mut _ as *mut ::std::os::raw::c_void,
666 Some(
667 x as Box<
668 dyn FnMut(ot::SrpServerServiceUpdateId, &'a ot::SrpServerHost, u32) + 'a,
669 >,
670 ),
671 service_update_handler,
672 )
673 } else {
674 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
675 };
676
677 unsafe {
678 otSrpServerSetServiceUpdateHandler(self.as_ot_ptr(), cb, fn_ptr);
679
680 self.borrow_backing().srp_server_service_update_fn.set(std::mem::transmute::<
686 Option<Box<dyn FnMut(SrpServerServiceUpdateId, &'a ot::SrpServerHost, u32) + 'a>>,
687 Option<Box<dyn FnMut(SrpServerServiceUpdateId, &ot::SrpServerHost, u32) + 'static>>,
688 >(fn_box));
689 }
690 }
691}