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