Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions examples/browser/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,15 @@ fn main() -> zeroconf::Result<()> {

loop {
// calling `poll()` will keep this browser alive
event_loop.poll(Duration::from_secs(0))?;
event_loop.poll(Duration::from_secs(1))?;
Comment thread
windy1 marked this conversation as resolved.
}
}

fn on_service_discovered(
result: zeroconf::Result<ServiceDiscovery>,
_context: Option<Arc<dyn Any>>,
) {
info!(
"Service discovered: {:?}",
result.expect("service discovery failed")
);
info!("Service discovery event: {:?}", result);

// ...
}
22 changes: 17 additions & 5 deletions zeroconf/src/avahi/avahi_util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Utilities related to Avahi

use crate::ffi::c_str;
use crate::{ffi::c_str, Error};
use avahi_sys::{
avahi_address_snprint, avahi_alternative_service_name, avahi_strerror, AvahiAddress,
AvahiClient,
Expand Down Expand Up @@ -47,8 +47,14 @@ pub unsafe fn get_error<'a>(code: i32) -> &'a str {
///
/// # Safety
/// This function is unsafe because of internal Avahi calls.
pub unsafe fn get_last_error<'a>(client: *mut AvahiClient) -> &'a str {
get_error(avahi_sys::avahi_client_errno(client))
pub unsafe fn get_last_error(client: *mut AvahiClient) -> Error {
let code = avahi_sys::avahi_client_errno(client);
let message = get_error(code);

Error::MdnsSystemError {
code,
message: message.into(),
}
}

/// Converts the specified [`NetworkInterface`] to the Avahi expected value.
Expand Down Expand Up @@ -77,7 +83,10 @@ pub unsafe fn sys_exec<F: FnOnce() -> i32>(func: F, message: &str) -> Result<()>
let err = func();

if err < 0 {
Err(format!("{}: `{}`", message, get_error(err)).into())
Err(Error::MdnsSystemError {
code: err,
message: format!("{}: (code: {}, message:{:?})", message, err, get_error(err)).into(),
})
} else {
Ok(())
}
Expand Down Expand Up @@ -139,7 +148,10 @@ mod tests {
fn sys_exec_returns_error_for_failure() {
assert_eq!(
unsafe { sys_exec(|| avahi_sys::AVAHI_ERR_FAILURE, "uh oh spaghetti-o") },
Err("uh oh spaghetti-o: `Operation failed`".into())
Err(Error::MdnsSystemError {
code: avahi_sys::AVAHI_ERR_FAILURE,
message: "uh oh spaghetti-o: (code: -1, message:\"Operation failed\")".into(),
})
);
}

Expand Down
49 changes: 28 additions & 21 deletions zeroconf/src/avahi/browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use super::{
};
use crate::ffi::{c_str, AsRaw, FromRaw};
use crate::prelude::*;
use crate::Result;
use crate::{Error, Result};
use crate::{
EventLoop, NetworkInterface, ServiceDiscoveredCallback, ServiceDiscovery, ServiceType,
TxtRecord,
Expand Down Expand Up @@ -74,20 +74,25 @@ impl TMdnsBrowser for AvahiMdnsBrowser {
fn browse_services(&mut self) -> Result<EventLoop> {
debug!("Browsing services: {:?}", self);

self.poll = Some(Arc::new(unsafe { ManagedAvahiSimplePoll::new() }?));
self.poll = Some(Arc::new(
unsafe { ManagedAvahiSimplePoll::new() }.ok_or_else(|| {
Error::BrowserError("could not initialize AvahiSimplePoll".into())
})?,
));

let poll = self
.poll
.as_ref()
.ok_or("could not get poll as ref")?
.ok_or(Error::BrowserError("could not get poll as ref".into()))?
.clone();

let client_params = ManagedAvahiClientParams::builder()
.poll(poll)
.flags(AvahiClientFlags(0))
.callback(Some(client_callback))
.userdata(self.context.as_raw())
.build()?;
.build()
.map_err(Error::BrowserError)?;

self.client = Some(Arc::new(unsafe { ManagedAvahiClient::new(client_params) }?));

Expand All @@ -102,7 +107,7 @@ impl TMdnsBrowser for AvahiMdnsBrowser {
Ok(EventLoop::new(
self.poll
.as_ref()
.ok_or("could not get poll as ref")?
.ok_or(Error::BrowserError("could not get poll as ref".into()))?
.clone(),
))
}
Expand Down Expand Up @@ -171,13 +176,11 @@ unsafe fn create_browser(context: &mut AvahiBrowserContext) -> Result<()> {
.flags(0)
.callback(Some(browse_callback))
.userdata(context.as_raw())
.client(Arc::clone(
context
.client
.as_ref()
.ok_or("could not get client as ref")?,
))
.build()?,
.client(Arc::clone(context.client.as_ref().ok_or(
Error::BrowserError("could not get client as ref".into()),
)?))
.build()
.map_err(Error::BrowserError)?,
)?);

Ok(())
Expand All @@ -203,7 +206,7 @@ unsafe extern "C" fn browse_callback(
}
}
avahi_sys::AvahiBrowserEvent_AVAHI_BROWSER_FAILURE => {
context.invoke_callback(Err("browser failure".into()))
context.invoke_callback(Err(Error::BrowserError("browser failure".into())))
}
_ => {}
};
Expand All @@ -222,7 +225,7 @@ unsafe fn handle_browser_new(
let client = context
.client
.as_ref()
.ok_or("expected initialized client")?;
.ok_or(Error::BrowserError("expected initialized client".into()))?;

context.resolvers.insert(ManagedAvahiServiceResolver::new(
ManagedAvahiServiceResolverParams::builder()
Expand All @@ -236,7 +239,8 @@ unsafe fn handle_browser_new(
.flags(0)
.callback(Some(resolve_callback))
.userdata(raw_context)
.build()?,
.build()
.map_err(Error::BrowserError)?,
)?);

Ok(())
Expand Down Expand Up @@ -265,11 +269,13 @@ unsafe extern "C" fn resolve_callback(

match event {
avahi_sys::AvahiResolverEvent_AVAHI_RESOLVER_FAILURE => {
context.invoke_callback(Err(format!(
"failed to resolve service `{}` of type `{}` in domain `{}`",
name, kind, domain
)
.into()));
context.invoke_callback(Err(Error::BrowserError(
format!(
"failed to resolve service `{}` of type `{}` in domain `{}`",
name, kind, domain
)
.into(),
)));
}
avahi_sys::AvahiResolverEvent_AVAHI_RESOLVER_FOUND => {
let result = handle_resolver_found(
Expand Down Expand Up @@ -320,7 +326,8 @@ unsafe fn handle_resolver_found(
.address(address)
.port(port)
.txt(txt)
.build()?;
.build()
.map_err(Error::BrowserError)?;

debug!("Service resolved: {:?}", result);

Expand Down
21 changes: 9 additions & 12 deletions zeroconf/src/avahi/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

use std::sync::Arc;

use super::{avahi_util, poll::ManagedAvahiSimplePoll};
use super::avahi_util;
use super::poll::ManagedAvahiSimplePoll;
use crate::ffi::c_str;
use crate::Result;
use crate::{Error, Result};
use avahi_sys::{
avahi_client_free, avahi_client_get_host_name, avahi_client_new, avahi_simple_poll_get,
AvahiClient, AvahiClientCallback, AvahiClientFlags,
Expand Down Expand Up @@ -46,17 +47,13 @@ impl ManagedAvahiClient {
);

if inner.is_null() {
return Err("could not initialize AvahiClient".into());
return Err(Error::MdnsSystemError {
code: err,
message: avahi_util::get_error(err).into(),
});
}

match err {
0 => Ok(Self { inner, _poll: poll }),
_ => Err(format!(
"could not initialize AvahiClient: {}",
avahi_util::get_error(err)
)
.into()),
}
Ok(Self { inner, _poll: poll })
}

/// Delegate function for [`avahi_client_get_host_name()`].
Expand Down Expand Up @@ -99,6 +96,6 @@ pub(super) unsafe fn get_host_name<'a>(client: *mut AvahiClient) -> Result<&'a s
if !host_name.is_null() {
Ok(c_str::raw_to_str(host_name))
} else {
Err("could not get host name from AvahiClient".into())
Err(avahi_util::get_last_error(client))
}
}
11 changes: 5 additions & 6 deletions zeroconf/src/avahi/entry_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use crate::avahi::avahi_util;
use crate::ffi::UnwrapMutOrNull;
use crate::Result;
use avahi_sys::{
avahi_client_errno, avahi_entry_group_add_service_strlst,
avahi_entry_group_add_service_subtype, avahi_entry_group_commit, avahi_entry_group_free,
avahi_entry_group_is_empty, avahi_entry_group_new, avahi_entry_group_reset, AvahiClient,
AvahiEntryGroup, AvahiEntryGroupCallback, AvahiIfIndex, AvahiProtocol, AvahiPublishFlags,
avahi_entry_group_add_service_strlst, avahi_entry_group_add_service_subtype,
avahi_entry_group_commit, avahi_entry_group_free, avahi_entry_group_is_empty,
avahi_entry_group_new, avahi_entry_group_reset, AvahiClient, AvahiEntryGroup,
AvahiEntryGroupCallback, AvahiIfIndex, AvahiProtocol, AvahiPublishFlags,
};
use libc::{c_char, c_void};

Expand Down Expand Up @@ -40,8 +40,7 @@ impl ManagedAvahiEntryGroup {
let inner = avahi_entry_group_new(client.inner, callback, userdata);

if inner.is_null() {
let err = avahi_util::get_error(avahi_client_errno(client.inner));
Err(format!("could not initialize AvahiEntryGroup: {}", err).into())
Err(avahi_util::get_last_error(client.inner))
} else {
Ok(Self {
inner,
Expand Down
20 changes: 11 additions & 9 deletions zeroconf/src/avahi/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ impl ManagedAvahiSimplePoll {
///
/// # Safety
/// This function is unsafe because of the raw pointer dereference.
pub unsafe fn new() -> Result<Self> {
pub unsafe fn new() -> Option<Self> {
let poll = avahi_simple_poll_new();
if poll.is_null() {
Err("could not initialize AvahiSimplePoll".into())
None
} else {
Ok(Self(poll))
Some(Self(poll))
}
}

Expand Down Expand Up @@ -58,12 +58,14 @@ impl ManagedAvahiSimplePoll {
// Returns -1 on error, 0 on success and 1 if a quit request has been scheduled
match avahi_simple_poll_iterate(self.0, sleep_time) {
0 | 1 => Ok(()),
-1 => Err(Error::from(
"avahi_simple_poll_iterate(..) threw an error result",
)),
_ => Err(Error::from(
"avahi_simple_poll_iterate(..) returned an unknown result",
)),
-1 => Err(Error::MdnsSystemError {
code: -1, // Translates to AVAHI_ERR_FAILURE with description "Generic error code".
message: "avahi_simple_poll_iterate(..) threw an error result".into(),
}),
err => Err(Error::MdnsSystemError {
code: err,
message: "avahi_simple_poll_iterate(..) returned an unknown result".into(),
}),
}
}

Expand Down
4 changes: 2 additions & 2 deletions zeroconf/src/avahi/raw_browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::sync::Arc;

use crate::Result;
use crate::{avahi::avahi_util, Result};
use avahi_sys::{
avahi_service_browser_free, avahi_service_browser_get_client, avahi_service_browser_new,
AvahiClient, AvahiIfIndex, AvahiLookupFlags, AvahiProtocol, AvahiServiceBrowser,
Expand Down Expand Up @@ -52,7 +52,7 @@ impl ManagedAvahiServiceBrowser {
);

if inner.is_null() {
Err("could not initialize Avahi service browser".into())
Err(avahi_util::get_last_error(client.inner))
} else {
Ok(Self {
inner,
Expand Down
4 changes: 2 additions & 2 deletions zeroconf/src/avahi/resolver.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Rust friendly `AvahiServiceResolver` wrappers/helpers

use crate::Result;
use crate::{avahi::avahi_util, Result};
use avahi_sys::{
avahi_service_resolver_free, avahi_service_resolver_new, AvahiIfIndex, AvahiLookupFlags,
AvahiProtocol, AvahiServiceResolver, AvahiServiceResolverCallback,
Expand Down Expand Up @@ -55,7 +55,7 @@ impl ManagedAvahiServiceResolver {
);

if inner.is_null() {
Err("could not initialize AvahiServiceResolver".into())
Err(avahi_util::get_last_error(client.inner))
} else {
Ok(Self {
inner,
Expand Down
Loading