X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-sharp%2FClient.cs;h=b3815b32cb5d3120bacf2b83bad89c82ae5819bf;hb=dac7e8a519f90d85f6bcdde6164f0f352c485c82;hp=394efc58e22100db7790d83782927e1815a923f2;hpb=e2baad5870d5aaf25657035b2391a3a29f7cff46;p=catta diff --git a/avahi-sharp/Client.cs b/avahi-sharp/Client.cs index 394efc5..b3815b3 100644 --- a/avahi-sharp/Client.cs +++ b/avahi-sharp/Client.cs @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of avahi. @@ -24,6 +22,10 @@ using System; using System.Threading; using System.Collections; using System.Runtime.InteropServices; +using Mono.Unix; +using Mono.Unix.Native; + +using Stdlib = Mono.Unix.Native.Stdlib; namespace Avahi { @@ -31,7 +33,7 @@ namespace Avahi Found, Failure } - + internal enum BrowserEvent { Added, Removed, @@ -43,7 +45,29 @@ namespace Avahi 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 class ClientStateArgs : EventArgs + { + private ClientState state; + private ErrorCode error; + + public ClientState State + { + get { return state; } + } + + public ErrorCode Error + { + get { return error; } + } + + public ClientStateArgs (ClientState state, ErrorCode error) + { + this.state = state; + this.error = error; + } + } public enum Protocol { Unspecified = -1, @@ -57,7 +81,7 @@ namespace Avahi Running, Collision } - + public enum ClientState { Registering = ServerState.Registering, Running = ServerState.Running, @@ -70,7 +94,8 @@ namespace Avahi public enum LookupFlags { None = 0, UseWideArea = 1, - UseMulticast = 4, + UseMulticast = 2, + NoTxt = 4, NoAddress = 8 } @@ -90,7 +115,7 @@ namespace Avahi IgnoreUserConfig = 1, NoFail = 2 } - + public class Client : IDisposable { private IntPtr handle; @@ -124,7 +149,7 @@ namespace Avahi [DllImport ("avahi-client")] private static extern int avahi_client_errno (IntPtr handle); - + [DllImport ("avahi-common")] private static extern IntPtr avahi_simple_poll_new (); @@ -146,6 +171,15 @@ namespace Avahi [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); @@ -156,7 +190,7 @@ namespace Avahi { get { return handle; } } - + public string Version { get { @@ -250,11 +284,68 @@ namespace Avahi public void Dispose () { if (handle != IntPtr.Zero) { - avahi_client_free (handle); - avahi_simple_poll_quit (spoll); - avahi_simple_poll_free (spoll); - handle = IntPtr.Zero; + lock (this) { + avahi_client_free (handle); + handle = IntPtr.Zero; + + avahi_simple_poll_quit (spoll); + Monitor.Wait (this); + + avahi_simple_poll_free (spoll); + } + } + } + + 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); + + 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; + } + + public static void SplitServiceName (string service, out string name, out string type, out string domain) + { + 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; + } + + name = Utility.PtrToString (namePtr); + type = Utility.PtrToString (typePtr); + domain = Utility.PtrToString (domainPtr); + + Utility.Free (namePtr); + Utility.Free (typePtr); + Utility.Free (domainPtr); } internal void ThrowError () @@ -264,11 +355,11 @@ namespace Avahi 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, LastError)); } private int OnPollCallback (IntPtr ufds, uint nfds, int timeout) { @@ -282,6 +373,7 @@ namespace Avahi try { lock (this) { avahi_simple_poll_loop (spoll); + Monitor.Pulse (this); } } catch (Exception e) { Console.Error.WriteLine ("Error in avahi-sharp event loop: " + e);