]> git.meshlink.io Git - catta/blob - avahi-sharp/EntryGroup.cs
make stuff work with mono older than 1.1.13
[catta] / avahi-sharp / EntryGroup.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.Net;
24 using System.Runtime.InteropServices;
25 using System.Text;
26 using Mono.Unix;
27
28 namespace Avahi
29 {
30
31     [Flags]
32     public enum PublishFlags {
33         None = 0,
34         Unique = 1,
35         NoProbe = 2,
36         NoAnnounce = 4,
37         AllowMultiple = 8,
38         NoReverse = 16,
39         NoCookie = 32,
40         Update = 64,
41         UseWideArea = 128,
42         UseMulticast = 256
43     }
44     
45     public enum EntryGroupState {
46         Uncommited,
47         Registering,
48         Established,
49         Collision,
50         Failure
51     }
52
53     public class EntryGroupStateArgs : EventArgs
54     {
55         private EntryGroupState state;
56
57         public EntryGroupState State
58         {
59             get { return state; }
60         }
61         
62         public EntryGroupStateArgs (EntryGroupState state)
63         {
64             this.state = state;
65         }
66     }
67
68     internal delegate void EntryGroupCallback (IntPtr group, EntryGroupState state, IntPtr userdata);
69     public delegate void EntryGroupStateHandler (object o, EntryGroupStateArgs args);
70     
71     public class EntryGroup : IDisposable
72     {
73         private Client client;
74         private IntPtr handle;
75         private EntryGroupCallback cb;
76         
77         [DllImport ("avahi-client")]
78         private static extern IntPtr avahi_entry_group_new (IntPtr client, EntryGroupCallback cb, IntPtr userdata);
79
80         [DllImport ("avahi-client")]
81         private static extern int avahi_entry_group_commit (IntPtr group);
82
83         [DllImport ("avahi-client")]
84         private static extern int avahi_entry_group_reset (IntPtr group);
85
86         [DllImport ("avahi-client")]
87         private static extern EntryGroupState avahi_entry_group_get_state (IntPtr group);
88
89         [DllImport ("avahi-client")]
90         private static extern bool avahi_entry_group_is_empty (IntPtr group);
91
92         [DllImport ("avahi-client")]
93         private static extern int avahi_entry_group_add_service_strlst (IntPtr group, int iface, Protocol proto,
94                                                                         PublishFlags flags, byte[] name, byte[] type,
95                                                                         byte[] domain, byte[] host, UInt16 port,
96                                                                         IntPtr strlst);
97
98         [DllImport ("avahi-client")]
99         private static extern int avahi_entry_group_update_service_strlst (IntPtr group, int iface, Protocol proto,
100                                                                            PublishFlags flags, byte[] name,
101                                                                            byte[] type, byte[] domain, IntPtr strlst);
102
103         [DllImport ("avahi-client")]
104         private static extern int avahi_entry_group_add_service_subtype (IntPtr group, int iface, Protocol proto,
105                                                                          PublishFlags flags, byte[] name, byte[] type,
106                                                                          byte[] domain, byte[] subtype);
107
108         [DllImport ("avahi-client")]
109         private static extern int avahi_entry_group_add_address (IntPtr group, int iface, Protocol proto,
110                                                                  PublishFlags flags, byte[] name, IntPtr address);
111
112
113         [DllImport ("avahi-client")]
114         private static extern int avahi_entry_group_add_record (IntPtr group, int iface, Protocol proto,
115                                                                 PublishFlags flags, byte[] name, RecordClass clazz,
116                                                                 RecordType type, uint ttl, byte[] rdata, int size);
117         
118         [DllImport ("avahi-client")]
119         private static extern void avahi_entry_group_free (IntPtr group);
120
121         [DllImport ("avahi-common")]
122         private static extern IntPtr avahi_string_list_new (IntPtr txt);
123
124         [DllImport ("avahi-common")]
125         private static extern IntPtr avahi_string_list_add (IntPtr list, byte[] txt);
126
127         [DllImport ("avahi-common")]
128         private static extern void avahi_string_list_free (IntPtr list);
129
130         [DllImport ("avahi-common")]
131         private static extern IntPtr avahi_alternative_service_name (byte[] name);
132
133         public event EntryGroupStateHandler StateChanged;
134         
135         public EntryGroupState State
136         {
137             get {
138                 lock (client) {
139                     return avahi_entry_group_get_state (handle);
140                 }
141             }
142         }
143
144         public bool IsEmpty
145         {
146             get {
147                 lock (client) {
148                     return avahi_entry_group_is_empty (handle);
149                 }
150             }
151         }
152         
153         public EntryGroup (Client client)
154         {
155             this.client = client;
156             cb = OnEntryGroupCallback;
157
158             lock (client) {
159                 handle = avahi_entry_group_new (client.Handle, cb, IntPtr.Zero);
160                 if (handle == IntPtr.Zero)
161                     client.ThrowError ();
162             }
163         }
164
165         ~EntryGroup ()
166         {
167             Dispose ();
168         }
169
170         public void Dispose ()
171         {
172             if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero) {
173                 lock (client) {
174                     avahi_entry_group_free (handle);
175                     handle = IntPtr.Zero;
176                 }
177             }
178         }
179
180         public void Commit ()
181         {
182             lock (client) {
183                 if (avahi_entry_group_commit (handle) < 0)
184                     client.ThrowError ();
185             }
186         }
187
188         public void Reset ()
189         {
190             lock (client) {
191                 if (avahi_entry_group_reset (handle) < 0)
192                     client.ThrowError ();
193             }
194         }
195
196         public void AddService (string name, string type, string domain,
197                                 UInt16 port, params string[] txt)
198         {
199             AddService (PublishFlags.None, name, type, domain, port, txt);
200         }
201
202         public void AddService (PublishFlags flags, string name, string type, string domain,
203                                 UInt16 port, params string[] txt)
204         {
205             AddService (-1, Protocol.Unspecified, flags, name, type, domain, null, port, txt);
206         }
207
208         public void AddService (int iface, Protocol proto, PublishFlags flags, string name, string type, string domain,
209                                 string host, UInt16 port, params string[] txt)
210         {
211             IntPtr list = avahi_string_list_new (IntPtr.Zero);
212
213             if (txt != null) {
214                 foreach (string item in txt) {
215                     list = avahi_string_list_add (list, Utility.StringToBytes (item));
216                 }
217             }
218
219             AddService (iface, proto, flags, name, type, domain, host, port, list);
220         }
221
222         public void AddService (int iface, Protocol proto, PublishFlags flags, string name, string type, string domain,
223                                 string host, UInt16 port, params byte[][] txt)
224         {
225             IntPtr list = avahi_string_list_new (IntPtr.Zero);
226
227             if (txt != null) {
228                 foreach (byte[] item in txt) {
229                     list = avahi_string_list_add (list, item);
230                 }
231             }
232
233             AddService (iface, proto, flags, name, type, domain, host, port, list);
234         }
235
236         private void AddService (int iface, Protocol proto, PublishFlags flags, string name, string type,
237                                  string domain, string host, UInt16 port, IntPtr list)
238         {
239             int ret = avahi_entry_group_add_service_strlst (handle, iface, proto, flags,
240                                                             Utility.StringToBytes (name),
241                                                             Utility.StringToBytes (type),
242                                                             Utility.StringToBytes (domain),
243                                                             Utility.StringToBytes (host), port, list);
244             
245             avahi_string_list_free (list);
246             
247             if (ret < 0) {
248                 client.ThrowError ();
249             }
250         }
251
252         public void UpdateService (string name, string type, string domain, params string[] txt)
253         {
254             UpdateService (-1, Protocol.Unspecified, PublishFlags.None, name, type, domain, txt);
255         }
256
257         public void UpdateService (int iface, Protocol proto, PublishFlags flags, string name, string type,
258                                    string domain, params string[] txt)
259         {
260             IntPtr list = avahi_string_list_new (IntPtr.Zero);
261
262             if (txt != null) {
263                 foreach (string item in txt) {
264                     list = avahi_string_list_add (list, Utility.StringToBytes (item));
265                 }
266             }
267
268             UpdateService (iface, proto, flags, name, type, domain, list);
269         }
270
271         public void UpdateService (int iface, Protocol proto, PublishFlags flags, string name, string type,
272                                    string domain, params byte[][] txt)
273         {
274             IntPtr list = avahi_string_list_new (IntPtr.Zero);
275
276             if (txt != null) {
277                 foreach (byte[] item in txt) {
278                     list = avahi_string_list_add (list, item);
279                 }
280             }
281
282             UpdateService (iface, proto, flags, name, type, domain, list);
283         }
284         
285         private void UpdateService (int iface, Protocol proto, PublishFlags flags, string name, string type,
286                                     string domain, IntPtr list)
287         {
288             lock (client) {
289                 int ret = avahi_entry_group_update_service_strlst (handle, iface, proto, flags,
290                                                                    Utility.StringToBytes (name),
291                                                                    Utility.StringToBytes (type),
292                                                                    Utility.StringToBytes (domain),
293                                                                    list);
294
295                 avahi_string_list_free (list);
296
297                 if (ret < 0) {
298                     client.ThrowError ();
299                 }
300             }
301         }
302
303         public void AddServiceSubtype (string name, string type, string domain, string subtype)
304         {
305             AddServiceSubtype (-1, Protocol.Unspecified, PublishFlags.None, name, type, domain, subtype);
306         }
307
308         public void AddServiceSubtype (int iface, Protocol proto, PublishFlags flags, string name,
309                                        string type, string domain, string subtype)
310         {
311             lock (client) {
312                 int ret = avahi_entry_group_add_service_subtype (handle, iface, proto, flags,
313                                                                  Utility.StringToBytes (name),
314                                                                  Utility.StringToBytes (type),
315                                                                  Utility.StringToBytes (domain),
316                                                                  Utility.StringToBytes (subtype));
317
318                 if (ret < 0) {
319                     client.ThrowError ();
320                 }
321             }
322         }
323
324         public void AddAddress (string name, IPAddress address)
325         {
326             AddAddress (-1, Protocol.Unspecified, PublishFlags.None, name, address);
327         }
328
329         public void AddAddress (int iface, Protocol proto, PublishFlags flags, string name, IPAddress address)
330         {
331             IntPtr addressPtr = Utility.AddressToPtr (address);
332
333             lock (client) {
334                 int ret = avahi_entry_group_add_address (handle, iface, proto, flags,
335                                                          Utility.StringToBytes (name), addressPtr);
336
337                 Utility.Free (addressPtr);
338
339                 if (ret < 0) {
340                     client.ThrowError ();
341                 }
342             }
343         }
344
345         public void AddRecord (string name, RecordClass clazz, RecordType type, uint ttl, byte[] rdata, int length)
346         {
347             AddRecord (-1, Protocol.Unspecified, PublishFlags.None, name, clazz, type, ttl, rdata, length);
348         }
349
350         public void AddRecord (int iface, Protocol proto, PublishFlags flags, string name,
351                                RecordClass clazz, RecordType type, uint ttl, byte[] rdata, int length)
352         {
353             lock (client) {
354                 int ret = avahi_entry_group_add_record (handle, iface, proto, flags,
355                                                         Utility.StringToBytes (name),
356                                                         clazz, type, ttl, rdata, length);
357
358                 if (ret < 0) {
359                     client.ThrowError ();
360                 }
361             }
362         }
363
364         public static string GetAlternativeServiceName (string name) {
365             return Utility.PtrToStringFree (avahi_alternative_service_name (Utility.StringToBytes (name)));
366         }
367
368         private void OnEntryGroupCallback (IntPtr group, EntryGroupState state, IntPtr userdata)
369         {
370             if (StateChanged != null)
371                 StateChanged (this, new EntryGroupStateArgs (state));
372         }
373     }
374 }