X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-sharp%2FClient.cs;h=01b08bd5934c9e8eae4c126548151ed579a80f82;hb=1b1e2692e498d7bab5183c344887f83c0a94e4bb;hp=3e4e617b7742f5baf20d9f8f7a0e157382e5ace7;hpb=a26804ae8742b59b220b5a0776f42de3da026d6a;p=catta diff --git a/avahi-sharp/Client.cs b/avahi-sharp/Client.cs index 3e4e617..01b08bd 100644 --- a/avahi-sharp/Client.cs +++ b/avahi-sharp/Client.cs @@ -21,6 +21,7 @@ using System; +using System.Threading; using System.Collections; using System.Runtime.InteropServices; @@ -28,36 +29,94 @@ namespace Avahi { internal enum ResolverEvent { Found, - Timeout + Failure } internal enum BrowserEvent { Added, - Removed + Removed, + CacheExhausted, + AllForNow, + Failure } - - internal delegate void ClientHandler (IntPtr client, ClientState state, IntPtr userData); - public enum Protocol { - Unspecified = 0, - IPv4 = 2, - IPv6 = 10 + internal delegate int PollCallback (IntPtr ufds, uint nfds, int timeout); + internal delegate void ClientCallback (IntPtr client, ClientState state, IntPtr userData); + + public delegate void ClientStateHandler (object o, ClientStateArgs state); + + public class ClientStateArgs : EventArgs + { + private ClientState state; + + public ClientState State + { + get { return state; } + } + + public ClientStateArgs (ClientState state) + { + this.state = state; + } } - public enum ClientState { + public enum Protocol { + Unspecified = -1, + IPv4 = 0, + IPv6 = 1 + } + + internal enum ServerState { Invalid, Registering, Running, - Collision, - Disconnected = 100 + Collision + } + + public enum ClientState { + Registering = ServerState.Registering, + Running = ServerState.Running, + Collision = ServerState.Collision, + Failure = 100, + Connecting = 101 + } + + [Flags] + public enum LookupFlags { + None = 0, + UseWideArea = 1, + UseMulticast = 4, + NoAddress = 8 + } + + [Flags] + public enum LookupResultFlags { + None = 0, + Cached = 1, + WideArea = 2, + Multicast = 4, + Local = 8, + OurOwn = 16, + } + + [Flags] + public enum ClientFlags { + None = 0, + IgnoreUserConfig = 1, + NoFail = 2 } public class Client : IDisposable { private IntPtr handle; + private ClientCallback cb; + private PollCallback pollcb; + private IntPtr spoll; + + private Thread thread; [DllImport ("avahi-client")] - private static extern IntPtr avahi_client_new (IntPtr poll, ClientHandler handler, + private static extern IntPtr avahi_client_new (IntPtr poll, ClientFlags flags, ClientCallback handler, IntPtr userData, out int error); [DllImport ("avahi-client")] @@ -81,11 +140,32 @@ namespace Avahi [DllImport ("avahi-client")] private static extern int avahi_client_errno (IntPtr handle); - [DllImport ("avahi-glib")] - private static extern IntPtr avahi_glib_poll_new (IntPtr context, int priority); + [DllImport ("avahi-common")] + private static extern IntPtr avahi_simple_poll_new (); + + [DllImport ("avahi-common")] + private static extern IntPtr avahi_simple_poll_get (IntPtr spoll); + + [DllImport ("avahi-common")] + private static extern void avahi_simple_poll_free (IntPtr spoll); - [DllImport ("avahi-glib")] - private static extern IntPtr avahi_glib_poll_get (IntPtr gpoll); + [DllImport ("avahi-common")] + private static extern int avahi_simple_poll_loop (IntPtr spoll); + + [DllImport ("avahi-common")] + private static extern void avahi_simple_poll_set_func (IntPtr spoll, PollCallback cb); + + [DllImport ("avahi-common")] + private static extern void avahi_simple_poll_quit (IntPtr spoll); + + [DllImport ("avahi-client")] + private static extern uint avahi_client_get_local_service_cookie (IntPtr client); + + + [DllImport ("libc")] + private static extern int poll(IntPtr ufds, uint nfds, int timeout); + + public event ClientStateHandler StateChanged; internal IntPtr Handle { @@ -94,43 +174,87 @@ namespace Avahi public string Version { - get { return Utility.PtrToString (avahi_client_get_version_string (handle)); } + get { + lock (this) { + return Utility.PtrToString (avahi_client_get_version_string (handle)); + } + } } public string HostName { - get { return Utility.PtrToString (avahi_client_get_host_name (handle)); } + get { + lock (this) { + return Utility.PtrToString (avahi_client_get_host_name (handle)); + } + } } public string DomainName { - get { return Utility.PtrToString (avahi_client_get_domain_name (handle)); } + get { + lock (this) { + return Utility.PtrToString (avahi_client_get_domain_name (handle)); + } + } } public string HostNameFqdn { - get { return Utility.PtrToString (avahi_client_get_host_name_fqdn (handle)); } + get { + lock (this) { + return Utility.PtrToString (avahi_client_get_host_name_fqdn (handle)); + } + } } public ClientState State { - get { return (ClientState) avahi_client_get_state (handle); } + get { + lock (this) { + return (ClientState) avahi_client_get_state (handle); + } + } } - internal int LastError + public uint LocalServiceCookie { - get { return avahi_client_errno (handle); } + get { + lock (this) { + return avahi_client_get_local_service_cookie (handle); + } + } } - public Client () + internal ErrorCode LastError { - IntPtr gpoll = avahi_glib_poll_new (IntPtr.Zero, 0); - IntPtr poll = avahi_glib_poll_get (gpoll); + get { + lock (this) { + return (ErrorCode) avahi_client_errno (handle); + } + } + } + + public Client (ClientFlags flags) + { + spoll = avahi_simple_poll_new (); + + pollcb = OnPollCallback; + avahi_simple_poll_set_func (spoll, pollcb); + IntPtr poll = avahi_simple_poll_get (spoll); + cb = OnClientCallback; int error; - handle = avahi_client_new (poll, OnClientCallback, IntPtr.Zero, out error); + handle = avahi_client_new (poll, flags, cb, IntPtr.Zero, out error); if (error != 0) throw new ClientException (error); + + thread = new Thread (PollLoop); + thread.IsBackground = true; + thread.Start (); + } + + public Client () : this (ClientFlags.None) { } ~Client () @@ -142,21 +266,41 @@ namespace Avahi { if (handle != IntPtr.Zero) { avahi_client_free (handle); + avahi_simple_poll_quit (spoll); + avahi_simple_poll_free (spoll); handle = IntPtr.Zero; } } - internal void CheckError () + internal void ThrowError () { - int error = LastError; + ErrorCode error = LastError; - if (error != 0) + if (error != ErrorCode.Ok) throw new ClientException (error); } private void OnClientCallback (IntPtr client, ClientState state, IntPtr userData) { - Console.WriteLine ("Got new state: " + state); + if (StateChanged != null) + StateChanged (this, new ClientStateArgs (state)); + } + + private int OnPollCallback (IntPtr ufds, uint nfds, int timeout) { + Monitor.Exit (this); + int result = poll (ufds, nfds, timeout); + Monitor.Enter (this); + return result; + } + + private void PollLoop () { + try { + lock (this) { + avahi_simple_poll_loop (spoll); + } + } catch (Exception e) { + Console.Error.WriteLine ("Error in avahi-sharp event loop: " + e); + } } } }