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 { DomainBrowserCallback(IntPtr browser, int iface, Protocol proto, BrowserEvent bevent, IntPtr domain, LookupResultFlags flags, IntPtr userdata)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 DomainInfoArgs(DomainInfo domain)55 public DomainInfoArgs (DomainInfo domain) 56 { 57 this.domain = domain; 58 } 59 } 60 DomainInfoHandler(object o, DomainInfoArgs args)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")] avahi_domain_browser_new(IntPtr client, int iface, int proto, byte[] domain, int btype, LookupFlags flags, DomainBrowserCallback cb, IntPtr userdata)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")] avahi_domain_browser_free(IntPtr handle)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 DomainBrowser(Client client)116 public DomainBrowser (Client client) : this (client, -1, Protocol.Unspecified, client.DomainName, 117 DomainBrowserType.Browse, LookupFlags.None) { 118 } 119 DomainBrowser(Client client, int iface, Protocol proto, string domain, DomainBrowserType btype, LookupFlags flags)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 ~DomainBrowser()132 ~DomainBrowser () 133 { 134 Dispose (); 135 } 136 Dispose()137 public void Dispose () 138 { 139 Stop (true); 140 } 141 Start()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 Stop(bool force)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 OnDomainBrowserCallback(IntPtr browser, int iface, Protocol proto, BrowserEvent bevent, IntPtr domain, LookupResultFlags flags, IntPtr userdata)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 } 199