use crate::prelude_internal::*;
#[allow(missing_debug_implementations)]
pub struct NeighborInfoIterator<'a, T: ?Sized> {
ot_instance: &'a T,
ot_iter: otNeighborInfoIterator,
}
impl<T: ?Sized + Thread> Iterator for NeighborInfoIterator<'_, T> {
type Item = NeighborInfo;
fn next(&mut self) -> Option<Self::Item> {
self.ot_instance.iter_next_neighbor_info(&mut self.ot_iter)
}
}
pub trait Thread {
fn become_leader(&self) -> Result;
fn become_router(&self) -> Result;
fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo>;
fn get_leader_data(&self) -> Result<LeaderData>;
fn get_leader_weight(&self) -> u8;
#[must_use]
fn get_network_key(&self) -> NetworkKey;
fn set_network_key(&self, key: &NetworkKey) -> Result;
#[must_use]
fn get_network_name(&self) -> NetworkName {
NetworkName::try_from_slice(self.get_network_name_as_slice()).unwrap()
}
#[must_use]
fn get_network_name_as_slice(&self) -> &[u8];
fn set_network_name(&self, name: &NetworkName) -> Result;
#[must_use]
fn is_singleton(&self) -> bool;
#[must_use]
fn get_extended_pan_id(&self) -> &ExtendedPanId;
fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result;
fn thread_set_enabled(&self, enabled: bool) -> Result;
#[must_use]
fn get_device_role(&self) -> DeviceRole;
fn get_partition_id(&self) -> u32;
fn get_rloc16(&self) -> u16;
fn get_link_mode(&self) -> ot::LinkModeConfig;
fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result;
fn get_rloc(&self) -> std::net::Ipv6Addr;
fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr;
fn get_link_local_addr(&self) -> std::net::Ipv6Addr;
fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr;
fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix;
fn get_router_info(&self, router_id: u16) -> Result<RouterInfo>;
fn get_ip6_counters(&self) -> &IpCounters;
fn iter_next_neighbor_info(&self, ot_iter: &mut otNeighborInfoIterator)
-> Option<NeighborInfo>;
fn iter_neighbor_info(&self) -> NeighborInfoIterator<'_, Self> {
NeighborInfoIterator {
ot_instance: self,
ot_iter: OT_NEIGHBOR_INFO_ITERATOR_INIT.try_into().unwrap(),
}
}
}
impl<T: Thread + Boxable> Thread for ot::Box<T> {
fn become_leader(&self) -> Result<()> {
self.as_ref().become_leader()
}
fn become_router(&self) -> Result<()> {
self.as_ref().become_router()
}
fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
self.as_ref().get_child_info_by_id(child_id)
}
fn get_leader_data(&self) -> Result<LeaderData> {
self.as_ref().get_leader_data()
}
fn get_leader_weight(&self) -> u8 {
self.as_ref().get_leader_weight()
}
fn get_network_key(&self) -> NetworkKey {
self.as_ref().get_network_key()
}
fn set_network_key(&self, key: &NetworkKey) -> Result {
self.as_ref().set_network_key(key)
}
fn get_network_name_as_slice(&self) -> &[u8] {
self.as_ref().get_network_name_as_slice()
}
fn set_network_name(&self, name: &NetworkName) -> Result {
self.as_ref().set_network_name(name)
}
fn is_singleton(&self) -> bool {
self.as_ref().is_singleton()
}
fn get_extended_pan_id(&self) -> &ExtendedPanId {
self.as_ref().get_extended_pan_id()
}
fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
self.as_ref().set_extended_pan_id(xpanid)
}
fn thread_set_enabled(&self, enabled: bool) -> Result {
self.as_ref().thread_set_enabled(enabled)
}
fn get_device_role(&self) -> DeviceRole {
self.as_ref().get_device_role()
}
fn get_partition_id(&self) -> u32 {
self.as_ref().get_partition_id()
}
fn get_rloc16(&self) -> u16 {
self.as_ref().get_rloc16()
}
fn get_link_mode(&self) -> ot::LinkModeConfig {
self.as_ref().get_link_mode()
}
fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
self.as_ref().set_link_mode(link_mode_config)
}
fn get_rloc(&self) -> std::net::Ipv6Addr {
self.as_ref().get_rloc()
}
fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
self.as_ref().get_mesh_local_eid()
}
fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
self.as_ref().get_link_local_addr()
}
fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
self.as_ref().get_link_local_all_nodes_multicast_addr()
}
fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
self.as_ref().get_mesh_local_prefix()
}
fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
self.as_ref().get_router_info(router_id)
}
fn get_ip6_counters(&self) -> &IpCounters {
self.as_ref().get_ip6_counters()
}
fn iter_next_neighbor_info(
&self,
ot_iter: &mut otNeighborInfoIterator,
) -> Option<NeighborInfo> {
self.as_ref().iter_next_neighbor_info(ot_iter)
}
}
impl Thread for Instance {
fn become_leader(&self) -> Result<()> {
Error::from(unsafe { otThreadBecomeLeader(self.as_ot_ptr()) }).into()
}
fn become_router(&self) -> Result<()> {
Error::from(unsafe { otThreadBecomeRouter(self.as_ot_ptr()) }).into()
}
fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
let mut ret: otChildInfo = Default::default();
Error::from(unsafe { otThreadGetChildInfoById(self.as_ot_ptr(), child_id, &mut ret) })
.into_result()?;
Ok(ret)
}
fn get_leader_data(&self) -> Result<LeaderData> {
let mut ret = LeaderData::default();
Error::from(unsafe { otThreadGetLeaderData(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
.into_result()?;
Ok(ret)
}
fn get_leader_weight(&self) -> u8 {
unsafe { otThreadGetLeaderWeight(self.as_ot_ptr()) }
}
fn get_network_key(&self) -> NetworkKey {
let mut ret = NetworkKey::default();
unsafe { otThreadGetNetworkKey(self.as_ot_ptr(), ret.as_ot_mut_ptr()) }
ret
}
fn set_network_key(&self, key: &NetworkKey) -> Result {
Error::from(unsafe { otThreadSetNetworkKey(self.as_ot_ptr(), key.as_ot_ptr()) })
.into_result()
}
#[allow(clippy::unnecessary_cast)]
fn get_network_name_as_slice(&self) -> &[u8] {
unsafe {
let slice = std::slice::from_raw_parts(
otThreadGetNetworkName(self.as_ot_ptr()) as *const u8,
OT_NETWORK_NAME_MAX_SIZE as usize,
);
let first_zero_index =
slice.iter().position(|&x| x == 0).unwrap_or(OT_NETWORK_NAME_MAX_SIZE as usize);
&slice[0..first_zero_index]
}
}
fn set_network_name(&self, name: &NetworkName) -> Result {
Error::from(unsafe { otThreadSetNetworkName(self.as_ot_ptr(), name.as_c_str()) })
.into_result()
}
fn is_singleton(&self) -> bool {
unsafe { otThreadIsSingleton(self.as_ot_ptr()) }
}
fn get_extended_pan_id(&self) -> &ExtendedPanId {
unsafe {
let xpanid = otThreadGetExtendedPanId(self.as_ot_ptr());
ExtendedPanId::ref_from_ot_ptr(xpanid)
}
.unwrap()
}
fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
Error::from(unsafe { otThreadSetExtendedPanId(self.as_ot_ptr(), xpanid.as_ot_ptr()) })
.into_result()
}
fn thread_set_enabled(&self, enabled: bool) -> Result {
Error::from(unsafe { otThreadSetEnabled(self.as_ot_ptr(), enabled) }).into_result()
}
fn get_device_role(&self) -> ot::DeviceRole {
unsafe { otThreadGetDeviceRole(self.as_ot_ptr()) }.into()
}
fn get_partition_id(&self) -> u32 {
unsafe { otThreadGetPartitionId(self.as_ot_ptr()) }
}
fn get_rloc16(&self) -> u16 {
unsafe { otThreadGetRloc16(self.as_ot_ptr()) }
}
fn get_link_mode(&self) -> ot::LinkModeConfig {
unsafe { otThreadGetLinkMode(self.as_ot_ptr()) }.into()
}
fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
Error::from(unsafe { otThreadSetLinkMode(self.as_ot_ptr(), link_mode_config.into()) })
.into_result()
}
fn get_rloc(&self) -> std::net::Ipv6Addr {
std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetRloc(self.as_ot_ptr()) })
}
fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetMeshLocalEid(self.as_ot_ptr()) })
}
fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetLinkLocalIp6Address(self.as_ot_ptr()) })
}
fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
std::net::Ipv6Addr::from_ot(unsafe {
*otThreadGetLinkLocalAllThreadNodesMulticastAddress(self.as_ot_ptr())
})
}
fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
unsafe { MeshLocalPrefix::ref_from_ot_ptr(otThreadGetMeshLocalPrefix(self.as_ot_ptr())) }
.unwrap()
}
fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
let mut ret = RouterInfo::default();
Error::from(unsafe {
otThreadGetRouterInfo(self.as_ot_ptr(), router_id, ret.as_ot_mut_ptr())
})
.into_result()?;
Ok(ret)
}
fn get_ip6_counters(&self) -> &IpCounters {
unsafe { IpCounters::ref_from_ot_ptr(otThreadGetIp6Counters(self.as_ot_ptr())) }.unwrap()
}
fn iter_next_neighbor_info(
&self,
ot_iter: &mut otNeighborInfoIterator,
) -> Option<NeighborInfo> {
unsafe {
let mut ret = NeighborInfo::default();
match Error::from(otThreadGetNextNeighborInfo(
self.as_ot_ptr(),
ot_iter as *mut otNeighborInfoIterator,
ret.as_ot_mut_ptr(),
)) {
Error::NotFound => None,
Error::None => Some(ret),
err => unreachable!("Unexpected error from otThreadGetNextNeighborInfo: {:?}", err),
}
}
}
}