[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")]
public class DnssdBrowser : INsdBrowser
{
private string _serviceType;
+ private uint _browserHandle;
private event EventHandler<DnssdServiceFoundEventArgs> _serviceFound;
+ private Interop.Nsd.Dnssd.ServiceFoundCallback _serviceFoundCallback;
/// <summary>
- /// 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.
/// </summary>
public event EventHandler<DnssdServiceFoundEventArgs> ServiceFound
{
/// <param name="serviceType">The DNSSD service type</param>
public DnssdBrowser(string serviceType)
{
+ DnssdInitializer dnssdInit = Globals.s_threadDns.Value;
+ Log.Info(Globals.LogTag, "Initialize ThreadLocal<DnssdInitializer> instance = " + dnssdInit);
+
_serviceType = serviceType;
}
+
+ internal void StartDiscovery()
+ {
+ DnssdInitializer dnssdInit = Globals.s_threadDns.Value;
+ Log.Info(Globals.LogTag, "Initialize ThreadLocal<DnssdInitializer> 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);
+ }
+ }
}
}
* 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);
+ }
+ }
+ }
/// <summary>
- /// 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.
/// </summary>
public class DnssdService : INsdService
{
- private uint _service;
+ private uint _serviceHandle;
+ private string _serviceType;
+ private ushort _dnsRecordtype = 16;
+ private Interop.Nsd.Dnssd.ServiceRegisteredCallback _serviceRegisteredCallback;
/// <summary>
- /// Name of DNSSD local service.
+ /// Constructor to create DnssdService instance that sets the serviceType to a given value.
/// </summary>
+ /// <param name="serviceType">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.
+ /// </param>
+ 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<DnssdInitializer> 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);
+ }
+ }
+
+ /// <summary>
+ /// Name of DNSSD service.
+ /// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when DNSSD is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occured.</exception>
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);
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);
/// <summary>
/// Type of DNSSD local/remote service.
/// </summary>
+ /// <remarks>
+ /// In case of error, null will be returned.
+ /// </remarks>
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);
return type;
}
}
+
+ /// <summary>
+ /// Port number of DNSSD local/remote service.
+ /// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when DNSSD is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occured.</exception>
+ 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);
+ }
+ }
+ }
+
+ /// <summary>
+ /// IP of DNSSD remote service.
+ /// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ 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);
+ }
+ }
+
+ /// <summary>
+ /// Adds the TXT record.
+ /// </summary>
+ /// <remarks>
+ /// TXT record should be added after registering local service using RegisterService().
+ /// </remarks>
+ /// <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>
+ /// <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>
+ /// <exception cref="NotSupportedException">Thrown when DNSSD is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when any other error occured.</exception>
+ 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);
+ }
+ }
+
+ /// <summary>
+ /// Removes the TXT record.
+ /// </summary>
+ /// <param name="key">The key of the TXT record to be removed.</param>
+ /// <exception cref="NotSupportedException">Thrown when DNSSD is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when any other error occured.</exception>
+ 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);
+ }
+ }
+ }
+
+ /// <summary>
+ /// This class manages the IP address properties of DNSSD service.
+ /// </summary>
+ public class IPAddressInformation
+ {
+ private string _ipv4, _ipv6;
+ internal IPAddressInformation()
+ {
+ }
+
+ internal IPAddressInformation(string ipv4, string ipv6)
+ {
+ _ipv4 = ipv4;
+ _ipv6 = ipv6;
+ }
+
+ /// <summary>
+ /// The IP version 4 address of DNSSD service.
+ /// </summary>
+ public IPAddress IPV4Address
+ {
+ get
+ {
+ return IPAddress.Parse(_ipv4);
+ }
+ }
+
+ /// <summary>
+ /// The IP version 6 address of DNSSD service.
+ /// </summary>
+ public IPAddress IPV6Address
+ {
+ get
+ {
+ return IPAddress.Parse(_ipv6);
+ }
+ }
}
-}
+}
\ No newline at end of file
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:
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:
* 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<DnssdInitializer> s_threadDns = new ThreadLocal<DnssdInitializer>(() =>
+ {
+ Log.Info(LogTag, "Inside Dnssd ThreadLocal delegate");
+ return new DnssdInitializer();
+ });
+
+ internal static ThreadLocal<SsdpInitializer> s_threadSsd = new ThreadLocal<SsdpInitializer>(() =>
+ {
+ Log.Info(LogTag, "Inside Ssdp ThreadLocal delegate");
+ return new SsdpInitializer();
+ });
}
/// <summary>
- /// 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.
/// </summary>
public static class NsdManager
{
+ /// <summary>
+ /// Registers the DNSSD/SSDP local service for publishing.
+ /// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ /// <param name="service">The DNSSD/SSDP service instance.</param>
+ /// <exception cref="NotSupportedException">Thrown when DNSSD/SSDP is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when any other error occured.</exception>
+ 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();
+ }
+ }
+
+ /// <summary>
+ /// Deregisters the DNSSD/SSDP local service.
+ /// </summary>
+ /// <remarks>
+ /// A local service registered using RegisterService() must be passed.
+ /// </remarks>
+ /// <param name="service">The DNSSD/SSDP service instance.</param>
+ /// <exception cref="NotSupportedException">Thrown when DNSSD/SSDP is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when any other error occured.</exception>
+ 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();
+ }
+ }
+
+ /// <summary>
+ /// Starts browsing the DNSSD/SSDP remote service.
+ /// </summary>
+ /// <remarks>
+ /// If there are any services available, ServiceFound event will be invoked.
+ /// Application will keep browsing for available/unavailable services until it calls StopDiscovery().
+ /// </remarks>
+ /// <param name="browser">The DNSSD/SSDP browser instance.</param>
+ /// <exception cref="NotSupportedException">Thrown when DNSSD/SSDP is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when any other error occured.</exception>
+ 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();
+ }
+ }
+
+ /// <summary>
+ /// Stops browsing the DNSSD/SSDP remote service.
+ /// </summary>
+ /// <param name="browser">The DNSSD/SSDP browser instance.</param>
+ /// <exception cref="NotSupportedException">Thrown when DNSSD/SSDP is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when any other error occured.</exception>
+ 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();
+ }
+ }
}
}
public class SsdpBrowser : INsdBrowser
{
private string _target;
+ private uint _browserHandle;
private event EventHandler<SsdpServiceFoundEventArgs> _serviceFound;
+ private Interop.Nsd.Ssdp.ServiceFoundCallback _serviceFoundCallback;
/// <summary>
- /// 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.
/// </summary>
public event EventHandler<SsdpServiceFoundEventArgs> ServiceFound
{
/// <param name="target">The target to browse for the service.</param>
public SsdpBrowser(string target)
{
+ SsdpInitializer ssdpInit = Globals.s_threadSsd.Value;
+ Log.Info(Globals.LogTag, "Initialize ThreadLocal<SsdpInitializer> instance = " + ssdpInit);
+
_target = target;
}
+
+ internal void StartDiscovery()
+ {
+ SsdpInitializer ssdpInit = Globals.s_threadSsd.Value;
+ Log.Info(Globals.LogTag, "Initialize ThreadLocal<SsdpInitializer> 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);
+ }
+ }
}
}
* 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);
+ }
+ }
+ }
+
/// <summary>
- /// 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.
/// </summary>
public class SsdpService : INsdService
{
- private uint _service;
+ private uint _serviceHandle;
+ private string _target;
+ private Interop.Nsd.Ssdp.ServiceRegisteredCallback _serviceRegisteredCallback;
+
+ /// <summary>
+ /// Constructor to create SsdpService instance that sets the target to a given value.
+ /// </summary>
+ /// <param name="target">The SSDP local service's target. It may be a device type or a service type.</param>
+ 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<SsdpInitializer> 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);
+ }
+ }
/// <summary>
- /// Name of SSDP local service.
+ /// Unique Service Name of SSDP service.
/// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when SSDP is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occured.</exception>
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);
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);
}
/// <summary>
- /// Type of SSDP local/remote service.
+ /// Type of SSDP service.
/// </summary>
+ /// <remarks>
+ /// In case of error, null will be returned.
+ /// </remarks>
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);
return type;
}
}
+
+ /// <summary>
+ /// URL of SSDP service.
+ /// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ /// <exception cref="NotSupportedException">Thrown while setting this property when SSDP is not supported.</exception>
+ /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occured.</exception>
+ 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);
+ }
+ }
}
}