Skip to main content

openthread/ot/
srp.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// for now, we allow this for this module because we can't apply it
6// specifically to the type `ChangedFlags`, due to a bug in `bitflags!`.
7#![allow(missing_docs)]
8
9use crate::ot::DnsTxtEntryIterator;
10use crate::prelude_internal::*;
11
12/// Represents the SRP server state.
13///
14/// Functional equivalent of [`otsys::otSrpServerState`](crate::otsys::otSrpServerState).
15#[derive(Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, num_derive::FromPrimitive)]
16#[allow(missing_docs)]
17pub enum SrpServerState {
18    /// Functional equivalent of
19    /// [`otsys::otSrpServerState_OT_SRP_SERVER_STATE_DISABLED`](crate::otsys::otSrpServerState_OT_SRP_SERVER_STATE_DISABLED).
20    Disabled = OT_SRP_SERVER_STATE_DISABLED as isize,
21
22    /// Functional equivalent of
23    /// [`otsys::otSrpServerState_OT_SRP_SERVER_STATE_RUNNING`](crate::otsys::otSrpServerState_OT_SRP_SERVER_STATE_RUNNING).
24    Running = OT_SRP_SERVER_STATE_RUNNING as isize,
25
26    /// Functional equivalent of
27    /// [`otsys::otSrpServerState_OT_SRP_SERVER_STATE_STOPPED`](crate::otsys::otSrpServerState_OT_SRP_SERVER_STATE_STOPPED).
28    Stopped = OT_SRP_SERVER_STATE_STOPPED as isize,
29}
30
31/// Represents the SRP server address mode.
32///
33/// Functional equivalent of
34/// [`otsys::otSrpServerAddressMode`](crate::otsys::otSrpServerAddressMode).
35#[derive(Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, num_derive::FromPrimitive)]
36#[allow(missing_docs)]
37pub enum SrpServerAddressMode {
38    /// Functional equivalent of
39    /// [`otsys::otSrpServerAddressMode_OT_SRP_SERVER_ADDRESS_MODE_UNICAST`](crate::otsys::otSrpServerAddressMode_OT_SRP_SERVER_ADDRESS_MODE_UNICAST).
40    Unicast = OT_SRP_SERVER_ADDRESS_MODE_UNICAST as isize,
41
42    /// Functional equivalent of
43    /// [`otsys::otSrpServerAddressMode_OT_SRP_SERVER_ADDRESS_MODE_ANYCAST`](crate::otsys::otSrpServerAddressMode_OT_SRP_SERVER_ADDRESS_MODE_ANYCAST).
44    Anycast = OT_SRP_SERVER_ADDRESS_MODE_ANYCAST as isize,
45}
46
47/// Iterates over the available SRP server hosts. See [`SrpServer::srp_server_get_hosts`].
48pub struct SrpServerHostIterator<'a, T: SrpServer> {
49    prev: Option<&'a SrpServerHost>,
50    ot_instance: &'a T,
51}
52
53// This cannot be easily derived because T doesn't implement `Clone`,
54// so we must implement it manually.
55impl<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/// Iterates over all the available SRP services.
82#[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/// This opaque type (only used by reference) represents a SRP host.
109///
110/// Functional equivalent of [`otsys::otSrpServerHost`](crate::otsys::otSrpServerHost).
111#[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    /// Functional equivalent of
128    /// [`otsys::otSrpServerHostGetAddresses`](crate::otsys::otSrpServerHostGetAddresses).
129    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    /// Functional equivalent of
144    /// [`otsys::otSrpServerHostMatchesFullName`](crate::otsys::otSrpServerHostMatchesFullName).
145    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    /// Functional equivalent of
150    /// [`otsys::otSrpServerHostGetFullName`](crate::otsys::otSrpServerHostGetFullName).
151    pub fn full_name_cstr(&self) -> &CStr {
152        unsafe { CStr::from_ptr(otSrpServerHostGetFullName(self.as_ot_ptr())) }
153    }
154
155    /// Functional equivalent of
156    /// [`otsys::otSrpServerHostIsDeleted`](crate::otsys::otSrpServerHostIsDeleted).
157    pub fn is_deleted(&self) -> bool {
158        unsafe { otSrpServerHostIsDeleted(self.as_ot_ptr()) }
159    }
160
161    /// Functional equivalent of
162    /// [`otsys::otSrpServerHostGetLeaseInfo`](crate::otsys::otSrpServerHostGetLeaseInfo).
163    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    /// Functional equivalent of
168    /// [`otsys::otSrpServerHostGetNextService`](crate::otsys::otSrpServerHostGetNextService).
169    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    /// Returns an iterator over all of the services for this host.
180    pub fn services(&self) -> SrpServerServiceIterator<'_> {
181        SrpServerServiceIterator { prev: None, host: self }
182    }
183}
184
185/// Iterates over all the available SRP services subtypes.
186#[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/// This opaque type (only used by reference) represents a SRP service.
216///
217/// Functional equivalent of [`otsys::otSrpServerService`](crate::otsys::otSrpServerService).
218#[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    /// Functional equivalent of
249    /// [`otsys::otSrpServerServiceGetPort`](crate::otsys::otSrpServerServiceGetPort).
250    pub fn port(&self) -> u16 {
251        unsafe { otSrpServerServiceGetPort(self.as_ot_ptr()) }
252    }
253
254    /// Functional equivalent of
255    /// [`otsys::otSrpServerServiceGetPriority`](crate::otsys::otSrpServerServiceGetPriority).
256    pub fn priority(&self) -> u16 {
257        unsafe { otSrpServerServiceGetPriority(self.as_ot_ptr()) }
258    }
259
260    /// Functional equivalent of
261    /// [`otsys::otSrpServerServiceIsDeleted`](crate::otsys::otSrpServerServiceIsDeleted).
262    pub fn is_deleted(&self) -> bool {
263        unsafe { otSrpServerServiceIsDeleted(self.as_ot_ptr()) }
264    }
265
266    /// Functional equivalent of
267    /// [`otsys::otSrpServerServiceGetLeaseInfo`](crate::otsys::otSrpServerServiceGetLeaseInfo).
268    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    /// Returns an iterator over all of the subtypes.
273    pub fn subtypes(&self) -> SrpServerServiceSubtypeIterator<'_> {
274        SrpServerServiceSubtypeIterator { service: self, next_i: 0 }
275    }
276
277    /// Functional equivalent of
278    /// [`otsys::otSrpServerServiceGetNumberOfSubTypes`](crate::otsys::otSrpServerServiceGetNumberOfSubTypes).
279    pub fn number_of_subtypes(&self) -> u16 {
280        unsafe { otSrpServerServiceGetNumberOfSubTypes(self.as_ot_ptr()) }
281    }
282
283    /// Functional equivalent of
284    /// [`otsys::otSrpServerServiceGetSubTypeServiceNameAt`](crate::otsys::otSrpServerServiceGetSubTypeServiceNameAt).
285    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    /// Functional equivalent of
293    /// [`otsys::otSrpServerServiceGetTxtData`](crate::otsys::otSrpServerServiceGetTxtData).
294    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    /// Returns iterator over all the DNS TXT entries.
309    pub fn txt_entries(&self) -> DnsTxtEntryIterator<'_> {
310        DnsTxtEntryIterator::try_new(self.txt_data()).unwrap()
311    }
312
313    /// Functional equivalent of
314    /// [`otsys::otSrpServerServiceGetWeight`](crate::otsys::otSrpServerServiceGetWeight).
315    pub fn weight(&self) -> u16 {
316        unsafe { otSrpServerServiceGetWeight(self.as_ot_ptr()) }
317    }
318
319    /// Functional equivalent of
320    /// [`otsys::otSrpServerServiceGetServiceName`](crate::otsys::otSrpServerServiceGetServiceName).
321    pub fn service_name_cstr(&self) -> &CStr {
322        unsafe { CStr::from_ptr(otSrpServerServiceGetServiceName(self.as_ot_ptr())) }
323    }
324
325    /// Functional equivalent of
326    /// [`otsys::otSrpServerServiceGetInstanceName`](crate::otsys::otSrpServerServiceGetInstanceName).
327    pub fn instance_name_cstr(&self) -> &CStr {
328        unsafe { CStr::from_ptr(otSrpServerServiceGetInstanceName(self.as_ot_ptr())) }
329    }
330
331    /// Functional equivalent of
332    /// [`otsys::otSrpServerServiceGetInstanceLabel`](crate::otsys::otSrpServerServiceGetInstanceLabel).
333    pub fn instance_label_cstr(&self) -> &CStr {
334        unsafe { CStr::from_ptr(otSrpServerServiceGetInstanceLabel(self.as_ot_ptr())) }
335    }
336
337    /// Functional equivalent of
338    /// [`otsys::otSrpServerServiceGetTtl`](crate::otsys::otSrpServerServiceGetTtl).
339    pub fn ttl(&self) -> zx::MonotonicDuration {
340        unsafe {
341            zx::MonotonicDuration::from_seconds(otSrpServerServiceGetTtl(self.as_ot_ptr()).into())
342        }
343    }
344}
345
346/// The ID of a SRP service update transaction on the SRP Server.
347///
348/// Functional equivalent of
349/// [`otsys::otSrpServerServiceUpdateId`](crate::otsys::otSrpServerServiceUpdateId).
350#[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
363/// Server Methods from the [OpenThread SRP Module][1].
364///
365/// [1]: https://openthread.io/reference/group/api-srp
366pub trait SrpServer {
367    /// Functional equivalent of
368    /// [`otsys::otSrpServerGetAddressMode`](crate::otsys::otSrpServerGetAddressMode).
369    fn srp_server_get_address_mode(&self) -> SrpServerAddressMode;
370
371    /// Functional equivalent of
372    /// [`otsys::otSrpServerGetState`](crate::otsys::otSrpServerGetState).
373    fn srp_server_get_state(&self) -> SrpServerState;
374
375    /// Functional equivalent of
376    /// [`otsys::otSrpServerGetPort`](crate::otsys::otSrpServerGetPort).
377    fn srp_server_get_port(&self) -> u16;
378
379    /// Functional equivalent of
380    /// [`otsys::otSrpServerSetEnabled`](crate::otsys::otSrpServerSetEnabled).
381    fn srp_server_set_enabled(&self, enabled: bool);
382
383    /// Functional equivalent of
384    /// [`otsys::otSrpServerSetEnabled`](crate::otsys::otSrpServerSetAutoEnableMode).
385    fn srp_server_set_auto_enable_mode(&self, enabled: bool);
386
387    /// Returns true if the SRP server is enabled.
388    fn srp_server_is_enabled(&self) -> bool;
389
390    /// Returns true if SRP server auto-enable mode is enabled.
391    fn srp_server_is_auto_enable_mode(&self) -> bool;
392
393    /// Returns true if the SRP server is running, false if it is stopped or disabled.
394    fn srp_server_is_running(&self) -> bool;
395
396    /// Functional equivalent of
397    /// [`otsys::otSrpServerSetDomain`](crate::otsys::otSrpServerSetDomain).
398    fn srp_server_set_domain(&self, domain: &CStr) -> Result;
399
400    /// Functional equivalent of
401    /// [`otsys::otSrpServerGetDomain`](crate::otsys::otSrpServerGetDomain).
402    fn srp_server_get_domain(&self) -> &CStr;
403
404    /// Functional equivalent of
405    /// [`otsys::otSrpServerGetResponseCounters`](crate::otsys::otSrpServerGetResponseCounters).
406    fn srp_server_get_response_counters(&self) -> &SrpServerResponseCounters;
407
408    /// Functional equivalent of
409    /// [`otsys::otSrpServerGetNextHost`](crate::otsys::otSrpServerGetNextHost).
410    fn srp_server_next_host<'a>(
411        &'a self,
412        prev: Option<&'a SrpServerHost>,
413    ) -> Option<&'a SrpServerHost>;
414
415    /// Returns an iterator over the SRP hosts.
416    fn srp_server_hosts(&self) -> SrpServerHostIterator<'_, Self>
417    where
418        Self: Sized,
419    {
420        SrpServerHostIterator { prev: None, ot_instance: self }
421    }
422
423    /// Functional equivalent of
424    /// [`otsys::otSrpServerHandleServiceUpdateResult`](crate::otsys::otSrpServerHandleServiceUpdateResult).
425    fn srp_server_handle_service_update_result(&self, id: SrpServerServiceUpdateId, result: Result);
426
427    /// Functional equivalent of
428    /// [`otsys::otSrpServerSetServiceUpdateHandler`](crate::otsys::otSrpServerSetServiceUpdateHandler).
429    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    /// Functional equivalent of
434    /// [`otsys::otSrpServerParseSubTypeServiceName`](crate::otsys::otSrpServerParseSubTypeServiceName).
435    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            // Reconstitute a reference to our closure.
615            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        // This helper func is just to allow us to get the type of the
625        // wrapper closure (`f_wrapped`) so we can pass that type
626        // as a type argument to `_ot_srp_server_service_update_handler`.
627        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            // Grab a pointer to our ot::Instance for use below in the wrapper closure.
636            let ot_instance_ptr = self.as_ot_ptr();
637
638            // Wrap around `f` with a closure that fills in the `ot_instance` field, which we
639            // won't have access to inside of `_ot_srp_server_service_update_handler::<_>`.
640            let f_wrapped =
641                move |id: SrpServerServiceUpdateId, host: &'a SrpServerHost, timeout: u32| {
642                    // SAFETY: This ot::Instance will be passed to the original closure as
643                    //         an argument. We know that it is valid because:
644                    //         1. It is being called by the instance, so it must still be around.
645                    //         2. By design there are no mutable references to the `ot::Instance`
646                    //            in existence.
647                    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            // Since we don't have a way to directly refer to the type of the closure `f_wrapped`,
653            // we need to use a helper function that can pass the type as a generic argument to
654            // `_ot_srp_server_service_update_handler::<X>` as `X`.
655            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            // Make sure our object eventually gets cleaned up.
676            // Here we must also transmute our closure to have a 'static lifetime.
677            // We need to do this because the borrow checker cannot infer the
678            // proper lifetime for the singleton instance backing, but
679            // this is guaranteed by the API.
680            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        // SAFETY: We are passing in valid pointers with a length one less than the array size.
694        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        // SAFETY: `bytes` is guaranteed to be zero terminated because of the size of the array.
704        Ok(unsafe { CStr::from_ptr(&bytes as *const c_char) }.to_owned())
705    }
706}