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