]> git.meshlink.io Git - catta/blob - avahi-sharp/ServiceResolver.cs
add initial mono bindings
[catta] / avahi-sharp / ServiceResolver.cs
1 using System;
2 using System.Collections;
3 using System.Net;
4 using System.Runtime.InteropServices;
5 using Mono.Unix;
6
7 namespace Avahi
8 {
9
10     internal delegate void ServiceResolverCallback (IntPtr resolver, int iface, Protocol proto,
11                                                     ResolverEvent revent, IntPtr name, IntPtr type,
12                                                     IntPtr domain, IntPtr host, IntPtr address,
13                                                     UInt16 port, IntPtr txt, IntPtr userdata);
14
15     public class ServiceResolver : IDisposable
16     {
17         private IntPtr handle;
18         private ServiceInfo currentInfo;
19         private Client client;
20         private int iface;
21         private Protocol proto;
22         private string name;
23         private string type;
24         private string domain;
25         private Protocol aproto;
26
27         private ArrayList foundListeners = new ArrayList ();
28         private ArrayList timeoutListeners = new ArrayList ();
29         
30         [DllImport ("avahi-client")]
31         private static extern IntPtr avahi_service_resolver_new (IntPtr client, int iface, Protocol proto,
32                                                                  IntPtr name, IntPtr type, IntPtr domain,
33                                                                  Protocol aproto, ServiceResolverCallback cb,
34                                                                  IntPtr userdata);
35
36         [DllImport ("avahi-client")]
37         private static extern void avahi_service_resolver_free (IntPtr handle);
38
39         public event ServiceInfoHandler Found
40         {
41             add {
42                 foundListeners.Add (value);
43                 Start ();
44             }
45             remove {
46                 foundListeners.Remove (value);
47                 Stop (false);
48             }
49         }
50         
51         public event EventHandler Timeout
52         {
53             add {
54                 timeoutListeners.Add (value);
55                 Start ();
56             }
57             remove {
58                 timeoutListeners.Remove (value);
59                 Stop (false);
60             }
61         }
62
63         public ServiceInfo Service
64         {
65             get { return currentInfo; }
66         }
67
68         public ServiceResolver (Client client, string name, string type, string domain) : this (client, -1,
69                                                                                                 Protocol.Unspecified,
70                                                                                                 name, type, domain,
71                                                                                                 Protocol.Unspecified)
72         {
73         }
74
75         public ServiceResolver (Client client, ServiceInfo service) : this (client, service.NetworkInterface,
76                                                                             service.Protocol, service.Name,
77                                                                             service.ServiceType, service.Domain,
78                                                                             Protocol.Unspecified)
79         {
80         }
81         
82         public ServiceResolver (Client client, int iface, Protocol proto, string name,
83                                 string type, string domain, Protocol aproto)
84         {
85             this.client = client;
86             this.iface = iface;
87             this.proto = proto;
88             this.name = name;
89             this.type = type;
90             this.domain = domain;
91             this.aproto = aproto;
92             
93             
94         }
95
96         ~ServiceResolver ()
97         {
98             Dispose ();
99         }
100
101         public void Dispose ()
102         {
103             Stop (true);
104         }
105
106         private void Start ()
107         {
108             if (handle != IntPtr.Zero || (foundListeners.Count == 0 && timeoutListeners.Count == 0))
109                 return;
110
111             IntPtr namePtr = Utility.StringToPtr (name);
112             IntPtr typePtr = Utility.StringToPtr (type);
113             IntPtr domainPtr = Utility.StringToPtr (domain);
114             handle = avahi_service_resolver_new (client.Handle, iface, proto, namePtr, typePtr, domainPtr,
115                                                  aproto, OnServiceResolverCallback, IntPtr.Zero);
116             Utility.Free (namePtr);
117             Utility.Free (typePtr);
118             Utility.Free (domainPtr);
119         }
120
121         private void Stop (bool force)
122         {
123             if (handle != IntPtr.Zero && (force || (foundListeners.Count == 0 && timeoutListeners.Count == 0))) {
124                 avahi_service_resolver_free (handle);
125                 handle = IntPtr.Zero;
126             }
127         }
128
129         private void OnServiceResolverCallback (IntPtr resolver, int iface, Protocol proto,
130                                                 ResolverEvent revent, IntPtr name, IntPtr type,
131                                                 IntPtr domain, IntPtr host, IntPtr address,
132                                                 UInt16 port, IntPtr txt, IntPtr userdata)
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 = Utility.PtrToString (host);
141             info.Address = Utility.PtrToAddress (address);
142             info.Port = port;
143             info.Text = null;
144
145             if (revent == ResolverEvent.Found) {
146                 currentInfo = info;
147
148                 foreach (ServiceInfoHandler handler in foundListeners)
149                     handler (this, info);
150             } else {
151                 currentInfo = ServiceInfo.Zero;
152                 
153                 foreach (EventHandler handler in timeoutListeners)
154                     handler (this, new EventArgs ());
155             }
156         }
157     }
158 }