]> git.meshlink.io Git - catta/blob - avahi-sharp/ServiceResolver.cs
add the Id line, enable keyword expansion
[catta] / avahi-sharp / ServiceResolver.cs
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5
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.
10
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.
15
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
19   USA.
20 ***/
21
22 using System;
23 using System.Collections;
24 using System.Net;
25 using System.Runtime.InteropServices;
26 using Mono.Unix;
27
28 namespace Avahi
29 {
30
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, IntPtr userdata);
35
36     public class ServiceResolver : IDisposable
37     {
38         private IntPtr handle;
39         private ServiceInfo currentInfo;
40         private Client client;
41         private int iface;
42         private Protocol proto;
43         private string name;
44         private string type;
45         private string domain;
46         private Protocol aproto;
47
48         private ArrayList foundListeners = new ArrayList ();
49         private ArrayList timeoutListeners = new ArrayList ();
50         
51         [DllImport ("avahi-client")]
52         private static extern IntPtr avahi_service_resolver_new (IntPtr client, int iface, Protocol proto,
53                                                                  IntPtr name, IntPtr type, IntPtr domain,
54                                                                  Protocol aproto, ServiceResolverCallback cb,
55                                                                  IntPtr userdata);
56
57         [DllImport ("avahi-client")]
58         private static extern void avahi_service_resolver_free (IntPtr handle);
59
60         public event ServiceInfoHandler Found
61         {
62             add {
63                 foundListeners.Add (value);
64                 Start ();
65             }
66             remove {
67                 foundListeners.Remove (value);
68                 Stop (false);
69             }
70         }
71         
72         public event EventHandler Timeout
73         {
74             add {
75                 timeoutListeners.Add (value);
76                 Start ();
77             }
78             remove {
79                 timeoutListeners.Remove (value);
80                 Stop (false);
81             }
82         }
83
84         public ServiceInfo Service
85         {
86             get { return currentInfo; }
87         }
88
89         public ServiceResolver (Client client, string name, string type, string domain) : this (client, -1,
90                                                                                                 Protocol.Unspecified,
91                                                                                                 name, type, domain,
92                                                                                                 Protocol.Unspecified)
93         {
94         }
95
96         public ServiceResolver (Client client, ServiceInfo service) : this (client, service.NetworkInterface,
97                                                                             service.Protocol, service.Name,
98                                                                             service.ServiceType, service.Domain,
99                                                                             Protocol.Unspecified)
100         {
101         }
102         
103         public ServiceResolver (Client client, int iface, Protocol proto, string name,
104                                 string type, string domain, Protocol aproto)
105         {
106             this.client = client;
107             this.iface = iface;
108             this.proto = proto;
109             this.name = name;
110             this.type = type;
111             this.domain = domain;
112             this.aproto = aproto;
113             
114             
115         }
116
117         ~ServiceResolver ()
118         {
119             Dispose ();
120         }
121
122         public void Dispose ()
123         {
124             Stop (true);
125         }
126
127         private void Start ()
128         {
129             if (handle != IntPtr.Zero || (foundListeners.Count == 0 && timeoutListeners.Count == 0))
130                 return;
131
132             IntPtr namePtr = Utility.StringToPtr (name);
133             IntPtr typePtr = Utility.StringToPtr (type);
134             IntPtr domainPtr = Utility.StringToPtr (domain);
135             handle = avahi_service_resolver_new (client.Handle, iface, proto, namePtr, typePtr, domainPtr,
136                                                  aproto, OnServiceResolverCallback, IntPtr.Zero);
137             Utility.Free (namePtr);
138             Utility.Free (typePtr);
139             Utility.Free (domainPtr);
140         }
141
142         private void Stop (bool force)
143         {
144             if (handle != IntPtr.Zero && (force || (foundListeners.Count == 0 && timeoutListeners.Count == 0))) {
145                 avahi_service_resolver_free (handle);
146                 handle = IntPtr.Zero;
147             }
148         }
149
150         private void OnServiceResolverCallback (IntPtr resolver, int iface, Protocol proto,
151                                                 ResolverEvent revent, IntPtr name, IntPtr type,
152                                                 IntPtr domain, IntPtr host, IntPtr address,
153                                                 UInt16 port, IntPtr txt, IntPtr userdata)
154         {
155             ServiceInfo info;
156             info.NetworkInterface = iface;
157             info.Protocol = proto;
158             info.Domain = Utility.PtrToString (domain);
159             info.ServiceType = Utility.PtrToString (type);
160             info.Name = Utility.PtrToString (name);
161             info.Host = Utility.PtrToString (host);
162             info.Address = Utility.PtrToAddress (address);
163             info.Port = port;
164             info.Text = null;
165
166             if (revent == ResolverEvent.Found) {
167                 currentInfo = info;
168
169                 foreach (ServiceInfoHandler handler in foundListeners)
170                     handler (this, info);
171             } else {
172                 currentInfo = ServiceInfo.Zero;
173                 
174                 foreach (EventHandler handler in timeoutListeners)
175                     handler (this, new EventArgs ());
176             }
177         }
178     }
179 }