X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-sharp%2FClient.cs;h=80349ddb9902b5e925668f1e578cf6de6d1bb41a;hb=0da62a499e177d194cb8622e3cd1dd9d6bc170e8;hp=c3584c59b13d450ab67649bf6811b937fd266c92;hpb=264700bf97de2e4430494cb41201950162fba020;p=catta diff --git a/avahi-sharp/Client.cs b/avahi-sharp/Client.cs index c3584c5..80349dd 100644 --- a/avahi-sharp/Client.cs +++ b/avahi-sharp/Client.cs @@ -24,36 +24,87 @@ using System; using System.Threading; using System.Collections; using System.Runtime.InteropServices; +using Mono.Unix; namespace Avahi { internal enum ResolverEvent { Found, - Timeout + Failure } internal enum BrowserEvent { Added, - Removed + Removed, + CacheExhausted, + AllForNow, + Failure } 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, ClientState state); + public delegate void ClientStateHandler (object o, ClientStateArgs state); - public enum Protocol { - Unspecified = 0, - IPv4 = 2, - IPv6 = 10 + 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 @@ -66,7 +117,7 @@ namespace Avahi private Thread thread; [DllImport ("avahi-client")] - private static extern IntPtr avahi_client_new (IntPtr poll, ClientCallback handler, + private static extern IntPtr avahi_client_new (IntPtr poll, ClientFlags flags, ClientCallback handler, IntPtr userData, out int error); [DllImport ("avahi-client")] @@ -100,7 +151,7 @@ namespace Avahi private static extern void avahi_simple_poll_free (IntPtr spoll); [DllImport ("avahi-common")] - private static extern int avahi_simple_poll_iterate (IntPtr spoll, int timeout); + 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); @@ -108,6 +159,19 @@ namespace Avahi [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 ("avahi-common")] + private static extern int avahi_service_name_join (IntPtr buf, int len, byte[] name, byte[] type, + byte[] domain); + + [DllImport ("avahi-common")] + private static extern int avahi_service_name_split (byte[] service, IntPtr name, int name_len, + IntPtr type, int type_len, + IntPtr domain, int domain_len); + + [DllImport ("libc")] private static extern int poll(IntPtr ufds, uint nfds, int timeout); @@ -163,16 +227,25 @@ namespace Avahi } } - internal int LastError + public uint LocalServiceCookie { get { lock (this) { - return avahi_client_errno (handle); + return avahi_client_get_local_service_cookie (handle); } } } - public Client () + internal ErrorCode LastError + { + get { + lock (this) { + return (ErrorCode) avahi_client_errno (handle); + } + } + } + + public Client (ClientFlags flags) { spoll = avahi_simple_poll_new (); @@ -182,7 +255,7 @@ namespace Avahi cb = OnClientCallback; int error; - handle = avahi_client_new (poll, cb, IntPtr.Zero, out error); + handle = avahi_client_new (poll, flags, cb, IntPtr.Zero, out error); if (error != 0) throw new ClientException (error); @@ -191,6 +264,9 @@ namespace Avahi thread.Start (); } + public Client () : this (ClientFlags.None) { + } + ~Client () { Dispose (); @@ -198,30 +274,78 @@ namespace Avahi public void Dispose () { - lock (this) { - if (handle != IntPtr.Zero) { - thread.Abort (); + if (handle != IntPtr.Zero) { + avahi_client_free (handle); + avahi_simple_poll_quit (spoll); + avahi_simple_poll_free (spoll); + handle = IntPtr.Zero; + } + } + + public static string JoinServiceName (string name, string type, string domain) + { + int len = 4 * (name.Length + type.Length + domain.Length) + 4; + IntPtr buf = Stdlib.malloc ((ulong) len); - avahi_client_free (handle); - avahi_simple_poll_quit (spoll); - avahi_simple_poll_free (spoll); - handle = IntPtr.Zero; - } + int ret = avahi_service_name_join (buf, len, + Utility.StringToBytes (name), + Utility.StringToBytes (type), + Utility.StringToBytes (domain)); + + if (ret < 0) { + Utility.Free (buf); + return null; // FIXME, should throw exception } + + string service = Utility.PtrToString (buf); + Utility.Free (buf); + + return service; } - internal void CheckError () + public static void SplitServiceName (string service, out string name, out string type, out string domain) { - int error = LastError; + int len = 1024; + + IntPtr namePtr = Stdlib.malloc ((ulong) len); + IntPtr typePtr = Stdlib.malloc ((ulong) len); + IntPtr domainPtr = Stdlib.malloc ((ulong) len); + + int ret = avahi_service_name_split (Utility.StringToBytes (service), namePtr, len, typePtr, len, + domainPtr, len); + + if (ret < 0) { + Utility.Free (namePtr); + Utility.Free (typePtr); + Utility.Free (domainPtr); + + name = null; + type = null; + domain = null; + return; + } - if (error != 0) + name = Utility.PtrToString (namePtr); + type = Utility.PtrToString (typePtr); + domain = Utility.PtrToString (domainPtr); + + Utility.Free (namePtr); + Utility.Free (typePtr); + Utility.Free (domainPtr); + } + + internal void ThrowError () + { + ErrorCode error = LastError; + + if (error != ErrorCode.Ok) throw new ClientException (error); } private void OnClientCallback (IntPtr client, ClientState state, IntPtr userData) { if (StateChanged != null) - StateChanged (this, state); + StateChanged (this, new ClientStateArgs (state)); } private int OnPollCallback (IntPtr ufds, uint nfds, int timeout) { @@ -234,12 +358,8 @@ namespace Avahi private void PollLoop () { try { lock (this) { - while (true) { - if (avahi_simple_poll_iterate (spoll, -1) != 0) - break; - } + avahi_simple_poll_loop (spoll); } - } catch (ThreadAbortException e) { } catch (Exception e) { Console.Error.WriteLine ("Error in avahi-sharp event loop: " + e); }