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