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