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;
31 internal delegate void ServiceResolverCallback (IntPtr resolver, int iface, Protocol proto,
32 ResolverEvent revent, IntPtr name, IntPtr type,
33 IntPtr domain, IntPtr host, IntPtr address,
34 UInt16 port, IntPtr txt, LookupResultFlags flags,
37 public class ServiceResolver : ResolverBase, IDisposable
39 private IntPtr handle;
40 private ServiceInfo currentInfo;
41 private Client client;
43 private Protocol proto;
46 private string domain;
47 private Protocol aproto;
48 private LookupFlags flags;
49 private ServiceResolverCallback cb;
51 private ArrayList foundListeners = new ArrayList ();
52 private ArrayList timeoutListeners = new ArrayList ();
54 [DllImport ("avahi-client")]
55 private static extern IntPtr avahi_service_resolver_new (IntPtr client, int iface, Protocol proto,
56 IntPtr name, IntPtr type, IntPtr domain,
57 Protocol aproto, LookupFlags flags,
58 ServiceResolverCallback cb,
61 [DllImport ("avahi-common")]
62 private static extern IntPtr avahi_string_list_get_next (IntPtr list);
64 [DllImport ("avahi-common")]
65 private static extern IntPtr avahi_string_list_get_text (IntPtr list);
67 [DllImport ("avahi-common")]
68 private static extern int avahi_string_list_get_size (IntPtr list);
70 [DllImport ("avahi-client")]
71 private static extern void avahi_service_resolver_free (IntPtr handle);
73 public event ServiceInfoHandler Found
76 foundListeners.Add (value);
80 foundListeners.Remove (value);
85 public event EventHandler Timeout
88 timeoutListeners.Add (value);
92 timeoutListeners.Remove (value);
97 public ServiceInfo Service
99 get { return currentInfo; }
102 public ServiceResolver (Client client, string name, string type, string domain) : this (client, -1,
103 Protocol.Unspecified,
105 Protocol.Unspecified,
110 public ServiceResolver (Client client, ServiceInfo service) : this (client, service.NetworkInterface,
111 service.Protocol, service.Name,
112 service.ServiceType, service.Domain,
113 Protocol.Unspecified,
114 GetLookupFlags (service.Flags))
118 public ServiceResolver (Client client, int iface, Protocol proto, string name,
119 string type, string domain, Protocol aproto, LookupFlags flags)
121 this.client = client;
126 this.domain = domain;
127 this.aproto = aproto;
129 cb = OnServiceResolverCallback;
137 public void Dispose ()
142 private void Start ()
144 if (client.Handle == IntPtr.Zero || handle != IntPtr.Zero ||
145 (foundListeners.Count == 0 && timeoutListeners.Count == 0))
148 IntPtr namePtr = Utility.StringToPtr (name);
149 IntPtr typePtr = Utility.StringToPtr (type);
150 IntPtr domainPtr = Utility.StringToPtr (domain);
153 handle = avahi_service_resolver_new (client.Handle, iface, proto, namePtr, typePtr, domainPtr,
154 aproto, flags, cb, IntPtr.Zero);
157 Utility.Free (namePtr);
158 Utility.Free (typePtr);
159 Utility.Free (domainPtr);
162 private void Stop (bool force)
164 if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero &&
165 (force || (foundListeners.Count == 0 && timeoutListeners.Count == 0))) {
168 avahi_service_resolver_free (handle);
169 handle = IntPtr.Zero;
174 private void OnServiceResolverCallback (IntPtr resolver, int iface, Protocol proto,
175 ResolverEvent revent, IntPtr name, IntPtr type,
176 IntPtr domain, IntPtr host, IntPtr address,
177 UInt16 port, IntPtr txt, LookupResultFlags flags,
181 info.NetworkInterface = iface;
182 info.Protocol = proto;
183 info.Domain = Utility.PtrToString (domain);
184 info.ServiceType = Utility.PtrToString (type);
185 info.Name = Utility.PtrToString (name);
186 info.HostName = Utility.PtrToString (host);
187 info.Address = Utility.PtrToAddress (address);
190 ArrayList txtlist = new ArrayList ();
191 for (IntPtr l = txt; l != IntPtr.Zero; l = avahi_string_list_get_next (l)) {
192 IntPtr buf = avahi_string_list_get_text (l);
193 int len = avahi_string_list_get_size (l);
195 byte[] txtbuf = new byte[len];
196 Marshal.Copy (buf, txtbuf, 0, len);
197 txtlist.Add (txtbuf);
200 info.Text = (byte[][]) txtlist.ToArray (typeof (byte[]));
204 case ResolverEvent.Found:
207 foreach (ServiceInfoHandler handler in foundListeners)
208 handler (this, info);
210 case ResolverEvent.Timeout:
211 currentInfo = ServiceInfo.Zero;
213 foreach (EventHandler handler in timeoutListeners)
214 handler (this, new EventArgs ());
217 EmitResolverEvent (revent);
222 private static LookupFlags GetLookupFlags (LookupResultFlags rflags) {
223 LookupFlags ret = LookupFlags.None;
225 if ((rflags & LookupResultFlags.Multicast) > 0)
226 ret |= LookupFlags.UseMulticast;
227 if ((rflags & LookupResultFlags.WideArea) > 0)
228 ret |= LookupFlags.UseWideArea;