From: shikha.ta Date: Fri, 17 Mar 2017 06:23:15 +0000 (+0530) Subject: [Nsd] Implemented Dnssd and Ssdp apis and properties X-Git-Tag: submit/tizen/20170609.022236~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2aa2f95ece9fe1086a15ba4d75c67961f1e07bc7;p=platform%2Fcore%2Fcsapi%2Fnsd.git [Nsd] Implemented Dnssd and Ssdp apis and properties Change-Id: I5e66da168fa67cf01f12870e83763d8fa49cd9e7 Signed-off-by: shikha.ta --- diff --git a/Tizen.Network.Nsd/Interop/Interop.Nsd.cs b/Tizen.Network.Nsd/Interop/Interop.Nsd.cs index 940d922..5979c1d 100755 --- a/Tizen.Network.Nsd/Interop/Interop.Nsd.cs +++ b/Tizen.Network.Nsd/Interop/Interop.Nsd.cs @@ -70,7 +70,7 @@ internal static partial class Interop [DllImport(Libraries.Dnssd, EntryPoint = "dnssd_service_get_name")] internal static extern int GetName(uint service, out string name); [DllImport(Libraries.Dnssd, EntryPoint = "dnssd_service_get_ip")] - internal static extern int GetIp(uint service, out string ipV4, out string ipV6); + internal static extern int GetIP(uint service, out string ipV4, out string ipV6); [DllImport(Libraries.Dnssd, EntryPoint = "dnssd_service_get_port")] internal static extern int GetPort(uint service, out int port); [DllImport(Libraries.Dnssd, EntryPoint = "dnssd_service_get_all_txt_record")] diff --git a/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdBrowser.cs b/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdBrowser.cs index 8dd3911..020a58a 100755 --- a/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdBrowser.cs +++ b/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdBrowser.cs @@ -24,10 +24,12 @@ namespace Tizen.Network.Nsd public class DnssdBrowser : INsdBrowser { private string _serviceType; + private uint _browserHandle; private event EventHandler _serviceFound; + private Interop.Nsd.Dnssd.ServiceFoundCallback _serviceFoundCallback; /// - /// This event is raised when service state changes during service discovery using DNSSD. + /// This event is raised when a DNSSD service is found during service discovery. /// public event EventHandler ServiceFound { @@ -48,7 +50,43 @@ namespace Tizen.Network.Nsd /// The DNSSD service type public DnssdBrowser(string serviceType) { + DnssdInitializer dnssdInit = Globals.s_threadDns.Value; + Log.Info(Globals.LogTag, "Initialize ThreadLocal instance = " + dnssdInit); + _serviceType = serviceType; } + + internal void StartDiscovery() + { + DnssdInitializer dnssdInit = Globals.s_threadDns.Value; + Log.Info(Globals.LogTag, "Initialize ThreadLocal instance = " + dnssdInit); + + _serviceFoundCallback = (DnssdServiceState state, uint service, IntPtr userData) => + { + if (_serviceFound != null) + { + Log.Info(Globals.LogTag, "Inside Service found callback"); + DnssdService dnsService = new DnssdService(service); + _serviceFound(null, new DnssdServiceFoundEventArgs(state, dnsService)); + } + }; + + int ret = Interop.Nsd.Dnssd.StartBrowsing(_serviceType, out _browserHandle, _serviceFoundCallback, IntPtr.Zero); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to discover Dnssd remote service, Error - " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + + internal void StopDiscovery() + { + int ret = Interop.Nsd.Dnssd.StopBrowsing(_browserHandle); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to stop discovery of Dnssd remote service, Error - " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } } } diff --git a/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs b/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs index 852c9f0..e84ddcc 100755 --- a/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs +++ b/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs @@ -14,24 +14,83 @@ * limitations under the License. */ +using System; +using System.Text; +using System.Threading; +using System.Net; + namespace Tizen.Network.Nsd { + internal class DnssdInitializer + { + internal DnssdInitializer() + { + Globals.DnssdInitialize(); + } + + ~DnssdInitializer() + { + int ret = Interop.Nsd.Dnssd.Deinitialize(); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to deinitialize Dnssd, Error - " + (DnssdError)ret); + } + } + } /// - /// This class is used for managing local service discovery using DNSSD. + /// This class is used for managing local service registration and its properties using DNSSD. /// public class DnssdService : INsdService { - private uint _service; + private uint _serviceHandle; + private string _serviceType; + private ushort _dnsRecordtype = 16; + private Interop.Nsd.Dnssd.ServiceRegisteredCallback _serviceRegisteredCallback; /// - /// Name of DNSSD local service. + /// Constructor to create DnssdService instance that sets the serviceType to a given value. /// + /// The DNSSD service type. It is expressed as type followed by protocol, separated by a dot(e.g. "_ftp._tcp"). + /// It must begin with an underscore, followed by 1-15 characters which may be letters, digits or hyphens. + /// + public DnssdService(string serviceType) + { + _serviceType = serviceType; + DnssdInitializeCreateService(); + } + + internal DnssdService(uint service) + { + _serviceHandle = service; + } + + internal void DnssdInitializeCreateService() + { + DnssdInitializer dnssdInit = Globals.s_threadDns.Value; + Log.Info(Globals.LogTag, "Initialize ThreadLocal instance = " + dnssdInit); + int ret = Interop.Nsd.Dnssd.CreateService(_serviceType, out _serviceHandle); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to create a local Dnssd service handle, Error - " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + + /// + /// Name of DNSSD service. + /// + /// + /// Set Name for only unregistered service created locally. + /// In case of error, null will be returned during get and exception will be thrown during set. + /// + /// Thrown while setting this property when DNSSD is not supported. + /// Thrown while setting this property when any other error occured. public string Name { get { string name; - int ret = Interop.Nsd.Dnssd.GetName(_service, out name); + int ret = Interop.Nsd.Dnssd.GetName(_serviceHandle, out name); if (ret != (int)DnssdError.None) { Log.Error(Globals.LogTag, "Failed to get name of service, Error: " + (DnssdError)ret); @@ -43,7 +102,12 @@ namespace Tizen.Network.Nsd set { - int ret = Interop.Nsd.Dnssd.SetName(_service, value.ToString()); + if (!Globals.s_threadDns.IsValueCreated) + { + DnssdInitializeCreateService(); + } + + int ret = Interop.Nsd.Dnssd.SetName(_serviceHandle, value.ToString()); if (ret != (int)DnssdError.None) { Log.Error(Globals.LogTag, "Failed to set name of service, Error: " + (DnssdError)ret); @@ -55,12 +119,15 @@ namespace Tizen.Network.Nsd /// /// Type of DNSSD local/remote service. /// + /// + /// In case of error, null will be returned. + /// public string Type { get { string type; - int ret = Interop.Nsd.Dnssd.GetType(_service, out type); + int ret = Interop.Nsd.Dnssd.GetType(_serviceHandle, out type); if (ret != (int)DnssdError.None) { Log.Error(Globals.LogTag, "Failed to get type of service, Error: " + (DnssdError)ret); @@ -70,5 +137,223 @@ namespace Tizen.Network.Nsd return type; } } + + /// + /// Port number of DNSSD local/remote service. + /// + /// + /// Set Port for only unregistered service created locally. + /// In case of error, -1 will be returned during get and exception will be thrown during set. + /// + /// Thrown while setting this property when DNSSD is not supported. + /// Thrown while setting this property when any other error occured. + public int Port + { + get + { + int port; + int ret = Interop.Nsd.Dnssd.GetPort(_serviceHandle, out port); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to get port number of Dnssd service, Error: " + (DnssdError)ret); + return -1; + } + + return port; + } + + set + { + if (!Globals.s_threadDns.IsValueCreated) + { + DnssdInitializeCreateService(); + } + + int ret = Interop.Nsd.Dnssd.SetPort(_serviceHandle, value); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to set port number of Dnssd service, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + } + + /// + /// IP of DNSSD remote service. + /// + /// + /// If there is no IPv4 Address, then IPV4Address would contain null and if there is no IPv6 Address, then IPV6Address would contain null. + /// In case of error, null object will be returned. + /// + public IPAddressInformation IP + { + get + { + string IPv4, IPv6; + int ret = Interop.Nsd.Dnssd.GetIP(_serviceHandle, out IPv4, out IPv6); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to get the IP of Dnssd remote service, Error: " + (DnssdError)ret); + return null; + } + + IPAddressInformation IPAddressInstance = new IPAddressInformation(IPv4, IPv6); + return IPAddressInstance; + } + } + + private void GetTxtRecord(out ushort length, out byte[] value) + { + int ret = Interop.Nsd.Dnssd.GetAllTxtRecord(_serviceHandle, out length, out value); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to get the TXT record, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + + /// + /// Adds the TXT record. + /// + /// + /// TXT record should be added after registering local service using RegisterService(). + /// + /// The key of the TXT record. It must be a null-terminated string with 9 characters or fewer excluding null. It is case insensitive. + /// 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. + /// Thrown when DNSSD is not supported. + /// Thrown when any other error occured. + public void AddTXTRecord(string key, string value) + { + byte[] byteValue = Encoding.UTF8.GetBytes(value); + ushort length = Convert.ToUInt16(byteValue.Length); + int ret = Interop.Nsd.Dnssd.AddTxtRecord(_serviceHandle, key, length, byteValue); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to add the TXT record, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + + byte[] txtValue; + ushort txtLength; + GetTxtRecord(out txtLength, out txtValue); + + ret = Interop.Nsd.Dnssd.SetRecord(_serviceHandle, _dnsRecordtype, txtLength, txtValue); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to set the DNS resource record, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + + /// + /// Removes the TXT record. + /// + /// The key of the TXT record to be removed. + /// Thrown when DNSSD is not supported. + /// Thrown when any other error occured. + public void RemoveTXTRecord(string key) + { + int ret = Interop.Nsd.Dnssd.RemoveTxtRecord(_serviceHandle, key); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to remove the TXT record, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + + byte[] txtValue; + ushort txtLength; + GetTxtRecord(out txtLength, out txtValue); + if (txtLength == 0) + { + ret = Interop.Nsd.Dnssd.UnsetRecord(_serviceHandle, _dnsRecordtype); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to unset the DNS resource record, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + } + + internal void RegisterService() + { + if (Globals.s_threadDns.IsValueCreated) + { + DnssdInitializeCreateService(); + } + + _serviceRegisteredCallback = (DnssdError result, uint service, IntPtr userData) => + { + if (result != DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to finish the registration of Dnssd local service, Error: " + result); + NsdErrorFactory.ThrowDnssdException((int)result); + } + }; + + int ret = Interop.Nsd.Dnssd.RegisterService(_serviceHandle, _serviceRegisteredCallback, IntPtr.Zero); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to register the Dnssd local service, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + + internal void DeregisterService() + { + int ret = Interop.Nsd.Dnssd.DeregisterService(_serviceHandle); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to deregister the Dnssd local service, Error: " + (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + + ~DnssdService() + { + int ret = Interop.Nsd.Dnssd.DestroyService(_serviceHandle); + if (ret != (int)DnssdError.None) + { + Log.Error(Globals.LogTag, "Failed to destroy the local Dnssd service handle, Error - " + (DnssdError)ret); + } + } + } + + /// + /// This class manages the IP address properties of DNSSD service. + /// + public class IPAddressInformation + { + private string _ipv4, _ipv6; + internal IPAddressInformation() + { + } + + internal IPAddressInformation(string ipv4, string ipv6) + { + _ipv4 = ipv4; + _ipv6 = ipv6; + } + + /// + /// The IP version 4 address of DNSSD service. + /// + public IPAddress IPV4Address + { + get + { + return IPAddress.Parse(_ipv4); + } + } + + /// + /// The IP version 6 address of DNSSD service. + /// + public IPAddress IPV6Address + { + get + { + return IPAddress.Parse(_ipv6); + } + } } -} +} \ No newline at end of file diff --git a/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdError.cs b/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdError.cs index a26f265..36891f4 100755 --- a/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdError.cs +++ b/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdError.cs @@ -32,7 +32,7 @@ namespace Tizen.Network.Nsd case DnssdError.InvalidParameter: throw new InvalidOperationException("Invalid parameter"); case DnssdError.NotSupported: - throw new InvalidOperationException("Not supported"); + throw new NotSupportedException("Not supported"); case DnssdError.NotInitialized: throw new InvalidOperationException("Not initialized"); case DnssdError.AlreadyRegistered: @@ -58,7 +58,7 @@ namespace Tizen.Network.Nsd case SsdpError.InvalidParameter: throw new InvalidOperationException("Invalid parameter"); case SsdpError.NotSupported: - throw new InvalidOperationException("Not supported"); + throw new NotSupportedException("Not supported"); case SsdpError.NotInitialized: throw new InvalidOperationException("Not initialized"); case SsdpError.OperationFailed: diff --git a/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdManager.cs b/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdManager.cs index 5c52965..b80c273 100755 --- a/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdManager.cs +++ b/Tizen.Network.Nsd/Tizen.Network.Nsd/NsdManager.cs @@ -14,17 +14,145 @@ * limitations under the License. */ +using System.Threading; + namespace Tizen.Network.Nsd { internal static class Globals { internal const string LogTag = "Tizen.Network.Nsd"; + + internal static void DnssdInitialize() + { + int ret = Interop.Nsd.Dnssd.Initialize(); + if(ret!=(int)DnssdError.None) + { + Log.Error(LogTag, "Failed to initialize Dnssd, Error - "+ (DnssdError)ret); + NsdErrorFactory.ThrowDnssdException(ret); + } + } + + internal static void SsdpInitialize() + { + int ret = Interop.Nsd.Ssdp.Initialize(); + if (ret != (int)SsdpError.None) + { + Log.Error(LogTag, "Failed to initialize Ssdp, Error - " + (SsdpError)ret); + NsdErrorFactory.ThrowSsdpException(ret); + } + } + + internal static ThreadLocal s_threadDns = new ThreadLocal(() => + { + Log.Info(LogTag, "Inside Dnssd ThreadLocal delegate"); + return new DnssdInitializer(); + }); + + internal static ThreadLocal s_threadSsd = new ThreadLocal(() => + { + Log.Info(LogTag, "Inside Ssdp ThreadLocal delegate"); + return new SsdpInitializer(); + }); } /// - /// This class is used for managing local/network service discovery using DNSSD/SSDP. + /// This class is used for managing local/network service registration and discovery using DNSSD/SSDP. /// public static class NsdManager { + /// + /// Registers the DNSSD/SSDP local service for publishing. + /// + /// + /// A service created locally must be passed. + /// Name of the service must be set for DNSSD/SSDP both. Also, Port and Url must be set for DNSSD and SSDP respectively. + /// + /// The DNSSD/SSDP service instance. + /// Thrown when DNSSD/SSDP is not supported. + /// Thrown when any other error occured. + public static void RegisterService(INsdService service) + { + if (service.GetType() == typeof(DnssdService)) + { + DnssdService dnsService = (DnssdService)service; + dnsService.RegisterService(); + } + + else if (service.GetType() == typeof(SsdpService)) + { + SsdpService ssdService = (SsdpService)service; + ssdService.RegisterService(); + } + } + + /// + /// Deregisters the DNSSD/SSDP local service. + /// + /// + /// A local service registered using RegisterService() must be passed. + /// + /// The DNSSD/SSDP service instance. + /// Thrown when DNSSD/SSDP is not supported. + /// Thrown when any other error occured. + public static void UnregisterService(INsdService service) + { + if (service.GetType() == typeof(DnssdService)) + { + DnssdService dnsService = (DnssdService)service; + dnsService.DeregisterService(); + } + + else if (service.GetType() == typeof(SsdpService)) + { + SsdpService ssdService = (SsdpService)service; + ssdService.DeregisterService(); + } + } + + /// + /// Starts browsing the DNSSD/SSDP remote service. + /// + /// + /// If there are any services available, ServiceFound event will be invoked. + /// Application will keep browsing for available/unavailable services until it calls StopDiscovery(). + /// + /// The DNSSD/SSDP browser instance. + /// Thrown when DNSSD/SSDP is not supported. + /// Thrown when any other error occured. + public static void StartDiscovery(INsdBrowser browser) + { + if (browser.GetType() == typeof(DnssdBrowser)) + { + DnssdBrowser dnsBrowser = (DnssdBrowser)browser; + dnsBrowser.StartDiscovery(); + } + + else if (browser.GetType() == typeof(SsdpBrowser)) + { + SsdpBrowser ssdBrowser = (SsdpBrowser)browser; + ssdBrowser.StartDiscovery(); + } + } + + /// + /// Stops browsing the DNSSD/SSDP remote service. + /// + /// The DNSSD/SSDP browser instance. + /// Thrown when DNSSD/SSDP is not supported. + /// Thrown when any other error occured. + public static void StopDiscovery(INsdBrowser browser) + { + if (browser.GetType() == typeof(DnssdBrowser)) + { + DnssdBrowser dnsBrowser = (DnssdBrowser)browser; + dnsBrowser.StopDiscovery(); + } + + else if (browser.GetType() == typeof(SsdpBrowser)) + { + SsdpBrowser ssdBrowser = (SsdpBrowser)browser; + ssdBrowser.StopDiscovery(); + } + } } } diff --git a/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpBrowser.cs b/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpBrowser.cs index 3753610..7f7d1ed 100755 --- a/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpBrowser.cs +++ b/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpBrowser.cs @@ -24,10 +24,12 @@ namespace Tizen.Network.Nsd public class SsdpBrowser : INsdBrowser { private string _target; + private uint _browserHandle; private event EventHandler _serviceFound; + private Interop.Nsd.Ssdp.ServiceFoundCallback _serviceFoundCallback; /// - /// This event is raised when service state changes during service discovery using SSDP. + /// This event is raised when service has become available or unavailable during service discovery using SSDP. /// public event EventHandler ServiceFound { @@ -48,7 +50,43 @@ namespace Tizen.Network.Nsd /// The target to browse for the service. public SsdpBrowser(string target) { + SsdpInitializer ssdpInit = Globals.s_threadSsd.Value; + Log.Info(Globals.LogTag, "Initialize ThreadLocal instance = " + ssdpInit); + _target = target; } + + internal void StartDiscovery() + { + SsdpInitializer ssdpInit = Globals.s_threadSsd.Value; + Log.Info(Globals.LogTag, "Initialize ThreadLocal instance = " + ssdpInit); + + _serviceFoundCallback = (SsdpServiceState state, uint service, IntPtr userData) => + { + if (_serviceFound != null) + { + Log.Info(Globals.LogTag, "Inside Service found callback"); + SsdpService ssdpService = new SsdpService(service); + _serviceFound(null, new SsdpServiceFoundEventArgs(state, ssdpService)); + } + }; + + int ret = Interop.Nsd.Ssdp.StartBrowsing(_target, out _browserHandle, _serviceFoundCallback, IntPtr.Zero); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to discover Ssdp remote service, Error - " + (SsdpError)ret); + NsdErrorFactory.ThrowSsdpException(ret); + } + } + + internal void StopDiscovery() + { + int ret = Interop.Nsd.Ssdp.StopBrowsing(_browserHandle); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to stop discovery of Ssdp remote service, Error - " + (SsdpError)ret); + NsdErrorFactory.ThrowSsdpException(ret); + } + } } } diff --git a/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpService.cs b/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpService.cs index 86f2187..77f18ae 100755 --- a/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpService.cs +++ b/Tizen.Network.Nsd/Tizen.Network.Nsd/SsdpService.cs @@ -14,24 +14,78 @@ * limitations under the License. */ +using System; + namespace Tizen.Network.Nsd { + internal class SsdpInitializer + { + internal SsdpInitializer() + { + Globals.SsdpInitialize(); + } + + ~SsdpInitializer() + { + int ret = Interop.Nsd.Ssdp.Deinitialize(); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to deinitialize Ssdp, Error - " + (SsdpError)ret); + } + } + } + /// - /// This class is used for managing local service discovery using SSDP. + /// This class is used for managing local service registration and its properties using SSDP. /// public class SsdpService : INsdService { - private uint _service; + private uint _serviceHandle; + private string _target; + private Interop.Nsd.Ssdp.ServiceRegisteredCallback _serviceRegisteredCallback; + + /// + /// Constructor to create SsdpService instance that sets the target to a given value. + /// + /// The SSDP local service's target. It may be a device type or a service type. + public SsdpService(string target) + { + _target = target; + SsdpInitializeCreateService(); + } + + internal SsdpService(uint service) + { + _serviceHandle = service; + } + + internal void SsdpInitializeCreateService() + { + SsdpInitializer ssdpInit = Globals.s_threadSsd.Value; + Log.Info(Globals.LogTag, "Initialize ThreadLocal instance = " + ssdpInit); + int ret = Interop.Nsd.Ssdp.CreateService(_target, out _serviceHandle); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to create a local Ssdp service handle, Error - " + (SsdpError)ret); + NsdErrorFactory.ThrowSsdpException(ret); + } + } /// - /// Name of SSDP local service. + /// Unique Service Name of SSDP service. /// + /// + /// Set Name for only unregistered service created locally. If service is already registered, Name will not be set. + /// In case of error, null will be returned during get and exception will be thrown during set. + /// + /// Thrown while setting this property when SSDP is not supported. + /// Thrown while setting this property when any other error occured. public string Name { get { string name; - int ret = Interop.Nsd.Ssdp.GetUsn(_service, out name); + int ret = Interop.Nsd.Ssdp.GetUsn(_serviceHandle, out name); if (ret != (int)SsdpError.None) { Log.Error(Globals.LogTag, "Failed to get name of service, Error: " + (SsdpError)ret); @@ -43,7 +97,12 @@ namespace Tizen.Network.Nsd set { - int ret = Interop.Nsd.Ssdp.SetUsn(_service, value.ToString()); + if (Globals.s_threadSsd.IsValueCreated) + { + SsdpInitializeCreateService(); + } + + int ret = Interop.Nsd.Ssdp.SetUsn(_serviceHandle, value.ToString()); if (ret != (int)SsdpError.None) { Log.Error(Globals.LogTag, "Failed to set name of service, Error: " + (SsdpError)ret); @@ -53,14 +112,17 @@ namespace Tizen.Network.Nsd } /// - /// Type of SSDP local/remote service. + /// Type of SSDP service. /// + /// + /// In case of error, null will be returned. + /// public string Type { get { string type; - int ret = Interop.Nsd.Ssdp.GetTarget(_service, out type); + int ret = Interop.Nsd.Ssdp.GetTarget(_serviceHandle, out type); if (ret != (int)SsdpError.None) { Log.Error(Globals.LogTag, "Failed to get type of service, Error: " + (SsdpError)ret); @@ -70,5 +132,83 @@ namespace Tizen.Network.Nsd return type; } } + + /// + /// URL of SSDP service. + /// + /// + /// Set Url for only unregistered service created locally. If service is already registered, Url will not be set. + /// In case of error, null will be returned during get and exception will be thrown during set. + /// + /// Thrown while setting this property when SSDP is not supported. + /// Thrown while setting this property when any other error occured. + public string Url + { + get + { + string url; + int ret = Interop.Nsd.Ssdp.GetUrl(_serviceHandle, out url); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to get url of Ssdp service, Error: " + (SsdpError)ret); + return null; + } + + return url; + } + + set + { + if (Globals.s_threadSsd.IsValueCreated) + { + SsdpInitializeCreateService(); + } + + int ret = Interop.Nsd.Ssdp.SetUrl(_serviceHandle, value.ToString()); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to set url of Ssdp service, Error: " + (SsdpError)ret); + NsdErrorFactory.ThrowSsdpException(ret); + } + } + } + + internal void RegisterService() + { + if (Globals.s_threadSsd.IsValueCreated) + { + SsdpInitializeCreateService(); + } + + _serviceRegisteredCallback = (SsdpError result, uint service, IntPtr userData) => + { + }; + + int ret = Interop.Nsd.Ssdp.RegisterService(_serviceHandle, _serviceRegisteredCallback, IntPtr.Zero); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to register the Ssdp local service, Error: " + (SsdpError)ret); + NsdErrorFactory.ThrowSsdpException(ret); + } + } + + internal void DeregisterService() + { + int ret = Interop.Nsd.Ssdp.DeregisterService(_serviceHandle); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to deregister the Ssdp local service, Error: " + (SsdpError)ret); + NsdErrorFactory.ThrowSsdpException(ret); + } + } + + ~SsdpService() + { + int ret = Interop.Nsd.Ssdp.DestroyService(_serviceHandle); + if (ret != (int)SsdpError.None) + { + Log.Error(Globals.LogTag, "Failed to destroy the local Ssdp service handle, Error - " + (SsdpError)ret); + } + } } }