]> git.meshlink.io Git - catta/blob - avahi-sharp/EntryGroup.cs
02be643676bebbddcfc8c75e2fa299b090795fe0
[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;
240
241             lock (client) {
242                 ret = avahi_entry_group_add_service_strlst (handle, iface, proto, flags,
243                                                             Utility.StringToBytes (name),
244                                                             Utility.StringToBytes (type),
245                                                             Utility.StringToBytes (domain),
246                                                             Utility.StringToBytes (host), port, list);
247             }
248             
249             avahi_string_list_free (list);
250             
251             if (ret < 0) {
252                 client.ThrowError ();
253             }
254         }
255
256         public void UpdateService (string name, string type, string domain, params string[] txt)
257         {
258             UpdateService (-1, Protocol.Unspecified, PublishFlags.None, name, type, domain, txt);
259         }
260
261         public void UpdateService (int iface, Protocol proto, PublishFlags flags, string name, string type,
262                                    string domain, params string[] txt)
263         {
264             IntPtr list = avahi_string_list_new (IntPtr.Zero);
265
266             if (txt != null) {
267                 foreach (string item in txt) {
268                     list = avahi_string_list_add (list, Utility.StringToBytes (item));
269                 }
270             }
271
272             UpdateService (iface, proto, flags, name, type, domain, list);
273         }
274
275         public void UpdateService (int iface, Protocol proto, PublishFlags flags, string name, string type,
276                                    string domain, params byte[][] txt)
277         {
278             IntPtr list = avahi_string_list_new (IntPtr.Zero);
279
280             if (txt != null) {
281                 foreach (byte[] item in txt) {
282                     list = avahi_string_list_add (list, item);
283                 }
284             }
285
286             UpdateService (iface, proto, flags, name, type, domain, list);
287         }
288         
289         private void UpdateService (int iface, Protocol proto, PublishFlags flags, string name, string type,
290                                     string domain, IntPtr list)
291         {
292             lock (client) {
293                 int ret = avahi_entry_group_update_service_strlst (handle, iface, proto, flags,
294                                                                    Utility.StringToBytes (name),
295                                                                    Utility.StringToBytes (type),
296                                                                    Utility.StringToBytes (domain),
297                                                                    list);
298
299                 avahi_string_list_free (list);
300
301                 if (ret < 0) {
302                     client.ThrowError ();
303                 }
304             }
305         }
306
307         public void AddServiceSubtype (string name, string type, string domain, string subtype)
308         {
309             AddServiceSubtype (-1, Protocol.Unspecified, PublishFlags.None, name, type, domain, subtype);
310         }
311
312         public void AddServiceSubtype (int iface, Protocol proto, PublishFlags flags, string name,
313                                        string type, string domain, string subtype)
314         {
315             lock (client) {
316                 int ret = avahi_entry_group_add_service_subtype (handle, iface, proto, flags,
317                                                                  Utility.StringToBytes (name),
318                                                                  Utility.StringToBytes (type),
319                                                                  Utility.StringToBytes (domain),
320                                                                  Utility.StringToBytes (subtype));
321
322                 if (ret < 0) {
323                     client.ThrowError ();
324                 }
325             }
326         }
327
328         public void AddAddress (string name, IPAddress address)
329         {
330             AddAddress (-1, Protocol.Unspecified, PublishFlags.None, name, address);
331         }
332
333         public void AddAddress (int iface, Protocol proto, PublishFlags flags, string name, IPAddress address)
334         {
335             IntPtr addressPtr = Utility.AddressToPtr (address);
336
337             lock (client) {
338                 int ret = avahi_entry_group_add_address (handle, iface, proto, flags,
339                                                          Utility.StringToBytes (name), addressPtr);
340
341                 Utility.Free (addressPtr);
342
343                 if (ret < 0) {
344                     client.ThrowError ();
345                 }
346             }
347         }
348
349         public void AddRecord (string name, RecordClass clazz, RecordType type, uint ttl, byte[] rdata, int length)
350         {
351             AddRecord (-1, Protocol.Unspecified, PublishFlags.None, name, clazz, type, ttl, rdata, length);
352         }
353
354         public void AddRecord (int iface, Protocol proto, PublishFlags flags, string name,
355                                RecordClass clazz, RecordType type, uint ttl, byte[] rdata, int length)
356         {
357             lock (client) {
358                 int ret = avahi_entry_group_add_record (handle, iface, proto, flags,
359                                                         Utility.StringToBytes (name),
360                                                         clazz, type, ttl, rdata, length);
361
362                 if (ret < 0) {
363                     client.ThrowError ();
364                 }
365             }
366         }
367
368         public static string GetAlternativeServiceName (string name) {
369             return Utility.PtrToStringFree (avahi_alternative_service_name (Utility.StringToBytes (name)));
370         }
371
372         private void OnEntryGroupCallback (IntPtr group, EntryGroupState state, IntPtr userdata)
373         {
374             if (StateChanged != null)
375                 StateChanged (this, new EntryGroupStateArgs (state));
376         }
377     }
378 }