2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Threading;
22 namespace Tizen.Network.Nsd
24 internal class DnssdInitializer
26 internal DnssdInitializer()
28 Globals.DnssdInitialize();
33 int ret = Interop.Nsd.Dnssd.Deinitialize();
34 if (ret != (int)DnssdError.None)
36 Log.Error(Globals.LogTag, "Failed to deinitialize Dnssd, Error - " + (DnssdError)ret);
41 /// This class is used for managing local service registration and its properties using DNSSD.
43 /// <since_tizen> 4 </since_tizen>
44 public class DnssdService : INsdService
46 private uint _serviceHandle;
47 private string _serviceType;
48 private ushort _dnsRecordtype = 16;
49 private Interop.Nsd.Dnssd.ServiceRegisteredCallback _serviceRegisteredCallback;
52 /// Constructor to create DnssdService instance that sets the serviceType to a given value.
54 /// <since_tizen> 4 </since_tizen>
55 /// <param name="serviceType">The DNSSD service type. It is expressed as type followed by protocol, separated by a dot(e.g. "_ftp._tcp").
56 /// It must begin with an underscore, followed by 1-15 characters which may be letters, digits or hyphens.
58 /// <feature>http://tizen.org/feature/network.dnssd</feature>
59 public DnssdService(string serviceType)
61 _serviceType = serviceType;
62 DnssdInitializeCreateService();
65 internal DnssdService(uint service)
67 _serviceHandle = service;
70 internal void DnssdInitializeCreateService()
72 DnssdInitializer dnssdInit = Globals.s_threadDns.Value;
73 Log.Info(Globals.LogTag, "Initialize ThreadLocal<DnssdInitializer> instance = " + dnssdInit);
74 int ret = Interop.Nsd.Dnssd.CreateService(_serviceType, out _serviceHandle);
75 if (ret != (int)DnssdError.None)
77 Log.Error(Globals.LogTag, "Failed to create a local Dnssd service handle, Error - " + (DnssdError)ret);
78 NsdErrorFactory.ThrowDnssdException(ret);
83 /// Name of DNSSD service.
86 /// Set Name for only unregistered service created locally.
87 /// It may be up to 63 bytes.
88 /// In case of error, null will be returned during get and exception will be thrown during set.
90 /// <since_tizen> 4 </since_tizen>
91 /// <feature>http://tizen.org/feature/network.dnssd</feature>
92 /// <exception cref="NotSupportedException">Thrown while setting this property when DNSSD is not supported.</exception>
93 /// <exception cref="ArgumentException">Thrown when Name value is set to null.</exception>
94 /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occurred.</exception>
100 int ret = Interop.Nsd.Dnssd.GetName(_serviceHandle, out name);
101 if (ret != (int)DnssdError.None)
103 Log.Error(Globals.LogTag, "Failed to get name of service, Error: " + (DnssdError)ret);
112 if (!Globals.s_threadDns.IsValueCreated)
114 DnssdInitializeCreateService();
117 int ret = Interop.Nsd.Dnssd.SetName(_serviceHandle, value);
118 if (ret != (int)DnssdError.None)
120 Log.Error(Globals.LogTag, "Failed to set name of service, Error: " + (DnssdError)ret);
121 NsdErrorFactory.ThrowDnssdException(ret);
127 /// Type of DNSSD local/remote service.
130 /// It is expressed as type followed by protocol, separated by a dot(e.g. "_ftp._tcp").
131 /// It must begin with an underscore, followed by 1-15 characters which may be letters, digits or hyphens.
132 /// In case of error, null will be returned.
134 /// <since_tizen> 4 </since_tizen>
140 int ret = Interop.Nsd.Dnssd.GetType(_serviceHandle, out type);
141 if (ret != (int)DnssdError.None)
143 Log.Error(Globals.LogTag, "Failed to get type of service, Error: " + (DnssdError)ret);
152 /// Port number of DNSSD local/remote service.
155 /// Set Port for only unregistered service created locally. The default value of Port is 0.
156 /// In case of error, -1 will be returned during get and exception will be thrown during set.
158 /// <since_tizen> 4 </since_tizen>
159 /// <feature>http://tizen.org/feature/network.dnssd</feature>
160 /// <exception cref="NotSupportedException">Thrown while setting this property when DNSSD is not supported.</exception>
161 /// <exception cref="ArgumentException">Thrown if value of Port is set to less than 0 or more than 65535.</exception>
162 /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occurred.</exception>
168 int ret = Interop.Nsd.Dnssd.GetPort(_serviceHandle, out port);
169 if (ret != (int)DnssdError.None)
171 Log.Error(Globals.LogTag, "Failed to get port number of Dnssd service, Error: " + (DnssdError)ret);
180 if (!Globals.s_threadDns.IsValueCreated)
182 DnssdInitializeCreateService();
185 int ret = Interop.Nsd.Dnssd.SetPort(_serviceHandle, value);
186 if (ret != (int)DnssdError.None)
188 Log.Error(Globals.LogTag, "Failed to set port number of Dnssd service, Error: " + (DnssdError)ret);
189 NsdErrorFactory.ThrowDnssdException(ret);
195 /// IP address of DNSSD remote service.
198 /// If the remote service has no IPv4 Address, then IPv4Address would contain null and if it has no IPv6 Address, then IPv6Address would contain null.
199 /// In case of error, null object will be returned.
201 /// <since_tizen> 4 </since_tizen>
202 public IPAddressInformation IP
207 int ret = Interop.Nsd.Dnssd.GetIP(_serviceHandle, out IPv4, out IPv6);
208 if (ret != (int)DnssdError.None)
210 Log.Error(Globals.LogTag, "Failed to get the IP of Dnssd remote service, Error: " + (DnssdError)ret);
214 IPAddressInformation IPAddressInstance = new IPAddressInformation(IPv4, IPv6);
215 return IPAddressInstance;
219 private void GetTxtRecord(out ushort length, out byte[] value)
221 int ret = Interop.Nsd.Dnssd.GetAllTxtRecord(_serviceHandle, out length, out value);
222 if (ret != (int)DnssdError.None)
224 Log.Error(Globals.LogTag, "Failed to get the TXT record, Error: " + (DnssdError)ret);
225 NsdErrorFactory.ThrowDnssdException(ret);
230 /// Adds the TXT record.
233 /// TXT record should be added after registering local service using RegisterService().
235 /// <since_tizen> 4 </since_tizen>
236 /// <param name="key">The key of the TXT record. It must be a null-terminated string with 9 characters or fewer excluding null. It is case insensitive.</param>
237 /// <param name="value">The value of the TXT record.If null, then "key" will be added with no value. If non-null but value_length is zero, then "key=" will be added with empty value.</param>
238 /// <feature>http://tizen.org/feature/network.dnssd</feature>
239 /// <exception cref="NotSupportedException">Thrown when DNSSD is not supported.</exception>
240 /// <exception cref="ArgumentException">Thrown when value of key is null.</exception>
241 /// <exception cref="InvalidOperationException">Thrown when any other error occurred.</exception>
242 public void AddTXTRecord(string key, string value)
244 byte[] byteValue = Encoding.UTF8.GetBytes(value);
245 ushort length = Convert.ToUInt16(byteValue.Length);
246 int ret = Interop.Nsd.Dnssd.AddTxtRecord(_serviceHandle, key, length, byteValue);
247 if (ret != (int)DnssdError.None)
249 Log.Error(Globals.LogTag, "Failed to add the TXT record, Error: " + (DnssdError)ret);
250 NsdErrorFactory.ThrowDnssdException(ret);
255 GetTxtRecord(out txtLength, out txtValue);
257 ret = Interop.Nsd.Dnssd.SetRecord(_serviceHandle, _dnsRecordtype, txtLength, txtValue);
258 if (ret != (int)DnssdError.None)
260 Log.Error(Globals.LogTag, "Failed to set the DNS resource record, Error: " + (DnssdError)ret);
261 NsdErrorFactory.ThrowDnssdException(ret);
266 /// Removes the TXT record.
268 /// <since_tizen> 4 </since_tizen>
269 /// <param name="key">The key of the TXT record to be removed.</param>
270 /// <feature>http://tizen.org/feature/network.dnssd</feature>
271 /// <exception cref="NotSupportedException">Thrown when DNSSD is not supported.</exception>
272 /// <exception cref="ArgumentException">Thrown when value of key is null.</exception>
273 /// <exception cref="InvalidOperationException">Thrown when any other error occurred.</exception>
274 public void RemoveTXTRecord(string key)
276 int ret = Interop.Nsd.Dnssd.RemoveTxtRecord(_serviceHandle, key);
277 if (ret != (int)DnssdError.None)
279 Log.Error(Globals.LogTag, "Failed to remove the TXT record, Error: " + (DnssdError)ret);
280 NsdErrorFactory.ThrowDnssdException(ret);
285 GetTxtRecord(out txtLength, out txtValue);
288 ret = Interop.Nsd.Dnssd.UnsetRecord(_serviceHandle, _dnsRecordtype);
289 if (ret != (int)DnssdError.None)
291 Log.Error(Globals.LogTag, "Failed to unset the DNS resource record, Error: " + (DnssdError)ret);
292 NsdErrorFactory.ThrowDnssdException(ret);
298 /// Registers the DNSSD local service for publishing.
300 /// Name of the service must be set.
301 /// <since_tizen> 4 </since_tizen>
302 /// <privilege>http://tizen.org/privilege/internet</privilege>
303 /// <feature>http://tizen.org/feature/network.dnssd</feature>
304 /// <exception cref="InvalidOperationException">Thrown when any other error occurred.</exception>
305 /// <exception cref="NotSupportedException">Thrown when DNSSD is not supported.</exception>
306 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
307 public void RegisterService()
309 if (!Globals.s_threadDns.IsValueCreated)
311 DnssdInitializeCreateService();
314 _serviceRegisteredCallback = (DnssdError result, uint service, IntPtr userData) =>
316 if (result != DnssdError.None)
318 Log.Error(Globals.LogTag, "Failed to finish the registration of Dnssd local service, Error: " + result);
319 NsdErrorFactory.ThrowDnssdException((int)result);
323 int ret = Interop.Nsd.Dnssd.RegisterService(_serviceHandle, _serviceRegisteredCallback, IntPtr.Zero);
324 if (ret != (int)DnssdError.None)
326 Log.Error(Globals.LogTag, "Failed to register the Dnssd local service, Error: " + (DnssdError)ret);
327 NsdErrorFactory.ThrowDnssdException(ret);
332 /// Deregisters the DNSSD local service.
335 /// A local service registered using RegisterService() must be passed.
337 /// <since_tizen> 4 </since_tizen>
338 /// <feature>http://tizen.org/feature/network.dnssd</feature>
339 /// <exception cref="InvalidOperationException">Thrown when any other error occurred.</exception>
340 /// <exception cref="NotSupportedException">Thrown when DNSSD is not supported.</exception>
341 public void DeregisterService()
343 int ret = Interop.Nsd.Dnssd.DeregisterService(_serviceHandle);
344 if (ret != (int)DnssdError.None)
346 Log.Error(Globals.LogTag, "Failed to deregister the Dnssd local service, Error: " + (DnssdError)ret);
347 NsdErrorFactory.ThrowDnssdException(ret);
351 #region IDisposable Support
352 private bool _disposedValue = false; // To detect redundant calls
354 protected virtual void Dispose(bool disposing)
360 if (_serviceHandle != 0)
362 int ret = Interop.Nsd.Dnssd.DestroyService(_serviceHandle);
363 if (ret != (int)DnssdError.None)
365 Log.Error(Globals.LogTag, "Failed to destroy the local Dnssd service handle, Error - " + (DnssdError)ret);
370 _disposedValue = true;
380 /// Disposes the memory allocated to unmanaged resources.
382 /// <since_tizen> 4 </since_tizen>
383 public void Dispose()
386 GC.SuppressFinalize(this);
392 /// This class manages the IP address properties of DNSSD service.
394 /// <since_tizen> 4 </since_tizen>
395 public class IPAddressInformation
397 private string _ipv4, _ipv6;
398 internal IPAddressInformation()
402 internal IPAddressInformation(string ipv4, string ipv6)
409 /// The IP version 4 address of DNSSD service.
411 /// <since_tizen> 4 </since_tizen>
412 public IPAddress IPv4Address
416 return IPAddress.Parse(_ipv4);
421 /// The IP version 6 address of DNSSD service.
423 /// <since_tizen> 4 </since_tizen>
424 public IPAddress IPv6Address
428 return IPAddress.Parse(_ipv6);