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