]> git.meshlink.io Git - catta/blob - avahi-sharp/DomainBrowser.cs
a1165dcc638e58086d3a8aa2ddd901b2e4841474
[catta] / avahi-sharp / DomainBrowser.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.Collections;
22 using System.Runtime.InteropServices;
23 using System.Text;
24
25 namespace Avahi
26 {
27     internal delegate void DomainBrowserCallback (IntPtr browser, int iface, Protocol proto, BrowserEvent bevent,
28                                                   IntPtr domain, LookupResultFlags flags, IntPtr userdata);
29
30     public enum DomainBrowserType {
31         Browse,
32         BrowseDefault,
33         Register,
34         RegisterDefault,
35         BrowseLegacy
36     }
37
38     public struct DomainInfo
39     {
40         public int NetworkInterface;
41         public Protocol Protocol;
42         public string Domain;
43         public LookupResultFlags Flags;
44     }
45
46     public class DomainInfoArgs : EventArgs
47     {
48         private DomainInfo domain;
49
50         public DomainInfo Domain
51         {
52             get { return domain; }
53         }
54
55         public DomainInfoArgs (DomainInfo domain)
56         {
57             this.domain = domain;
58         }
59     }
60
61     public delegate void DomainInfoHandler (object o, DomainInfoArgs args);
62
63     public class DomainBrowser : BrowserBase, IDisposable
64     {
65         private IntPtr handle;
66         private ArrayList infos = new ArrayList ();
67         private Client client;
68         private int iface;
69         private Protocol proto;
70         private string domain;
71         private DomainBrowserType btype;
72         private LookupFlags flags;
73         private DomainBrowserCallback cb;
74
75         private ArrayList addListeners = new ArrayList ();
76         private ArrayList removeListeners = new ArrayList ();
77
78         [DllImport ("avahi-client")]
79         private static extern IntPtr avahi_domain_browser_new (IntPtr client, int iface, int proto,
80                                                                byte[] domain, int btype, LookupFlags flags,
81                                                                DomainBrowserCallback cb,
82                                                                IntPtr userdata);
83
84         [DllImport ("avahi-client")]
85         private static extern void avahi_domain_browser_free (IntPtr handle);
86
87         public event DomainInfoHandler DomainAdded
88         {
89             add {
90                 addListeners.Add (value);
91                 Start ();
92             }
93             remove {
94                 addListeners.Remove (value);
95                 Stop (false);
96             }
97         }
98
99         public event DomainInfoHandler DomainRemoved
100         {
101             add {
102                 removeListeners.Add (value);
103                 Start ();
104             }
105             remove {
106                 removeListeners.Remove (value);
107                 Stop (false);
108             }
109         }
110
111         public DomainInfo[] Domains
112         {
113             get { return (DomainInfo[]) infos.ToArray (typeof (DomainInfo)); }
114         }
115
116         public DomainBrowser (Client client) : this (client, -1, Protocol.Unspecified, client.DomainName,
117                                                      DomainBrowserType.Browse, LookupFlags.None) {
118         }
119
120         public DomainBrowser (Client client, int iface, Protocol proto, string domain,
121                               DomainBrowserType btype, LookupFlags flags)
122         {
123             this.client = client;
124             this.iface = iface;
125             this.proto = proto;
126             this.domain = domain;
127             this.btype = btype;
128             this.flags = flags;
129             cb = OnDomainBrowserCallback;
130         }
131
132         ~DomainBrowser ()
133         {
134             Dispose ();
135         }
136
137         public void Dispose ()
138         {
139             Stop (true);
140         }
141
142         private void Start ()
143         {
144             if (client.Handle == IntPtr.Zero && handle != IntPtr.Zero ||
145                 (addListeners.Count == 0 && removeListeners.Count == 0))
146                 return;
147
148             lock (client) {
149                 handle = avahi_domain_browser_new (client.Handle, iface, (int) proto,
150                                                    Utility.StringToBytes (domain), (int) btype, flags,
151                                                    cb, IntPtr.Zero);
152
153                 if (handle == IntPtr.Zero)
154                     client.ThrowError ();
155             }
156         }
157
158         private void Stop (bool force)
159         {
160             if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero &&
161                 (force || (addListeners.Count == 0 && removeListeners.Count == 0))) {
162                 lock (client) {
163                     avahi_domain_browser_free (handle);
164                     handle = IntPtr.Zero;
165                 }
166             }
167         }
168
169         private void OnDomainBrowserCallback (IntPtr browser, int iface, Protocol proto, BrowserEvent bevent,
170                                               IntPtr domain, LookupResultFlags flags, IntPtr userdata)
171         {
172
173             DomainInfo info;
174             info.NetworkInterface = iface;
175             info.Protocol = proto;
176             info.Domain = Utility.PtrToString (domain);
177             info.Flags = flags;
178
179             switch (bevent) {
180             case BrowserEvent.Added:
181                 infos.Add (info);
182
183                 foreach (DomainInfoHandler handler in addListeners)
184                     handler (this, new DomainInfoArgs (info));
185                 break;
186             case BrowserEvent.Removed:
187                 infos.Remove (info);
188
189                 foreach (DomainInfoHandler handler in removeListeners)
190                     handler (this, new DomainInfoArgs (info));
191                 break;
192             default:
193                 EmitBrowserEvent (bevent);
194                 break;
195             }
196         }
197     }
198 }