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