Mono.Zeroconf – Diff between revs 1 and 2
?pathlinks?
Rev 1 | Rev 2 | |||
---|---|---|---|---|
1 | // |
1 | // |
|
2 | // RegisterService.cs |
2 | // RegisterService.cs |
|
3 | // |
3 | // |
|
4 | // Authors: |
4 | // Authors: |
|
5 | // Aaron Bockover <abockover@novell.com> |
5 | // Aaron Bockover <abockover@novell.com> |
|
6 | // |
6 | // |
|
7 | // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) |
7 | // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) |
|
8 | // |
8 | // |
|
9 | // Permission is hereby granted, free of charge, to any person obtaining |
9 | // Permission is hereby granted, free of charge, to any person obtaining |
|
10 | // a copy of this software and associated documentation files (the |
10 | // a copy of this software and associated documentation files (the |
|
11 | // "Software"), to deal in the Software without restriction, including |
11 | // "Software"), to deal in the Software without restriction, including |
|
12 | // without limitation the rights to use, copy, modify, merge, publish, |
12 | // without limitation the rights to use, copy, modify, merge, publish, |
|
13 | // distribute, sublicense, and/or sell copies of the Software, and to |
13 | // distribute, sublicense, and/or sell copies of the Software, and to |
|
14 | // permit persons to whom the Software is furnished to do so, subject to |
14 | // permit persons to whom the Software is furnished to do so, subject to |
|
15 | // the following conditions: |
15 | // the following conditions: |
|
16 | // |
16 | // |
|
17 | // The above copyright notice and this permission notice shall be |
17 | // The above copyright notice and this permission notice shall be |
|
18 | // included in all copies or substantial portions of the Software. |
18 | // included in all copies or substantial portions of the Software. |
|
19 | // |
19 | // |
|
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|
24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
27 | // |
27 | // |
|
28 | |
28 | |
|
29 | using System; |
29 | using System; |
|
30 | using System.Net; |
30 | using System.Net; |
|
31 | using System.Threading; |
31 | using System.Threading; |
|
32 | using System.Runtime.InteropServices; |
32 | using System.Runtime.InteropServices; |
|
- | 33 | using System.Text; |
||
33 | |
34 | |
|
34 | namespace Mono.Zeroconf.Providers.Bonjour |
35 | namespace Mono.Zeroconf.Providers.Bonjour |
|
35 | { |
36 | { |
|
36 | public sealed class RegisterService : Service, IRegisterService, IDisposable |
37 | public sealed class RegisterService : Service, IRegisterService, IDisposable |
|
37 | { |
38 | { |
|
38 | private Thread thread; |
39 | private Thread thread; |
|
39 | private ServiceRef sd_ref; |
40 | private ServiceRef sd_ref; |
|
40 | private bool auto_rename = true; |
41 | private bool auto_rename = true; |
|
41 | |
42 | |
|
42 | private Native.DNSServiceRegisterReply register_reply_handler; |
43 | private Native.DNSServiceRegisterReply register_reply_handler; |
|
43 | |
44 | |
|
44 | public event RegisterServiceEventHandler Response; |
45 | public event RegisterServiceEventHandler Response; |
|
45 | |
46 | |
|
46 | public RegisterService() |
47 | public RegisterService() |
|
47 | { |
48 | { |
|
48 | SetupCallback(); |
49 | SetupCallback(); |
|
49 | } |
50 | } |
|
50 | |
51 | |
|
51 | public RegisterService(string name, string replyDomain, string regtype) : base(name, replyDomain, regtype) |
52 | public RegisterService(string name, string replyDomain, string regtype) : base(name, replyDomain, regtype) |
|
52 | { |
53 | { |
|
53 | SetupCallback(); |
54 | SetupCallback(); |
|
54 | } |
55 | } |
|
55 | |
56 | |
|
56 | private void SetupCallback() |
57 | private void SetupCallback() |
|
57 | { |
58 | { |
|
58 | register_reply_handler = new Native.DNSServiceRegisterReply(OnRegisterReply); |
59 | register_reply_handler = new Native.DNSServiceRegisterReply(OnRegisterReply); |
|
59 | } |
60 | } |
|
60 | |
61 | |
|
61 | public void Register() |
62 | public void Register() |
|
62 | { |
63 | { |
|
63 | Register(true); |
64 | Register(true); |
|
64 | } |
65 | } |
|
65 | |
66 | |
|
66 | public void Register(bool @async) |
67 | public void Register(bool @async) |
|
67 | { |
68 | { |
|
68 | if(thread != null) { |
69 | if(thread != null) { |
|
69 | throw new InvalidOperationException("RegisterService registration already in process"); |
70 | throw new InvalidOperationException("RegisterService registration already in process"); |
|
70 | } |
71 | } |
|
71 | |
72 | |
|
72 | if(@async) { |
73 | if(@async) { |
|
73 | thread = new Thread(new ThreadStart(ThreadedRegister)); |
74 | thread = new Thread(new ThreadStart(ThreadedRegister)); |
|
74 | thread.IsBackground = true; |
75 | thread.IsBackground = true; |
|
75 | thread.Start(); |
76 | thread.Start(); |
|
76 | } else { |
77 | } else { |
|
77 | ProcessRegister(); |
78 | ProcessRegister(); |
|
78 | } |
79 | } |
|
79 | } |
80 | } |
|
80 | |
81 | |
|
81 | public void RegisterSync() |
82 | public void RegisterSync() |
|
82 | { |
83 | { |
|
83 | Register(false); |
84 | Register(false); |
|
84 | } |
85 | } |
|
85 | |
86 | |
|
86 | private void ThreadedRegister() |
87 | private void ThreadedRegister() |
|
87 | { |
88 | { |
|
88 | try { |
89 | try { |
|
89 | ProcessRegister(); |
90 | ProcessRegister(); |
|
90 | } catch(ThreadAbortException) { |
91 | } catch(ThreadAbortException) { |
|
91 | Thread.ResetAbort(); |
92 | Thread.ResetAbort(); |
|
92 | } |
93 | } |
|
93 | |
94 | |
|
94 | thread = null; |
95 | thread = null; |
|
95 | } |
96 | } |
|
96 | |
97 | |
|
97 | public void ProcessRegister() |
98 | public void ProcessRegister() |
|
98 | { |
99 | { |
|
99 | ushort txt_rec_length = 0; |
100 | ushort txt_rec_length = 0; |
|
100 | byte [] txt_rec = null; |
101 | byte [] txt_rec = null; |
|
101 | |
102 | |
|
102 | if(TxtRecord != null) { |
103 | if(TxtRecord != null) { |
|
103 | txt_rec_length = ((TxtRecord)TxtRecord.BaseRecord).RawLength; |
104 | txt_rec_length = ((TxtRecord)TxtRecord.BaseRecord).RawLength; |
|
104 | txt_rec = new byte[txt_rec_length]; |
105 | txt_rec = new byte[txt_rec_length]; |
|
105 | Marshal.Copy(((TxtRecord)TxtRecord.BaseRecord).RawBytes, txt_rec, 0, txt_rec_length); |
106 | Marshal.Copy(((TxtRecord)TxtRecord.BaseRecord).RawBytes, txt_rec, 0, txt_rec_length); |
|
106 | } |
107 | } |
|
107 | |
108 | |
|
108 | ServiceError error = Native.DNSServiceRegister(out sd_ref, |
109 | ServiceError error = Native.DNSServiceRegister(out sd_ref, |
|
109 | auto_rename ? ServiceFlags.None : ServiceFlags.NoAutoRename, InterfaceIndex, |
110 | auto_rename ? ServiceFlags.None : ServiceFlags.NoAutoRename, InterfaceIndex, |
|
110 | Name, RegType, ReplyDomain, HostTarget, (ushort)IPAddress.HostToNetworkOrder((short)port), txt_rec_length, txt_rec, |
111 | Encoding.UTF8.GetBytes(Name), RegType, ReplyDomain, HostTarget, (ushort)IPAddress.HostToNetworkOrder((short)port), txt_rec_length, txt_rec, |
|
111 | register_reply_handler, IntPtr.Zero); |
112 | register_reply_handler, IntPtr.Zero); |
|
112 | |
113 | |
|
113 | if(error != ServiceError.NoError) { |
114 | if(error != ServiceError.NoError) { |
|
114 | throw new ServiceErrorException(error); |
115 | throw new ServiceErrorException(error); |
|
115 | } |
116 | } |
|
116 | |
117 | |
|
117 | sd_ref.Process(); |
118 | sd_ref.Process(); |
|
118 | } |
119 | } |
|
119 | |
120 | |
|
120 | public void Dispose() |
121 | public void Dispose() |
|
121 | { |
122 | { |
|
122 | if(thread != null) { |
123 | if(thread != null) { |
|
123 | thread.Abort(); |
124 | thread.Abort(); |
|
124 | thread = null; |
125 | thread = null; |
|
125 | } |
126 | } |
|
126 | |
127 | |
|
127 | sd_ref.Deallocate(); |
128 | sd_ref.Deallocate(); |
|
128 | } |
129 | } |
|
129 | |
130 | |
|
130 | private void OnRegisterReply(ServiceRef sdRef, ServiceFlags flags, ServiceError errorCode, |
131 | private void OnRegisterReply(ServiceRef sdRef, ServiceFlags flags, ServiceError errorCode, |
|
131 | string name, string regtype, string domain, IntPtr context) |
132 | IntPtr name, string regtype, string domain, IntPtr context) |
|
132 | { |
133 | { |
|
133 | RegisterServiceEventArgs args = new RegisterServiceEventArgs(); |
134 | RegisterServiceEventArgs args = new RegisterServiceEventArgs(); |
|
134 | |
135 | |
|
135 | args.Service = this; |
136 | args.Service = this; |
|
136 | args.IsRegistered = false; |
137 | args.IsRegistered = false; |
|
137 | args.ServiceError = (ServiceErrorCode)errorCode; |
138 | args.ServiceError = (ServiceErrorCode)errorCode; |
|
138 | |
139 | |
|
139 | if(errorCode == ServiceError.NoError) { |
140 | if(errorCode == ServiceError.NoError) { |
|
140 | Name = name; |
141 | Name = Native.Utf8toString(name); |
|
141 | RegType = regtype; |
142 | RegType = regtype; |
|
142 | ReplyDomain = domain; |
143 | ReplyDomain = domain; |
|
143 | args.IsRegistered = true; |
144 | args.IsRegistered = true; |
|
144 | } |
145 | } |
|
145 | |
146 | |
|
146 | RegisterServiceEventHandler handler = Response; |
147 | RegisterServiceEventHandler handler = Response; |
|
147 | if(handler != null) { |
148 | if(handler != null) { |
|
148 | handler(this, args); |
149 | handler(this, args); |
|
149 | } |
150 | } |
|
150 | } |
151 | } |
|
151 | |
152 | |
|
152 | public bool AutoRename { |
153 | public bool AutoRename { |
|
153 | get { return auto_rename; } |
154 | get { return auto_rename; } |
|
154 | set { auto_rename = value; } |
155 | set { auto_rename = value; } |
|
155 | } |
156 | } |
|
156 | } |
157 | } |
|
157 | } |
158 | } |
|
158 | |
159 | |