4 This file is part of avahi.
6 avahi is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 avahi is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14 Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with avahi; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 using System.Collections;
25 using System.Runtime.InteropServices;
32 internal delegate void ServiceResolverCallback (IntPtr resolver, int iface, Protocol proto,
33 ResolverEvent revent, IntPtr name, IntPtr type,
34 IntPtr domain, IntPtr host, IntPtr address,
35 UInt16 port, IntPtr txt, LookupResultFlags flags,
38 public class ServiceResolver : ResolverBase, IDisposable
40 private IntPtr handle;
41 private ServiceInfo currentInfo;
42 private Client client;
44 private Protocol proto;
47 private string domain;
48 private Protocol aproto;
49 private LookupFlags flags;
50 private ServiceResolverCallback cb;
52 private ArrayList foundListeners = new ArrayList ();
53 private ArrayList timeoutListeners = new ArrayList ();
55 [DllImport ("avahi-client")]
56 private static extern IntPtr avahi_service_resolver_new (IntPtr client, int iface, Protocol proto,
57 byte[] name, byte[] type, byte[] domain,
58 Protocol aproto, LookupFlags flags,
59 ServiceResolverCallback cb,
62 [DllImport ("avahi-common")]
63 private static extern IntPtr avahi_string_list_get_next (IntPtr list);
65 [DllImport ("avahi-common")]
66 private static extern IntPtr avahi_string_list_get_text (IntPtr list);
68 [DllImport ("avahi-common")]
69 private static extern int avahi_string_list_get_size (IntPtr list);
71 [DllImport ("avahi-client")]
72 private static extern void avahi_service_resolver_free (IntPtr handle);
74 public event ServiceInfoHandler Found
77 foundListeners.Add (value);
81 foundListeners.Remove (value);
86 public event EventHandler Timeout
89 timeoutListeners.Add (value);
93 timeoutListeners.Remove (value);
98 public ServiceInfo Service
100 get { return currentInfo; }
103 public ServiceResolver (Client client, string name, string type, string domain) : this (client, -1,
104 Protocol.Unspecified,
106 Protocol.Unspecified,
111 public ServiceResolver (Client client, ServiceInfo service) : this (client, service.NetworkInterface,
112 service.Protocol, service.Name,
113 service.ServiceType, service.Domain,
114 Protocol.Unspecified,
115 GetLookupFlags (service.Flags))
119 public ServiceResolver (Client client, int iface, Protocol proto, string name,
120 string type, string domain, Protocol aproto, LookupFlags flags)
122 this.client = client;
127 this.domain = domain;
128 this.aproto = aproto;
130 cb = OnServiceResolverCallback;
138 public void Dispose ()
143 private void Start ()
145 if (client.Handle == IntPtr.Zero || handle != IntPtr.Zero ||
146 (foundListeners.Count == 0 && timeoutListeners.Count == 0))
150 handle = avahi_service_resolver_new (client.Handle, iface, proto,
151 Utility.StringToBytes (name), Utility.StringToBytes (type),
152 Utility.StringToBytes (domain), aproto, flags, cb, IntPtr.Zero);
154 if (handle == IntPtr.Zero)
155 client.ThrowError ();
159 private void Stop (bool force)
161 if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero &&
162 (force || (foundListeners.Count == 0 && timeoutListeners.Count == 0))) {
165 avahi_service_resolver_free (handle);
166 handle = IntPtr.Zero;
171 private void OnServiceResolverCallback (IntPtr resolver, int iface, Protocol proto,
172 ResolverEvent revent, IntPtr name, IntPtr type,
173 IntPtr domain, IntPtr host, IntPtr address,
174 UInt16 port, IntPtr txt, LookupResultFlags flags,
178 info.NetworkInterface = iface;
179 info.Protocol = proto;
180 info.Domain = Utility.PtrToString (domain);
181 info.ServiceType = Utility.PtrToString (type);
182 info.Name = Utility.PtrToString (name);
183 info.HostName = Utility.PtrToString (host);
184 info.Address = Utility.PtrToAddress (address);
187 ArrayList txtlist = new ArrayList ();
188 for (IntPtr l = txt; l != IntPtr.Zero; l = avahi_string_list_get_next (l)) {
189 IntPtr buf = avahi_string_list_get_text (l);
190 int len = avahi_string_list_get_size (l);
192 byte[] txtbuf = new byte[len];
193 Marshal.Copy (buf, txtbuf, 0, len);
194 txtlist.Add (txtbuf);
197 info.Text = (byte[][]) txtlist.ToArray (typeof (byte[]));
201 case ResolverEvent.Found:
204 foreach (ServiceInfoHandler handler in foundListeners)
205 handler (this, new ServiceInfoArgs (info));
207 case ResolverEvent.Failure:
208 EmitFailure (client.LastError);
213 private static LookupFlags GetLookupFlags (LookupResultFlags rflags) {
214 LookupFlags ret = LookupFlags.None;
216 if ((rflags & LookupResultFlags.Multicast) > 0)
217 ret |= LookupFlags.UseMulticast;
218 if ((rflags & LookupResultFlags.WideArea) > 0)
219 ret |= LookupFlags.UseWideArea;