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