]> git.meshlink.io Git - catta/blob - avahi-sharp/Client.cs
* Add RecordBrowser.cs
[catta] / avahi-sharp / Client.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
23 using System;
24 using System.Threading;
25 using System.Collections;
26 using System.Runtime.InteropServices;
27
28 namespace Avahi
29 {
30     internal enum ResolverEvent {
31         Found,
32         Failure
33     }
34     
35     internal enum BrowserEvent {
36         Added,
37         Removed,
38         CacheExhausted,
39         AllForNow,
40         Failure
41     }
42
43     internal delegate int PollCallback (IntPtr ufds, uint nfds, int timeout);
44     internal delegate void ClientCallback (IntPtr client, ClientState state, IntPtr userData);
45
46     public delegate void ClientStateHandler (object o, ClientStateArgs state);
47
48     public class ClientStateArgs : EventArgs
49     {
50         private ClientState state;
51
52         public ClientState State
53         {
54             get { return state; }
55         }
56
57         public ClientStateArgs (ClientState state)
58         {
59             this.state = state;
60         }
61     }
62     
63     public enum Protocol {
64         Unspecified = -1,
65         IPv4 = 0,
66         IPv6 = 1
67     }
68
69     internal enum ServerState {
70         Invalid,
71         Registering,
72         Running,
73         Collision
74     }
75     
76     public enum ClientState {
77         Registering = ServerState.Registering,
78         Running = ServerState.Running,
79         Collision = ServerState.Collision,
80         Failure = 100,
81         Connecting = 101
82     }
83
84     [Flags]
85     public enum LookupFlags {
86         None = 0,
87         UseWideArea = 1,
88         UseMulticast = 4,
89         NoAddress = 8
90     }
91
92     [Flags]
93     public enum LookupResultFlags {
94         None = 0,
95         Cached = 1,
96         WideArea = 2,
97         Multicast = 4,
98         Local = 8,
99         OurOwn = 16,
100     }
101
102     [Flags]
103     public enum ClientFlags {
104         None = 0,
105         IgnoreUserConfig = 1,
106         NoFail = 2
107     }
108     
109     public class Client : IDisposable
110     {
111         private IntPtr handle;
112         private ClientCallback cb;
113         private PollCallback pollcb;
114         private IntPtr spoll;
115
116         private Thread thread;
117
118         [DllImport ("avahi-client")]
119         private static extern IntPtr avahi_client_new (IntPtr poll, ClientFlags flags, ClientCallback handler,
120                                                        IntPtr userData, out int error);
121
122         [DllImport ("avahi-client")]
123         private static extern void avahi_client_free (IntPtr handle);
124
125         [DllImport ("avahi-client")]
126         private static extern IntPtr avahi_client_get_version_string (IntPtr handle);
127
128         [DllImport ("avahi-client")]
129         private static extern IntPtr avahi_client_get_host_name (IntPtr handle);
130
131         [DllImport ("avahi-client")]
132         private static extern IntPtr avahi_client_get_domain_name (IntPtr handle);
133
134         [DllImport ("avahi-client")]
135         private static extern IntPtr avahi_client_get_host_name_fqdn (IntPtr handle);
136
137         [DllImport ("avahi-client")]
138         private static extern ClientState avahi_client_get_state (IntPtr handle);
139
140         [DllImport ("avahi-client")]
141         private static extern int avahi_client_errno (IntPtr handle);
142         
143         [DllImport ("avahi-common")]
144         private static extern IntPtr avahi_simple_poll_new ();
145
146         [DllImport ("avahi-common")]
147         private static extern IntPtr avahi_simple_poll_get (IntPtr spoll);
148
149         [DllImport ("avahi-common")]
150         private static extern void avahi_simple_poll_free (IntPtr spoll);
151
152         [DllImport ("avahi-common")]
153         private static extern int avahi_simple_poll_loop (IntPtr spoll);
154
155         [DllImport ("avahi-common")]
156         private static extern void avahi_simple_poll_set_func (IntPtr spoll, PollCallback cb);
157
158         [DllImport ("avahi-common")]
159         private static extern void avahi_simple_poll_quit (IntPtr spoll);
160
161         [DllImport ("avahi-client")]
162         private static extern uint avahi_client_get_local_service_cookie (IntPtr client);
163
164
165         [DllImport ("libc")]
166         private static extern int poll(IntPtr ufds, uint nfds, int timeout);
167
168         public event ClientStateHandler StateChanged;
169
170         internal IntPtr Handle
171         {
172             get { return handle; }
173         }
174         
175         public string Version
176         {
177             get {
178                 lock (this) {
179                     return Utility.PtrToString (avahi_client_get_version_string (handle));
180                 }
181             }
182         }
183
184         public string HostName
185         {
186             get {
187                 lock (this) {
188                     return Utility.PtrToString (avahi_client_get_host_name (handle));
189                 }
190             }
191         }
192
193         public string DomainName
194         {
195             get {
196                 lock (this) {
197                     return Utility.PtrToString (avahi_client_get_domain_name (handle));
198                 }
199             }
200         }
201
202         public string HostNameFqdn
203         {
204             get {
205                 lock (this) {
206                     return Utility.PtrToString (avahi_client_get_host_name_fqdn (handle));
207                 }
208             }
209         }
210
211         public ClientState State
212         {
213             get {
214                 lock (this) {
215                     return (ClientState) avahi_client_get_state (handle);
216                 }
217             }
218         }
219
220         public uint LocalServiceCookie
221         {
222             get {
223                 lock (this) {
224                     return avahi_client_get_local_service_cookie (handle);
225                 }
226             }
227         }
228
229         internal ErrorCode LastError
230         {
231             get {
232                 lock (this) {
233                     return (ErrorCode) avahi_client_errno (handle);
234                 }
235             }
236         }
237
238         public Client (ClientFlags flags)
239         {
240             spoll = avahi_simple_poll_new ();
241
242             pollcb = OnPollCallback;
243             avahi_simple_poll_set_func (spoll, pollcb);
244             IntPtr poll = avahi_simple_poll_get (spoll);
245             cb = OnClientCallback;
246
247             int error;
248             handle = avahi_client_new (poll, flags, cb, IntPtr.Zero, out error);
249             if (error != 0)
250                 throw new ClientException (error);
251
252             thread = new Thread (PollLoop);
253             thread.IsBackground = true;
254             thread.Start ();
255         }
256
257         public Client () : this (ClientFlags.None) {
258         }
259
260         ~Client ()
261         {
262             Dispose ();
263         }
264
265         public void Dispose ()
266         {
267             if (handle != IntPtr.Zero) {
268                 avahi_client_free (handle);
269                 avahi_simple_poll_quit (spoll);
270                 avahi_simple_poll_free (spoll);
271                 handle = IntPtr.Zero;
272             }
273         }
274
275         internal void ThrowError ()
276         {
277             ErrorCode error = LastError;
278
279             if (error != ErrorCode.Ok)
280                 throw new ClientException (error);
281         }
282         
283         private void OnClientCallback (IntPtr client, ClientState state, IntPtr userData)
284         {
285             if (StateChanged != null)
286                 StateChanged (this, new ClientStateArgs (state));
287         }
288
289         private int OnPollCallback (IntPtr ufds, uint nfds, int timeout) {
290             Monitor.Exit (this);
291             int result = poll (ufds, nfds, timeout);
292             Monitor.Enter (this);
293             return result;
294         }
295
296         private void PollLoop () {
297             try {
298                 lock (this) {
299                     avahi_simple_poll_loop (spoll);
300                 }
301             } catch (Exception e) {
302                 Console.Error.WriteLine ("Error in avahi-sharp event loop: " + e);
303             }
304         }
305     }
306 }