-/* $Id$ */
-
/***
This file is part of avahi.
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
{
Found,
Failure
}
-
+
internal enum BrowserEvent {
Added,
Removed,
public class ClientStateArgs : EventArgs
{
private ClientState state;
+ private ErrorCode error;
public ClientState State
{
get { return state; }
}
- public ClientStateArgs (ClientState state)
+ public ErrorCode Error
+ {
+ get { return error; }
+ }
+
+ public ClientStateArgs (ClientState state, ErrorCode error)
{
this.state = state;
+ this.error = error;
}
}
-
+
public enum Protocol {
Unspecified = -1,
IPv4 = 0,
Running,
Collision
}
-
+
public enum ClientState {
Registering = ServerState.Registering,
Running = ServerState.Running,
public enum LookupFlags {
None = 0,
UseWideArea = 1,
- UseMulticast = 4,
+ UseMulticast = 2,
+ NoTxt = 4,
NoAddress = 8
}
IgnoreUserConfig = 1,
NoFail = 2
}
-
+
public class Client : IDisposable
{
private IntPtr handle;
[DllImport ("avahi-client")]
private static extern int avahi_client_errno (IntPtr handle);
-
+
[DllImport ("avahi-common")]
private static extern IntPtr avahi_simple_poll_new ();
[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);
{
get { return handle; }
}
-
+
public string Version
{
get {
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 ()
{
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, new ClientStateArgs (state));
+ StateChanged (this, new ClientStateArgs (state, LastError));
}
private int OnPollCallback (IntPtr ufds, uint nfds, int timeout) {
try {
lock (this) {
avahi_simple_poll_loop (spoll);
+ Monitor.Pulse (this);
}
} catch (Exception e) {
Console.Error.WriteLine ("Error in avahi-sharp event loop: " + e);