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